Here’s a problem to solve: I’m working on a code repository including a configuration file. This file is provided by the upstream project. I need to modify it locally for my tests but I definitely don’t want to commit my modifications and even less push them to the remote server.

I could use the git reset –hard command on a regular basis but it’s not very convenient. I could also locally ignore this file by positioning it in the .git / info / exclude file. Another solution is to lock the file locally. Git can do it for you!

How to lock files

 
What is locking files about?

Any modification made to a locked file will not be taken into account. You will not see it when running git status and you will not be able to index these changes and therefore commit them.

We will use the git update-index command for this. As its name suggests, it manages the contents of the staging area.

Lock, unlock a file

For each file that should be locked, use the command below:

git update-index --assume-unchanged <file>

And to unock a file it’s very simple:

git update-index --no-assume-unchanged <file>
Check locked files

Using this  command, let’s look at the characteristics of the files in the repository:

$ git ls-files -v
h Makefile 
H README 
H fic1 
H fic2

The command lists the files that make up the repository and that can be managed in the staging area. Each file is preceded by a letter which specifies the status of the file. As far as we are concerned :

H: file managed in the cache
h: unmanaged file in cache

In the example above, the README, fic1 and fic2 files are managed in the stagong area. The Makefile file is not so whatever the modification made to this file, it will never be taken into account for a subsequent commit. h is the output of the git update-index –assume-unchanged command.

There is no out-of-the-box command to list locked files. We will use something like:

git ls-files -v | grep "^h"

And to make life easier, nothing like an alias:

[alias]
hidden = ! git ls-files -v | grep ""^h""
hide = update-index --assume-unchanged
unhide = update-index --no-assume-unchanged

What about a remote update?

Suppose the upstream project made a modification to the locally locked file. This is what will happen at the time of this update:

$ git pull
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 9 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (9/9), 1.21 KiB | 248.00 KiB/s, done.
From https://gitlab-training.hupstream.com/ennael/web-training
a14e0c6..9c508f9 master -> origin/master
* [new branch] test -> origin/test
Updating a14e0c6..9c508f9
error: Your local changes to the following files would be overwritten by merge:
README.md
Please commit your changes or stash them before you merge.
Aborting

My local change conflicts with the update and that’s what is stated here. There is therefore no risk of missing updates!