Lorsque vous apprenez à coder, tôt ou tard, vous en apprendrez également sur les systèmes de contrôle de version. Et bien qu'il existe de nombreux outils concurrents dans cet espace, l'un d'eux est la norme de facto utilisée par presque tout le monde dans l'industrie. Il est si populaire que certaines entreprises utilisent son nom dans leur image de marque. Nous parlons de Git, bien sûr.
Bien que Git soit un outil puissant, sa puissance est bien cachée. Il y a quelques concepts essentiels que vous devez comprendre pour devenir vraiment compétent avec Git. La bonne nouvelle est qu'une fois que vous les aurez appris, vous ne rencontrerez presque jamais de problèmes auxquels vous ne pourrez échapper.
Le flux de travail typique
Dans un workflow Git typique, vous utiliserez un référentiel local, un référentiel distant et une ou plusieurs branches. Les référentiels stockent toutes les informations sur le projet, y compris son historique complet et toutes les branches. Une branche est essentiellement une collection de changements menant d'un projet vide à l'état actuel.
Après avoir cloné un référentiel, vous travaillez sur votre copie locale et introduisez de nouvelles modifications. Jusqu'à ce que vous transmettiez les modifications locales au référentiel distant, tout votre travail n'est disponible que sur votre machine.
Lorsque vous avez terminé une tâche, il est temps de se synchroniser avec le référentiel distant. Vous souhaitez extraire les modifications à distance pour suivre la progression du projet et vous souhaitez pousser les modifications locales pour partager votre travail avec d'autres.
Changements locaux
Tout va bien lorsque vous et le reste de votre équipe travaillez sur des fichiers totalement séparés. Quoi qu'il arrive, vous ne vous marcherez pas sur les pieds.
Cependant, il y a des moments où vous et vos coéquipiers introduisez simultanément des changements au même endroit. Et c'est généralement là que les problèmes commencent.
Avez-vous déjà exécuté git pull
uniquement pour voir les redoutés error: Your local changes to the following files would be overwritten by merge:
? Tôt ou tard, tout le monde se heurte à ce problème.
Ce qui est plus déroutant ici, c'est que vous ne voulez rien fusionner, juste tirer, non? En fait, tirer est un peu plus compliqué que vous ne le pensez.
Comment fonctionne exactement Git Pull?
La traction n'est pas une opération unique. Il consiste à récupérer les données du serveur distant, puis à fusionner les modifications avec le référentiel local. Ces deux opérations peuvent être effectuées manuellement si vous le souhaitez:
git fetch git merge origin/$CURRENT_BRANCH
La origin/$CURRENT_BRANCH
partie signifie que:
- Git fusionnera les modifications du référentiel distant nommé
origin
(celui à partir duquel vous avez cloné) - qui ont été ajoutés au
$CURRENT_BRANCH
- qui ne sont pas déjà présents dans votre succursale de départ locale
Étant donné que Git n'effectue des fusions que lorsqu'il n'y a pas de modifications non validées, chaque fois que vous exécutez des git pull
modifications non validées peut vous causer des problèmes. Heureusement, il existe des moyens de se sortir des ennuis en un seul morceau!

Différentes approches
Lorsque vous avez des modifications locales non validées et que vous souhaitez toujours extraire une nouvelle version du serveur distant, votre cas d'utilisation s'inscrit généralement dans l'un des scénarios suivants. Soit:
- vous ne vous souciez pas des modifications locales et souhaitez les écraser,
- vous vous souciez beaucoup des changements et aimeriez les appliquer après les changements à distance,
- vous souhaitez télécharger les modifications à distance mais pas encore les appliquer
Chacune des approches nécessite une solution différente.
Vous ne vous souciez pas des changements locaux
Dans ce cas, vous souhaitez simplement supprimer toutes les modifications locales non validées. Vous avez peut-être modifié un fichier pour expérimenter, mais vous n'avez plus besoin de la modification. Tout ce qui vous importe, c'est d'être à jour avec l'amont.
Cela signifie que vous ajoutez une étape supplémentaire entre la récupération des modifications distantes et leur fusion. Cette étape réinitialisera la branche à son état non modifié, permettant ainsi git merge
de fonctionner.
git fetch git reset --hard HEAD git merge origin/$CURRENT_BRANCH
Si vous ne voulez pas taper le nom de la branche à chaque fois que vous exécutez cette commande, Git a un raccourci agréable pointant vers la branche amont: @{u}
. Une branche en amont est la branche du référentiel distant vers laquelle vous poussez et récupérez.
Voici à quoi ressembleraient les commandes ci-dessus avec le raccourci:
git fetch git reset --hard HEAD git merge '@{u}'
Nous citons le raccourci dans l'exemple pour empêcher le shell de l'interpréter.
Vous vous souciez beaucoup des changements locaux
Lorsque vos modifications non validées sont importantes pour vous, il existe deux options. Vous pouvez les valider et les exécuter git pull
, ou vous pouvez les cacher.
Cacher signifie ranger les changements pendant un moment pour les ramener plus tard. Pour être plus précis, git stash
crée un commit qui n'est pas visible sur votre branche actuelle, mais qui est toujours accessible par Git.
Pour ramener les modifications enregistrées dans le dernier stash, vous utilisez la git stash pop
commande. Après avoir appliqué avec succès les modifications cachées, cette commande supprime également la validation cachée car elle n'est plus nécessaire.
Le flux de travail pourrait alors ressembler à ceci:
git fetch git stash git merge '@{u}' git stash pop
By default, the changes from the stash will become staged. If you want to unstage them, use the command git restore --staged
(if using Git newer than 2.25.0).
You Just Want to Download the Remote Changes
The last scenario is a little different from the previous ones. Let's say that you are in the middle of a very messy refactoring. Neither losing the changes nor stashing them is an option. Yet, you still want to have the remote changes available to run git diff
against them.
As you have probably figured out, downloading the remote changes does not require git pull
at all! git fetch
is just enough.
One thing to note is that by default, git fetch
will only bring you changes from the current branch. To get all the changes from all the branches, use git fetch --all
. And if you'd like to clean up some of the branches that no longer exist in the remote repository, git fetch --all --prune
will do the cleaning up!

Some Automation
Have you heard of Git Config? It's a file where Git stores all of the user-configured settings. It resides in your home directory: either as ~/.gitconfig
or ~/.config/git/config
. You can edit it to add some custom aliases that will be understood as Git commands.
For example, to have a shortcut equivalent to git diff --cached
(that shows the difference between the current branch and the staged files), you'd add the following section:
[alias] dc = diff --cached
After that, you can run git dc
whenever you wish to review the changes. Going this way, we can set up a few aliases related to the previous use cases.
[alias] pull_force = !"git fetch --all; git reset --hard HEAD; git merge @{u}" pf = pull_force pull_stash = !"git fetch --all; git stash; git merge @{u}; git stash pop"
This way, running git pull_force
will overwrite the local changes, while git pull_stash
will preserve them.
The Other Git Pull Force
Curious minds may have already discovered that there is such a thing as git pull --force
. However, this is a very different beast to what's presented in this article.
It may sound like something that would help us overwrite local changes. Instead, it lets us fetch the changes from one remote branch to a different local branch. git pull --force
only modifies the behavior of the fetching part. It is therefore equivalent to git fetch --force
.
Like git push
, git fetch
allows us to specify which local and remote branch do we want to operate on. git fetch origin/feature-1:my-feature
will mean that the changes in the feature-1
branch from the remote repository will end up visible on the local branch my-feature
. When such an operation modifies the existing history, it is not permitted by Git without an explicit --force
parameter.
Just like git push --force
allows overwriting remote branches, git fetch --force
(or git pull --force
) allows overwriting local branches. It is always used with source and destination branches mentioned as parameters. An alternative approach to overwriting local changes using git --pull force
could be git pull --force "@{u}:HEAD"
.
Conclusion
Le monde de Git est vaste. Cet article ne couvrait qu'une des facettes de la maintenance du référentiel: l'incorporation de modifications à distance dans un référentiel local. Même ce scénario quotidien nous a obligé à examiner un peu plus en profondeur les mécanismes internes de cet outil de contrôle de version.
L'apprentissage de cas d'utilisation réels vous aide à mieux comprendre comment Git fonctionne sous le capot. Cela, à son tour, vous donnera le sentiment d'être autonome chaque fois que vous vous posez des problèmes. Nous faisons tous cela de temps en temps.