Ajouter des modifications à un commit

Par Maxime Bréhin • Publié le 13 janvier 2025 • 4 min

Tu viens de commiter et tu t’aperçois que certaines modifications ou fichiers n’ont pas été intégrées à ton commit. Idéalement, tu aimerais les ajouter au commit initial plutôt que de faire le classique commit intitulé « Oops, j'ai oublié des choses » dont la valeur pour l’historique est très discutable.

Deux cas de figure peuvent exister :

  1. Tu viens tout juste de commiter ;
  2. Tu as fait d’autres commit entre temps.

Chaque situation a sa solution, voyons-les ensemble.

1. Ajouter des choses à mon dernier commit

C’est le cas le plus fréquent. La procédure est plutôt facile à suivre :

  1. tu ajoutes tes fichiers ou modifications oubliés au stage : git add … ;
  2. tu “amendes” le commit que tu viens de faire : git commit --amend --no-edit.

Et voilà, c’est fini ! Bien évidemment, tu vérifies ton historique avant et après ton opération pour garantir que le résultat est bien celui attendu. Tu peux même pousser en faisant un git show pour voir le contenu du commit.

Le contexte est important : on parle bien de reprendre le commit en fin de branche. Il est peu probable qu’on ait envie de défaire et continuer le travail d’un commit plus ancien. Si c’était le cas, ça serait certainement dans l’optique d’un des autres scenarios de notre série pour apprendre à annuler, défaire et corriger.

Un exemple avec des schémas

Partons de l’historique suivant :

%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': { 'commitLabelFontSize': '16px' }, 'gitGraph': {'showBranches': false} } }%%
  gitGraph
    commit id: "a"
    commit id: "b"
    commit id: "c"
    commit id: "d"
    commit id: "(HEAD) e" type: HIGHLIGHT

Le dernier commit « e » est celui qu’on souhaite modifier.

On prépare nos modifications, on les ajoute au stage et on fait notre :

git commit --amend --no-edit

On obtient alors l’historique avec un commit en remplacement de « e » que j’ai appelé ici « e’ » :

%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': { 'commitLabelFontSize': '16px' }, 'gitGraph': {'showBranches': false} } }%%
  gitGraph
    commit id: "a"
    commit id: "b"
    commit id: "c"
    commit id: "d"
    commit id: "(HEAD) e’"

2. Ajout des choses à un commit plus ancien

Ça semble complexe en apparence (et même techniquement), mais on verra à la fin de cette démonstration qu’on peut faire aussi simple que la procédure précédente. Si ça ne t’intéresse pas de comprendre le détail, libre à toi d’aller directement à la version “rapide”.

Changer l’historique depuis le commit à modifier

Comme dans la situation précédente, la modification du commit donnera lieu à un nouveau commit remplaçant celui modifié, avec un nouvel identifiant. Et comme l’identifiant de chaque commit est en partie déterminé par l’identité de son ou ses commits parents, les commits qui le suivaient vont devoir être tous recalculés, remplacés. C’est le rôle de la commande rebase qui fera toute l’opération pour nous.

La commande rebase est une commande qui offre un fort potentiel, sorte de super couteau Suisse de Git. Si tu veux en savoir plus, tu peux lire cet article.

Les étapes

Avant de lancer un rebase, on doit d’abord effectuer un commit de correction. L’objectif final est de dire au rebase de regrouper ce commit et le commit à modifier pour n’en faire plus qu’un.

Pour faciliter la suite, on utilise une option spécifique à la commande commit qui va renseigné un message particulier qui sera interprété par le rebase ensuite.

# On ajoute nos modifications au stage puis on fait le commit
git commit --fixup identifiant-du-commit-à-corriger

Le commit est créé et son message et la combinaison du préfixe fixup! suivi du message du commit d’origine.

Reste alors à lancer la commande rebase en partant du commit précédent celui à modifier :

git rebase -r -i identifiant

On utilise le mode interactif pour que Git puisse regrouper nos commits, mais en réalité nous n’avons aucune intervention à faire dans la liste des actions que Git ouvre dans notre éditeur. On peut se contenter de fermer l’éditeur.

Comme à chaque fois, on vérifie notre historique une fois que tout est terminé.

La solution en 2 étapes

Si tu as lu toute l’explication, tu dois avoir hâte de voir la solution simple. Ça consiste à créer un alias qui fera l’opération en un appel :

# On renseigne l’alias au global pour pouvoir l’utiliser partout
git config --global alias.autofixup '!git commit --fixup $1 && git rebase --autosquash --interactive --rebase-merges $1~1 && echo "autofixup finished"'

Une fois qu’on a ça, les étapes sont très similaires à la première situation :

  1. On ajoute au stage nos modifications (git add …) ;
  2. On lance la commande : git autofixup idenfitiant-du-commit-à-modifier.

Et voilà !

Je regrette que Git n’offre pas nativement cette solution. D’autant qu’on se retrouve contraint à l’utiliser dans le terminal. Il est possible que certaines interfaces graphiques permettent de faire à peu près la même chose, mais je n’en ai aujourd’hui pas connaissance.

Revoyons l’action au ralenti

On reprend l’exemple d’avant, sauf qu’on cherche à modifier le commit « c » :

%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': { 'commitLabelFontSize': '16px' }, 'gitGraph': {'showBranches': false} } }%%
  gitGraph
    commit id: "a"
    commit id: "b"
    commit id: "c" type: HIGHLIGHT
    commit id: "d"
    commit id: "(HEAD) e"

On prépare nos modifis, on les ajoute au stage et on lance l’alias

git autofixup c

Et la magie opère, notre historique final est alors

%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': { 'commitLabelFontSize': '16px' }, 'gitGraph': {'showBranches': false} } }%%
  gitGraph
    commit id: "a"
    commit id: "b"
    commit id: "c’"
    commit id: "d’"
    commit id: "(HEAD) e’"

« c’ » contient bien les modifications du commit initial enrichi des nouvelles, et les commits suivants « d » et « e » ont été répliqués et obtiennent de nouveaux identifiants « d’ » et « e’ ».

Tu veux aller plus loin et maîtriser pleinement les fondamentaux de Git ou être accompagné pour garantir la qualité de tes projets grâce à une bonne mise en place de Git ? On peut t’aider ou te former, il suffit de nous décrire ton besoin !
Tu peux aussi regarder le programme de notre formation "Comprendre Git" ou nous poser tes questions sur notre forum discord.