IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ Git : retrouvez les meilleures réponses à vos questions pour apprendre Git, de niveau débutant à expert

FAQ Git : retrouvez les meilleures réponses à vos questions pour apprendre Git, de niveau débutant à expertConsultez toutes les FAQ

Nombre d'auteurs : 6, nombre de questions : 110, dernière mise à jour : 19 juin 2021 

 
OuvrirSommaireRéécriture de l’historique (rebase)

Conceptuellement il s’agit d’une réécriture de l’historique.

Techniquement il s’agit de changer le parent du commit à la base de la branche dont on veut faire un rebase, ce qui a pour conséquence de recréer tous les commits descendants (du fait du nouveau timestamp).

De ce fait, il ne faut jamais faire un rebase d’une branche qui a été publiée quelque part et donc le rebase ne doit s’appliquer qu’à des branches privées, c’est à dire qui n’existent que sur votre machine.

Mis à jour le 8 mars 2019  par Marc Loupias

Principalement pour conserver un historique propre et lisible.

La bonne pratique est de systématiquement faire un rebase d’une branche de travail avant de chercher à la fusionner avec une branche de collaboration (nommée généralement master).

Prenons la situation suivante :

 
Sélectionnez
---M1 master
   \
   B1---B2---B3 toto

Dans ce cas de figure vous avez créé une branche toto sur la base d’une branche master qui est la branche de collaboration du projet (là où tout le monde déverse ses contributions).

Vous avez fini de travailler et vous allez fusionner votre branche avec master.

Or, d’autres utilisateurs ont fait avancer master et la situation sur le dépôt distant est en réalité :

 
Sélectionnez
---M1---M2---M3 origin/master

Si vous fusionnez en l’état, vous ne pourrez pas obtenir un merge fast-forward et vous aurez peut être même des conflits lors de la fusion.

Que vous fassiez un rebase ou non, vous allez d’abord devoir récupérer les modifications du dépôt distant :

 
Sélectionnez
1.
2.
git checkout master
git pull origin master

Ceci fait, votre historique local est désormais :

 
Sélectionnez
---M1---M2---M3 master
   \
   B1---B2---B3 toto

Si vous choisissez de faire un rebase, vous allez obtenir ceci :

 
Sélectionnez
---M1---M2---M3 master
              \
              B1'---B2'---B3' toto

Le commit parent de B1 était M1 avant le rebase, il sera M3 après.

De ce fait, Git va rejouer chaque commit en respectant l’ordre de filiation, d’abord B1, puis B2, etc.

À chaque étape, si Git rencontre un conflit, il vous laissera la main pour le résoudre.

Important : les commits après rebase sont identifiés avec un prime ('), B1 devient B1', B2 devient B2' etc.

En effet, Git recrée de nouveaux commits même en l’absence d’un conflit, donc avec un timestamp différent et un SHA-1 identifiant le commit différent.

Mis à jour le 8 mars 2019  par Marc Loupias

Commencez par récupérer l’état de la branche parente sur le dépôt distant :

 
Sélectionnez
1.
2.
git checkout master
git pull origin master

Ensuite, placez vous sur la branche concernée par le rebase et exécutez-le (la commande rebase prend en argument la branche servant de base, c’est à dire la branche parente) :

 
Sélectionnez
1.
2.
git checkout toto
git rebase master
Mis à jour le 8 mars 2019  par Marc Loupias

C’est un rebase étendu qui va vous permettre de définir quelle opération effectuer à chaque commit de votre branche subissant le rebase.

Les options à chaque étape sont les suivantes :

  • pick pour utiliser le commit ;
  • reword pour utiliser le commit et changer son message ;
  • edit pour utiliser le commit mais pour pouvoir le modifier ;
  • squash pour fusionner le commit avec le précédent ;
  • fixup comme squash mais en supprimant le message de commit du commit fusionné ;
  • exec pour exécuter une commande shell ;
  • drop pour ignorer le commit qui n’existera donc plus dans votre historique au terme de l’opération.
Mis à jour le 8 mars 2019  par Marc Loupias

On effectue un rebase interactif pour nettoyer son historique avant de le publier.

Fusionner les commits qui n’ont pas lieu d’exister indépendamment, nettoyer les messages de commits, supprimer des configurations temporaires, modifier leur ordre, etc.

Mis à jour le 8 mars 2019  par Marc Loupias

Il suffit d’ajouter le paramètre -i à la commande et d’y adjoindre la profondeur (combien de commits depuis la tête de la branche seront concernés).

Par exemple :

 
Sélectionnez
1.
git rebase -i HEAD~3

aura pour effet de faire un rebase des trois derniers commits de votre branche.

L’exécution de cette commande entraîne l’ouverture d’un éditeur de texte depuis votre shell. Sous Windows avec Git BASH c’est VIM, sur macOS c’est VIM également et sur Ubuntu c’est nano.

L’éditeur de texte contient un fichier de configuration du rebase à effectuer, pour dire, à chaque étape, quelle opération vous souhaitez effectuer.

Par défaut, on obtient pick pour chaque commit, par exemple :

 
Sélectionnez
pick d1fdf88 cypress - video recording on
pick b065479 travis and cypress - some fix in e2e tests + baseUrl conf + http-server devDeps + travis conf
pick 933cf95 migration from old webapp to jsonresume generated website

# Rebase 10f5b97..933cf95 onto 10f5b97 (3 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

Il suffit de changer la commande à effectuer, d’enregistrer ce fichier et de quitter l’éditeur, et Git démarrera l’opération de rebase interactif.

Si par exemple je veux changer les messages de commit des trois commits de ma branche, je vais configurer ainsi :

 
Sélectionnez
reword d1fdf88 cypress - video recording on
reword b065479 travis and cypress - some fix in e2e tests + baseUrl conf + http-server devDeps + travis conf
reword 933cf95 migration from old webapp to jsonresume generated website

# Rebase 10f5b97..933cf95 onto 10f5b97 (3 command(s))

...

Ceci fait, à chaque étape du rebase, Git me proposera de saisir un nouveau message de commit via l’éditeur de texte du shell par défaut.

Mis à jour le 8 mars 2019  par Marc Loupias

Comme pour annuler une fusion :

 
Sélectionnez
1.
git rebase --abort

Cette commande fonctionne pour le rebase standard comme pour le rebase interactif.

Mis à jour le 8 mars 2019  par Marc Loupias

Comme pour annuler une fusion.

Une fois les conflits traités et ajoutés à l’index il vous suffira de dire à Git de poursuivre le rebase (surtout pas de commit !)

 
Sélectionnez
1.
git rebase --continue

Vous pouvez très bien obtenir des conflits à chaque étape, tout dépend des modifications effectuées par vous et par les autres utilisateurs.

Cette commande fonctionne pour le rebase standard comme pour le rebase interactif.

Mis à jour le 8 mars 2019  par Marc Loupias

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2019 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.