Voilà une problématique à résoudre : je bosse sur un dépot de code pour une application disposant d’un fichier de configuration. Ce fichier est fourni par le projet. J’ai besoin de le modifier en local pour mes tests mais je ne veux surtout pas committer mes modifications et encore moins les pousser sur le serveur distant.

Je pourrais utiliser la commande git reset –hard régulièrement mais ce n’est pas très pratique. Je pourrais aussi ignorer localement ce fichier en le positionnant dans le fichier .git/info/exclude. Une autre solution consiste à locker mes modifications en local. Git l’a fait pour vous !

Locker un pour plusieurs fichiers

Quel est l’objectif du lock ?

Toute modification effectuée sur un fichier locké ne sera pas prise en compte. Vous ne la verrez pas en exécutant git status et vous ne pourrez pas indexer ces modifications et donc les committer.

Nous allons utiliser pour cela la commande git update-index. Comme son nom l’indique, elle gère le contenu du cache ou index.

Locker, delocker un fichier

Pour chaque fichier qui devrait être locké, utiliser la commande ci-dessous :

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

Et pour delocker un fichier c’est très simple :

git update-index --no-assume-unchanged <fichier>
Vérifier et lister les fichiers lockés
Avec cette même commande, regardons les caractéristiques des fichiers du dépot :
$ git ls-files -v
h Makefile 
H README 
H fic1 
H fic2

,La commande liste les fichiers qui constituent le dépot et gérables dans le cache. Chaque fichier est précédé d’une lettre qui précise le status du fichier. En ce qui nous concerne :

  • H : fichier géré dans le cache
  • h : fichier non géré dans le cache

Dans l’exemple au-dessus, les fichiers README, fic1 et fic2 sont gérés dans le cache local. Le fichier Makefile ne l’est pas donc quelque soit la modification apportée à ce fichier, elle ne sera jamais prise en compte pour un commit ultérieur. h le résultat de la commande git update-index –assume-unchanged.

Il n’existe pas de commande prête à l’emploi pour lister les fichiers lockés. On utilisera quelque chose comme : 

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

Et pour se faciliter la vie, rien de tel qu’un alias :

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

Et en cas de mise à jour ?

Imaginons que le projet upstream ait apporté une modification au fichier locké localement. Voilà ce qui se passera au moment de cette mise à jour :

$ 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

Ma modification locale entre en conflit avec la mise à jour et c’est ce qui est indiqué ici. Aucun risque donc de louper des mises à jour !