Git Squash Commit

Azhar Bashir Khan 30 janvier 2023
  1. Utilisation de l’outil interactif git rebase pour écraser les commits Git
  2. Utilisation git merge -squash pour écraser les commits Git
Git Squash Commit

Nous allons apprendre à écraser Git dans ce tutoriel. L’idée de base est de prendre plusieurs commits continus et de les écraser en un seul.

L’intention principale est de condenser de nombreux commits en quelques commits pertinents. Ainsi, faire cela rend l’historique de git concis et clair.

Une autre façon de voir les choses est que nous effectuons plusieurs commits liés à une tâche. Au bout d’un moment, lorsque nous atteignons un état satisfaisant, les nombreux messages de commit encombrent l’historique de git.

À ce stade, nous pouvons souhaiter combiner les différents commits en un seul afin que l’historique de git soit clair et reflète au mieux la tâche effectuée.

Un autre cas d’utilisation consiste à effectuer un écrasement lors de la fusion de branches. Habituellement, nous créons une branche de fonctionnalité à partir de la branche principale pour le développement de certaines fonctionnalités.

Une fois la fonctionnalité terminée, nous fusionnons la branche de fonctionnalité dans la branche principale. Ici aussi, nous pouvons vouloir écraser les différents messages de validation effectués dans la branche de fonctionnalité en un seul lors de la fusion dans la branche principale.

Veuillez noter qu’il n’y a pas de commande git squash.

Il existe deux manières d’effectuer un squashing Git :

  • git rebase -i comme outil interactif utilisé pour écraser les commits
  • git merge -squash en utilisant l’option -squash lors de la fusion

Utilisation de l’outil interactif git rebase pour écraser les commits Git

Considérez l’extrait de journal git suivant, qui montre les quatre derniers commits de HEAD que nous souhaitons écraser.

25c38c4 remove .class files
da66e6a Delete version.ini
f4e3f09 Delete .log
b0e6655 Delete .lock
da66e6a github git notes

Nous pouvons voir dans le journal les quatre premiers messages de validation signifiant les opérations de suppression de différents fichiers non pertinents. Maintenant, nous allons écraser ces quatre commits en un seul.

Voici la syntaxe de la commande pour écraser les X derniers commits à l’aide de l’outil de rebase interactif.

git rebase -i HEAD~[X]

Ainsi, pour écraser les quatre commits, nous ferions comme ci-dessous.

$ git rebase -i HEAD~4

Après avoir émis cette commande, Git invoquera l’éditeur par défaut avec les détails des commits à squash, comme indiqué ci-dessous.

pick b0e6655 Delete .lock
pick f4e3f09 Delete .log 
pick da66e6a Delete version.ini
pick 25c38c4 remove .class files

# Rebase 652d2fe..25c38c4 onto 652d2fe (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

L’éditeur affiche les différents commits avec la commande pick. Il affiche également des informations sur les commandes disponibles. Nous utiliserons la commande squash (ou s).

Comme indiqué ci-dessous, nous conserverons le premier commit avec la commande pick et passerons de la commande pick à s (pour squash) pour les trois autres commits.

pick b0e6655 Delete .lock
s f4e3f09 Delete .log 
s da66e6a Delete version.ini
s 25c38c4 remove .class files

# Rebase 652d2fe..25c38c4 onto 652d2fe (4 command(s))
#
...

Les commits marqués de squash (ou s) seront fusionnés avec le commit principal, à savoir. celui marqué par pick.

Maintenant, nous allons enregistrer les modifications dans l’éditeur et quitter. Après cela, l’outil rebase -i ouvrira un autre éditeur pour saisir le message de validation, comme ci-dessous :

# This is a combination of 4 commits. The first commit's message is:

Delete .lock

# This is the 2nd commit message:

Delete .log 

# This is the 3rd commit message:

Delete version.ini

# This is the 4th commit message:

remove .class files

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Jan 3 16:39:23 2021 +0530
#
# interactive rebase in progress; onto 652d2fe
# Last commands done (4 commands done):
#    pick b0e6655 Delete .lock
#    s f4e3f09 Delete .log 
#    s da66e6a Delete version.ini
#    s 25c38c4 remove .class files
# No commands remaining.
# You are currently editing a commit while rebasing branch 'master' on '652d2fe'.
#
# Changes to be committed:
#       new file:   github-git-notes.txt
#

Maintenant, nous allons ajouter le nouveau message de validation en haut du premier message de validation.

Deleted irrelevant files

# This is a combination of 4 commits. The first commit's message is:

Delete .lock

# This is the 2nd commit message:

Delete .log
...

Après avoir enregistré et quitté l’éditeur, l’outil rebase -i imprimera le message suivant.

HEAD~2
Rebasing (2/2)


[detached HEAD caab6e8] Deleted irrelevant files
 Date: Sun Jan 3 16:39:23 2021 +0530
 1 file changed, 54 insertions(+)
 create mode 100644 github-git-notes.txt
Successfully rebased and updated refs/heads/master.

Maintenant, nous allons vérifier le git log et voir le message de validation unique écrasé (c’est-à-dire) au lieu des quatre messages de validation.

$ git log --oneline
25c38c4 Deleted irrelevant files
da66e6a github git notes
...

Utilisation git merge -squash pour écraser les commits Git

Voici la syntaxe de la commande pour fusionner une branche avec la branche actuelle (généralement main) et écraser les commits de la branche source.

git merge --squash <source_branch_name_to_squash>

Nous allons maintenant fusionner la branche de fonctionnalité, à savoir. feature1 avec écrasement avec la branche main.

Tout d’abord, nous allons checkout dans la branche main.

$ git checkout main
Switched to branch 'main'

Ensuite, nous allons faire un git merge avec l’option squash comme suit.

$ git merge --squash feature1
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

Lorsque nous effectuons une fusion avec l’option --squash, Git ne créera pas de commit de fusion dans la branche de destination, comme il le fait dans une fusion normale. Au lieu de cela, Git prend toutes les modifications dans la branche source, à savoir. feature1 et le met en tant que modifications locales dans la copie de travail de la branche de destination, main.

Veuillez voir ci-dessous.

$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   config.ini

Ici, le fichier config.ini a les modifications effectuées dans la branche feature1.

Maintenant, il ne reste plus qu’à valider les modifications dans la branche main comme ci-dessous.

$ git commit -am 'Merged and squashed the feature1 branch changes'
[main 573b923] Squashed and merged the feature1 branch
 1 file changed, 4 insertions(+)

Ainsi, nous avons maintenant fusionné les modifications de la branche feature1 dans la branche main, ainsi que l’écrasement des messages de validation de la branche feature1. Nous n’avons plus qu’un seul message de commit dans la branche main.

Article connexe - Git Rebase

Article connexe - Git Merge