Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.46.2 → 2.47.0 no changes
- 2.46.1 09/13/24
- 2.45.1 → 2.46.0 no changes
- 2.45.0 04/29/24
- 2.44.1 → 2.44.2 no changes
- 2.44.0 02/23/24
- 2.43.3 → 2.43.5 no changes
- 2.43.2 02/13/24
- 2.43.1 02/09/24
- 2.43.0 11/20/23
- 2.42.2 → 2.42.3 no changes
- 2.42.1 11/02/23
- 2.41.1 → 2.42.0 no changes
- 2.41.0 06/01/23
- 2.40.1 → 2.40.3 no changes
- 2.40.0 03/12/23
- 2.39.4 → 2.39.5 no changes
- 2.39.3 04/17/23
- 2.39.1 → 2.39.2 no changes
- 2.39.0 12/12/22
- 2.38.1 → 2.38.5 no changes
- 2.38.0 10/02/22
- 2.37.3 → 2.37.7 no changes
- 2.37.2 08/11/22
- 2.36.3 → 2.37.1 no changes
- 2.36.2 06/23/22
- 2.35.1 → 2.36.1 no changes
- 2.35.0 01/24/22
- 2.34.1 → 2.34.8 no changes
- 2.34.0 11/15/21
- 2.33.2 → 2.33.8 no changes
- 2.33.1 10/12/21
- 2.32.1 → 2.33.0 no changes
- 2.32.0 06/06/21
- 2.31.1 → 2.31.8 no changes
- 2.31.0 03/15/21
- 2.30.1 → 2.30.9 no changes
- 2.30.0 12/27/20
- 2.29.1 → 2.29.3 no changes
- 2.29.0 10/19/20
- 2.28.1 no changes
- 2.28.0 07/27/20
- 2.27.1 no changes
- 2.27.0 06/01/20
- 2.26.1 → 2.26.3 no changes
- 2.26.0 03/22/20
- 2.25.1 → 2.25.5 no changes
- 2.25.0 01/13/20
- 2.24.1 → 2.24.4 no changes
- 2.24.0 11/04/19
- 2.23.1 → 2.23.4 no changes
- 2.23.0 08/16/19
- 2.22.1 → 2.22.5 no changes
- 2.22.0 06/07/19
- 2.21.1 → 2.21.4 no changes
- 2.21.0 02/24/19
- 2.20.1 → 2.20.5 no changes
- 2.20.0 12/09/18
- 2.19.3 → 2.19.6 no changes
- 2.19.2 11/21/18
- 2.19.1 no changes
- 2.19.0 09/10/18
- 2.18.1 → 2.18.5 no changes
- 2.18.0 06/21/18
- 2.17.1 → 2.17.6 no changes
- 2.17.0 04/02/18
- 2.16.6 12/06/19
- 2.15.4 12/06/19
- 2.14.6 12/06/19
- 2.13.7 05/22/18
- 2.12.5 09/22/17
- 2.10.5 → 2.11.4 no changes
- 2.9.5 07/30/17
- 2.8.6 07/30/17
- 2.7.6 no changes
- 2.6.7 05/05/17
- 2.5.6 no changes
- 2.4.12 05/05/17
- 2.3.10 09/28/15
- 2.2.3 09/04/15
- 2.1.4 12/17/14
- 2.0.5 12/17/14
SYNOPSIS
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <nouvellebase> | --keep-base] [<amont> [<branche>]] git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <nouvellebase>] --root [<branche>] git rebase (--continue|--skip|--abort|--quit|--edit-todo|--show-current-patch)
DESCRIPTION
Si l ' on spécifie <branche> ` , `git rebase
effectuera un git switch <branche>
automatique avant de faire autre chose. Sinon, il reste sur la branche actuelle.
Si <amont>
n’est pas spécifié, on utilisera l’amont configuré dans les options branch.<nom>. remote
et branch.<nom>.merge
(voir git-config[1] pour plus de détails) et on suppose l’option --fork-point
. Si vous n’êtes actuellement sur aucune branche ou si la branche actuelle n’a pas d’amont configuré, le rebasage échouera.
Tous les changements apportés par des commits dans la branche actuelle, mais qui ne sont pas dans <amont>
sont enregistrés dans une zone temporaire. Il s’agit de la même série de commits qui serait affichée par git log <amont>.HEAD
; ou par git log 'fork_point'.HEAD
, si --fork-point
est actif (voir la description de --fork-point
ci-dessous) ; ou par git log HEAD
si l’option --root
est spécifiée.
La branche actuelle est réinitialisée à <amont>
ou <nouvellebase>
si l’option --onto
a été fournie. Cela a le même effet que git reset --hard <amont>
(ou <nouvellebase>
). ORIG_HEAD
est fixé pour pointer au sommet de la branche avant la réinitialisation.
Note
|
ORIG_HEAD n’est pas garanti de toujours pointer vers le sommet de la branche précédente à la fin du rebasage si d’autres commandes qui écrivent cette pseudo-réf (par exemple git reset ) sont utilisées pendant le rebasage. La pointe de la branche précédente, cependant, est accessible en utilisant le reflog de la branche actuelle (i.e. @{1} , voir gitrevisions[7]).
|
Les commits qui ont été précédemment sauvés dans la zone temporaire sont ensuite réappliqués à la branche actuelle, un par un, dans l’ordre. Notez que tout commit dans HEAD
qui introduit les mêmes changements textuels que ceux d’un commit dans HEAD..<amont>
sont omis (c.-à-d. une rustine déjà acceptée en amont avec un autre message de validation ou un autre horodatage sera ignorée).
Il est possible qu’un échec de fusion empêche ce processus d’être complètement automatique. Vous devrez résoudre un tel échec de fusion et exécuter git rebase --continue
. Une autre option est de contourner le commit qui a causé l’échec de fusion avec git rebase --skip
. Pour extraire la <branche>`originale et supprimer les fichiers de travail de `.git/rebase-apply
, utilisez la commande git rebase --abort
à la place.
Supposons que l’historique suivant existe et que la branche actuelle est "topic" :
A---B---C sujet / D---E---F---G master
À partir de là, le résultat de l’une des commandes suivantes :
git rebase master git rebase master sujet
serait :
A'--B'--C' sujet / D---E---F---G master
NOTE: Cette dernière forme n’est qu’un raccourcis de`git checkout sujet` suivi par git rebase master
. Lorsque rebase se termine, sujet
restera à la branche extraite.
Si la branche amont contient déjà un changement que vous avez fait (par exemple, parce que vous avez envoyé une rustine qui a été appliquée en amont), alors ce commit sera ignoré et des avertissements seront émis (si le backend merge est utilisé). Par exemple, l’exécution de git rebase master
sur l’historique suivant (dans lequel A'
et A
introduisent le même ensemble de modifications, mais ont des informations de validateur différentes) :
A---B---C sujet / D---E---A'---F master
donnera :
B'---C' sujet / D---E---A'---F master
Voici comment vous transplanteriez une branche de sujet basée sur une branche sur une autre, pour prétendre que vous avez fourché la branche de sujet de cette dernière branche, en utilisant rebase --onto
.
D’abord supposons que votre sujet est basé sur la branche next. Par exemple, une fonctionnalité développée en sujet dépend de certaines fonctionnalités qui se trouvent dans next.
o---o---o---o---o master \ o---o---o---o---o next \ o---o---o topic
Nous voulons rendre sujet embranchée depuis la branche master. ; par exemple, parce que la fonctionnalité sur laquelle sujet dépend a été fusionnée dans la branche master plus stable. Nous voulons que notre arbre ressemble à ça :
o---o---o---o---o master | \ | o'--o'--o' sujet \ o---o---o---o---o next
Nous pouvons l’obtenir en utilisant la commande suivante :
git rebase --onto master next sujet
Un autre exemple de l’option --onto est de rebaser une partie d’une branche. Si nous avons la situation suivante :
H---I---J sujetB / E---F---G sujetA / A---B---C---D master
puis la commande
git rebase --onto master sujetA sujetB
aurait pour résultat :
H'--I'--J' sujetB / | E---F---G sujetA |/ A---B---C---D master
Ceci est utile lorsque le sujet B ne dépend pas du sujetA.
Une plage de commits pourrait également être supprimée avec rebase. Si nous avons la situation suivante :
E---F---G---H---I---J sujetA
puis la commande
git rebase --onto sujetA~5 sujetA~3 sujetA
entraînerait le retrait des commits F et G :
E---H'---I'---J' sujetA
Ceci est utile si F et G ont été corrompues d’une certaine manière, ou ne devraient pas faire partie de sujetA. Notez que l’argument pour --onto
et le paramètre <amont>
peuvent être n’importe quel commit-esque valide.
En cas de conflit, git rebase
s’arrêtera au premier commit problématique et laissera les marqueurs de conflit dans l’arbre. Vous pouvez utiliser git diff
pour localiser les marqueurs (<<<<<<) et faire des modification pour résoudre le conflit. Pour chaque fichier que vous éditez, vous devez dire à Git que le conflit a été résolu, généralement cela serait fait avec
git add <fichier>
Après avoir résolu le conflit manuellement et mis à jour l’index avec la résolution souhaitée, vous pouvez poursuivre le processus de rebasage avec
git rebase --continue
Alternativement, vous pouvez défaire le git rebase avec
git rebase --abort
OPTIONS DE MODE
Les options de cette section ne peuvent être utilisées avec aucune autre option, y compris pas les unes avec les autres :
- --continue
-
Redémarrer le processus de rebasage après avoir résolu un conflit de fusion.
- --skip
-
Redémarrer le processus de rebasage en sautant la rustine actuelle.
- --abort
-
Abandonner l’opération de rebasage et réinitialiser HEAD à la branche originale. Si
<branche>
a été fournie quand l’opération de rebasage a été lancée,HEAD
sera réinitialisée à<branche>
. SinonHEAD
sera réinitialisée vers où elle était lorsque l’opération de rebasage a été lancée. - --quit
-
Abandonner l’opération de rebasage mais
HEAD
n’est pas réinitialisé à la branche d’origine. L’index et l’arbre de travail sont également laissés inchangés en conséquence. Si une entrée de remisage temporaire a été créée à l’aide de--autostash
, elle sera sauvegardée sur la liste des remisages. - --edit-todo
-
Éditer la liste à faire lors d’un rebasage interactif.
- --show-current-patch
-
Afficher la rustine actuelle dans une rebasage interactive ou lorsque le rebasage est arrêté en raison de conflits. C’est l’équivalent de
git show REBASE_HEAD
.
OPTIONS
- --onto <nouvellebase>
-
Point de départ pour créer les nouveaux commits. Si l ' option
--onto
n’est pas spécifiée, le point de départ est<amont>
. Peut être tout commit valide, et pas seulement un nom de branche existant.Autre cas spécial, vous pouvez utiliser « A...B » comme raccourci pour la base de fusion de
A
etB
s’il y a exactement une seule base de fusion. Vous pouvez ne pas spécifierA
ouB
, auquel cas ce seraHEAD
par défaut. - --keep-base
-
Définir le point de départ pour créer les nouveaux commits à la base de fusion de
<amont>
et<branche>
. Lancergit rebase --keep-base <amont> <branche>
équivaut à lancergit rebase --reapply-cherry-picks --no-fork-point --onto <amont>...<branche> <amont> <branche>
.Cette option est utile dans le cas où l’on développe une fonctionnalité au sommet d’une branche amont. Bien que la fonction soit en cours de travaux, la branche amont peut progresser et ce n’est peut-être pas la meilleure idée de continuer à rebaser sur le sommet de l’amont au lieu de garder la base telle quelle. Comme le commit de base est inchangé cette option implique
--reapply-cherry-picks
pour éviter de perdre des commits.Bien que cette option et
--fork-point
trouvent la base de fusion entre<amont>
et<branche>
, cette option utilise la base de fusion comme point de départ sur lequel les nouveaux commits seront créés, tandis que--fork-point
utilise la base de fusion pour déterminer l'_ensemble de commits` qui sera rebasé.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- <branche_amont>
-
Branche en amont à comparer. Peut être n’importe quel commit valide, pas seulement un nom de branche existant. Par défaut à l’amont configuré pour la branche actuelle.
- <branche>
-
Branche de travail ; la valeur par défaut est
HEAD
. - --apply
-
Utiliser des stratégies de rebasage (appelant
git-am
en interne). Cette option peut devenir un non-op dans le futur une fois que le moteur de fusion gère tout ce que apply fait.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --empty=(drop|keep|stop)
-
Comment gérer les commits qui ne sont pas vide au départ et ne sont pas des picorages propres d’un commit amont, mais qui deviennent vides plus tard après le rebasage (parce qu’ils contiennent un sous-ensemble de modifications déjà en amont) :
-
drop
-
Le commit sera abandonné. C’est le comportement par défaut.
-
keep
-
Le commit sera gardé. Cette option est implicite lorsque
--exec
est spécifiée sauf si-i
/--interactive
est également spécifié. -
stop
-
ask
-
La rebasage s’arrêtera lorsque le commit sera appliqué, vous permettant de choisir de l’abandonner, d’éditer encore des fichiers ou simplement de valider les modifications vides. Cette option est implicite lorsque
-i
/--interactive
est spécifiée.ask
est un synonyme obsolète destop
.
Notez que les commits qui sont déjà vides sont maintenus (à moins que
--no-keep-empty
soit spécifié), et les commits qui sont des propres picorages (comme déterminé pargit log --cherry-mark ...
) sont détectés et abandonnés à une étape préliminaire (sauf si--reapply-cherry-picks
ou--keep-base
est passé).Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
-
- --no-keep-empty
- --keep-empty
-
Ne pas garder les commits qui sont vides au départ avant le rebasage (c.-à-d. qui ne changent rien de leur parent) dans le résultat. La valeur par défaut est de garder les commits qui commencent à vide, puisque la création de tels commits nécessite le passage du drapeau de surcharge
--allow-empty
àgit commit
, signifiant qu’un utilisateur a très intentionnellement créé un tel commit et veut donc le garder.L’utilisation de ce drapeau sera probablement rare, puisque vous pouvez vous débarrasser des commits qui commencent vides en lançant simplement un rebasage interactif et en supprimant les lignes correspondant aux commits que vous ne voulez pas. Ce drapeau existe comme un raccourci pratique, pour les cas où des outils externes génèrent de nombreux commits vides et vous voulez qu’ils soient tous enlevés.
Pour les commits qui ne démarrent pas vides mais deviennent vides après le rebasage, voir le drapeau
--empty
.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --reapply-cherry-picks
- --no-reapply-cherry-picks
-
Réappliquer tous les picorages propres de tous les commits amonts au lieu de le abandonner préventivement. (Si ces commit deviennent vides plus tard après le rebasage, parce qu’ils contiennent un sous-ensemble de modifications déjà en amont, le comportement les concernant est dicté par le drapeau
--empty
).En l’absence de
--keep-base
(ou si--no-reapply-cherry-picks
est donné), ces commits seront automatiquement abandonnés. Parce que cela nécessite la lecture de tous les commits en amont, cela peut être coûteux dans les dépôts avec un grand nombre de commits en amont qui doivent être lus. Lors de l’utilisation du backend merge, des avertissements seront émis pour chaque commit abandonné (sauf--quiet
est donnée). Des conseils seront également émis à moins queadvice.skippedCherryPicks
ne soit mis à false (voir git-config[1]).--reapply-cherry-picks
permet à rebase de sauter la lecture de tous les commits en amont, de manière à potentiellement améliorer les performances.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --allow-empty-message
-
Opération blanche. Rebaser des commits avec un message vide échouaient auparavant et cette option remplacerait ce comportement, permettant aux commits avec des messages vides d’être rebaser. Maintenant, les commits avec un message vide ne font plus échouer un rebasage.
Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- -m
- --merge
-
Utiliser des stratégies de fusion pour rebaser (par défaut).
Notez qu’un rebasage fusionne les travaux en rejouant chaque commit de la branche de travail sur le dessus de la branche
<amont>
. En raison de cela, lorsqu’un conflit de fusion se produit, le côté déclaré comme «nôtre» (ours) est la série rebasée jusqu’ici, commençant par<amont>
et «leurs» (theirs) est la branche de travail. En d’autres termes, les côtés sont échangés.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- -s <stratégie>
- --strategy=<strategie>
-
Utiliser la stratégie de fusion donnée, au lieu du
ort
par défaut. Cela implique--merge
.Parce que
git rebase
rejoue chaque commit de la branche de travail par dessus la branche <amont> en utilisant la stratégie donnée, utiliser la stratégieours
vide simplement toutes les rustines de <branche>, ce qui n’a pas de sens.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- -X <option-de-strategie>
- --strategy-option=<option-de-stratégie>
-
Passer l'<option-de-stratégie> à la stratégie de fusion. Cela implique
--merge
et, si aucune stratégie n’a été spécifiée,-s ort
. Notez le renversement de ours et theirs comme indiqué ci-dessus pour l’option-m
.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --rerere-autoupdate
- --no-rerere-autoupdate
-
Après que le mécanisme rerere réutilise une résolution enregistrée sur le conflit actuel pour mettre à jour les fichiers dans l’arbre de travail, lui permettre de mettre également à jour l’index avec le résultat de la résolution.
--no-rerere-autoupdate
est un bon moyen de revérifier ce quererere
a fait et de détecter des erreurs de fusion potentielles, avant de valider le résultat dans l’index avec ungit add
séparé.
- -S[<idclé>]
- --gpg-sign[=<idclé>]
- --no-gpg-sign
-
Signer les commits avec GPG. L’argument
idclé
est optionnel avec par défaut l’identité du validateur ; si spécifiée, elle doit être collée à l’option sans aucun espace.--no-gpg-sign
est utile pour annuler l’effet de la variable de configurationcommit.gpgSign
ainsi que tout--gpg-sign
précédent. - -q
- --quiet
-
Être silencieux. Implique
--no-stat
. - -v
- --verbose
-
Mode bavard. Implique
--stat
. - --stat
-
Afficher un diffstat de ce qui a changé en amont depuis le dernier rebasage. Le diffstat est également contrôlé par l’option de configuration
rebase.stat
. - -n
- --no-stat
-
Ne pas afficher un diffstat dans le cadre du processus de rebasage.
- --no-verify
-
Cette option court-circuite le crochet pre-rebase. Voir aussi githooks[5].
- --verify
-
Permet l’exécution du crochet pre-rebase, qui est la valeur par défaut. Cette option peut être utilisée pour remplacer
--no-verify
. Voir aussi githooks[5]. - -C<n>
-
S’assurer qu’au moins
<n>
lignes du contexte environnant correspondent avant et après chaque modification. Lorsqu’il y a moins de lignes de contexte environnant, elles doivent toutes correspondre. Par défaut, aucun contexte n’est jamais ignoré. Implique--apply
.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --no-ff
- --force-rebase
- -f
-
Rejouer individuellement tous les commits rebasés au lieu d’aller en avance-rapide sur ceux inchangés. Cela garantit que toute l’historique de la branche rebasée est composé de nouveaux commits.
Vous pouvez trouver cela utile après avoir annulé une fusion d’une branche de sujet, car cette option recrée la branche de sujet avec des commits frais afin qu’elle puisse être fusionnée avec succès sans avoir besoin d"'inverser l’inversion" (voir le Comment inverser une mauvaise fusion pour plus de détails).
- --fork-point
- --no-fork-point
-
Utiliser le reflog pour trouver un meilleur ancêtre commun entre
<amont>
et<branche>
lors du calcul des commits introduits par<branche>
.Lorsque
--fork-point
est actif, fork_point sera utilisé au lieu de<amont>
pour calculer l’ensemble des commits à rebaser, où fork_point est le résultat de la commandegit merge-base --fork-point <amont> <branche>
(voir git-merge-base[1]). Si fork_point finit par être vide, l'<amont>
sera utilisé par défaut.Si
<amon>
ou--keep-base
est fourni sur la ligne de commande, la valeur par défaut est--no-fork-point
, sinon la valeur par défaut est--fork-point
. Voir aussi `rebase.forkpoint ` dans git-config[1].Si votre branche était basée sur <amont> mais qu'<amont> a été rembobinée et votre branche contient des commits qui ont été abandonnés, cette option peut être utilisée avec
--keep-base
afin de laisser tomber ces commits de votre branche.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --ignore-whitespace
-
Ignorer les différences d’espace blanc en essayant de concilier les différences. Actuellement, chaque backend met en œuvre une approximation de ce comportement :
- appliquer le backend
-
Lors de l’application d’une rustine, ignorer les modifications d’espace blanc dans les lignes de contexte. Malheureusement, cela signifie que si les lignes « anciennes » remplacées par la rustine ne diffèrent que par des espace blanc du fichier existant, vous obtiendrez un conflit de fusion au lieu d’une application correcte réussie.
- backend de fusion
-
Traiter les lignes avec seulement des modifications d’espace blanc comme inchangées lors de la fusion. Malheureusement, cela signifie que toutes les sections de rustine qui étaient destinés à modifier les espaces blancs et rien d’autre seront abandonnés, même si l’autre côté n’avait aucune modification susceptible de générer un conflit.
- --whitespace=<option>
-
Ce drapeau est passé au programme
git apply
(voir git-apply[1]) qui applique la rustine. Implique--apply
.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --committer-date-is-author-date
-
Au lieu d’utiliser la date actuelle comme date de validateur, utilisez la date de l’auteur du commit comme date de validateur. Cette option implique
--force-rebase
. - --ignore-date
- --reset-author-date
-
Au lieu d’utiliser la date d’auteur du commit d’origine, utiliser la date actuelle comme date de d’auteur du commit rebasé. Cette option implique
--force-rebase
.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --signoff
-
Ajouter une ligne terminale
Signed-off-by
à tous les commits rebasés. Notez que si--interactive
est donné alors seulement les commits marqués pour être sélectionnés, modifiés ou reformulés auront la ligne terminale ajoutée.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- -i
- --interactive
-
Faire une liste des commits qui sont sur le point d’être rebasés. Laisser l’utilisateur modifier cette liste avant de rebaser. Ce mode peut également être utilisé pour scinder les commits (voir SCINDER LES COMMITS ci-dessous).
Le format de la liste de commits peut être modifié en définissant l’option de configuration rebase.instructionFormat. Un format d’instruction personnalisé aura automatiquement le hash de commit préfixé au format.
Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- -r
- --rebase-merges[=(rebase-cousins|no-rebase-cousins)]
- --no-rebase-merges
-
Par défaut, un rebasage va simplement abandonner les commits de fusion de la liste de todo, et mettre les commits rebasés en une seule branche linéaire. Avec
--rebase-merges
, le rebasage tentera plutôt de préserver la structure de ramification dans les commits qui doivent être rebasés, en recréant les commits de fusion. Tout conflit de fusion résolu ou toute modification manuelle dans ces commits de fusion devra être résolu/reappliqué manuellement.--no-rebase-merges
peut être utilisé pour contrecarrer à la fois l’option de configrebase.rebaseMerges
et un--rebase-merges
précédent.Quand le rebasage fait une fusion, il y a deux modes:
rebase-cousins
etno-rebase-cousins
. Si le mode n’est pas spécifié, il vaut par défautno-rebase-cousins
. Dans le modeno-rebase-cousins
, les commits qui n’ont pas d'<amont> comme ancêtre direct garderont leur point de branche original, c’est-à-dire que les commits qui seraient exclus par l’option--ancestry-path
de git-log[1] garderont leurs ancêtres originaux par défaut. Dans le moderebase-cousins
, ces commits sont plutôt rebasés sur <amont> (ou <nouvellebase> de--onto
, si spécifiée).Il est actuellement seulement possible de recréer des commits de fusion en utilisant la stratégie de fusion
ort
; les différentes stratégies de fusion ne peuvent être utilisées que par des commandes explicitesexec git merge -s <strategie> [...]
.Voir aussi FUSIONS DE REBASAGE et OPTIONS INCOMPATIBLES ci-dessous.
- -x <cmd>
- --exec <cmd>
-
Ajouter "exec <cmd>" après chaque ligne créant un commit dans l’historique final. <cmd> sera interprété comme une ou plusieurs commandes de shell. Toute commande qui échoue interrompra le rebasage, avec le code de sortie 1.
Vous pouvez exécuter plusieurs commandes en utilisant une instance de
--exec
avec plusieurs commandes :git rebase -i --exec "cmd1 && cmd2 && ..."
ou en donnant plus d’un
--exec
:git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
Si
--autosquash
est utilisé, les lignesexec
ne seront pas ajoutées pour les commits intermédiaires, et n’apparaîtront qu’à la fin de chaque série squash/fixup.Cela utilise la machinerie
--interactive
interne, mais elle peut être exécutée sans un--interactive
explicite.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --root
-
Rebaser tous les commits atteignables à partir de <branche>, au lieu de les limiter avec <amont>. Cela vous permet de rebaser le ou les commits racines sur une branche.
Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --autosquash
- --no-autosquash
-
Écrase automatiquement les commits avec des messages spécialement formatés dans les commits précédents en cours de rebasage. Si un message de commit commence par "squash!", "fixup!" ou "amend!", le reste de la ligne de sujet est pris comme spécificateur de commit, qui correspond à un commit précédent si il correspond à la ligne de sujet ou l’empreinte de ce commit. Si aucun commit ne correspond exactement, les correspondances du spécificateur avec le début des sujets de commit sont envisagées.
Dans la liste des à faire de rebase, les actions d’écrasement, de correction et de modification des commits sont changées de
pick
àsquash
,fixup
oufixup -C
, respectivement, et elles sont déplacés juste après le commit ils modifient. L’option--interactive
peut être utilisée pour examiner et modifier la liste à faire avant de procéder.La façon recommandée de créer des commits avec des marqueurs d’écrasement est d’utiliser les options
--squash
,--fixup
,--fixup=amend:
ou--fixup=reword:
de git-commit[1], qui prennent le commit cible comme argument et remplissent automatiquement la ligne de sujet du nouveau commit à partir de cela.Définir la variable de configuration
rebase.autoSquash
à true permet l’application d’autosquash par défaut pour le rebasage interactif. L’option--no-autosquash
peut être utilisée pour remplacer ce réglage.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
- --autostash
- --no-autostash
-
Créer automatiquement une entrée temporaire de remisage avant le début de l’opération et l’appliquer après la fin de l’opération. Cela signifie que vous pouvez exécuter l’opération sur un arbre de travail sale. Cependant, utilisez-le avec précaution : l’application finale du remisage après une fusion réussie peut entraîner des conflits non négligeables.
- --reschedule-failed-exec
- --no-reschedule-failed-exec
-
Reprogrammer automatiquement les commandes
exec
qui ont échoué. Cela n’a de sens qu’en mode interactif (ou lorsqu’une option--exec
a été fournie).Cette option s’applique une fois qu’un rebasage est lancé. Il est conservé pour l’ensemble du rebasage en fonction, dans l’ordre, de l’option de ligne de commande fournie au
git rebase
initial, la configurationrebase.rescheduleFailedExec
(voir git-config[1] ou "CONFIGURATION" ci-dessous), ou par défaut false (faux).Enregistrer cette option pour tout le rebasage est une fonctionnalité de commodité. Sinon, une
--no-reschedule-failed-exec
explicite au début serait remplacée par la présence d’une configurationrebase.rescheduleFailedExec=true
lorsquegit rebase --continue
est invoquée. Actuellement, vous ne pouvez pas passer-[no-]reschedule-failed-exec
àgit rebase --continue
. - --update-refs
- --no-update-refs
-
Mettre à jour en force automatiquement toute branche qui pointe sur les commits qui sont en train d’être rebasés. Toutes les branches qui sont extraites dans les arbre-de-travails ne sont pas ne sont pas mises à jour de cette manière.
Si la variable de configuration
rebase.updateRefs
est définie, cette option peut être utilisée pour remplacer et désactiver ce réglage.Voir aussi OPTIONS INCOMPATIBLES ci-dessous.
OPTIONS INCOMPATIBLES
Les options suivantes :
-
--apply
-
--whitespace
-
-C
sont incompatibles avec les options suivantes :
-
--merge
-
--strategy
-
--strategy-option
-
--autosquash
-
--rebase-merges
-
--interactive
-
--exec
-
--no-keep-empty
-
--empty=
-
--[no-]reapply-cherry-picks lorsqu’utilisé sans --keep-base
-
--update-refs
-
--root lorsqu’il est utilisé sans --onto
En outre, les paires d’options suivantes sont incompatibles :
-
--keep-base et --onto
-
--keep-base et --root
-
--fork-point et --root
DIFFÉRENCES DE COMPORTEMENT
git rebase
a deux backends primaires : apply et merge. (Le backend apply était connu comme le backend am, mais le nom a conduit à la confusion car il ressemble à un verbe au lieu d’un nom. De plus, le backend merge était connu comme le backend interactif, mais il est maintenant utilisé aussi pour les cas non interactifs. Les deux ont été renommés en fonction de la fonctionnalité de bas niveau qui sous-tend chacun.) Il y a quelques différences subtiles dans la façon dont ces deux backends se comportent :
Commits vides
Le backend apply élimine malheureusement des commits intentionnellement vides, c’est-à-dire des commits qui ont commencé vides, bien qu’ils soient rares en pratique. Il élimine également des commits qui deviennent vides et il n’y a aucune option pour contrôler ce comportement.
Le backend merge conserve intentionnellement les commits vides par défaut (mais avec -i
ils sont marqués comme vides dans l’éditeur de liste à faire, ou ils peuvent être éliminés automatiquement avec --no-keep-empty
).
De manière similaire au backend apply, par défaut le backend merge abandonne les commits qui deviennentt vides à moins que -i
/--interactive
ne soit spécifié (auquel cas il s’arrête et demande à l’utilisateur quoi faire). Le backend merge a également une option --empty=(drop|keep|stop)
pour changer le comportement de gestion des commits qui deviennent vides.
Détection de renommage de répertoire
En raison de l’absence d’informations précises sur les arbres (provenant de la construction d’ancêtres factices avec l’information limitée disponible dans les rustines), la détection de renommage est désactivée dans le backend apply. La déactivation de renommage de répertoire signifie que si un côté de l’historique renomme un répertoire et que l’autre ajoute de nouveaux fichiers à l’ancien répertoire, alors les nouveaux fichiers seront laissés en arrière dans l’ancien répertoire sans avertir au moment de rebasage que vous pourriez vouloir déplacer ces fichiers dans le nouveau répertoire.
La détection de renommage de répertoire fonctionne avec le backend merge pour vous fournir des avertissements dans de tels cas.
Contexte
Le backend apply fonctionne en créant une séquence de rustines (en appelant format-patch
en interne), puis en appliquant les rustines en séquence (en appelant am`en interne). Les rustines sont composées de plusieurs sections, chacune avec des numéros de ligne, une région de contexte et les changements réels. Les numéros de ligne doivent être pris avec un certain décalage, puisque l'autre côté aura probablement inséré ou supprimé des lignes plus haut dans le fichier. La région de contexte est destinée à aider à trouver comment ajuster les numéros de ligne afin d'appliquer les changements aux bonnes lignes. Cependant, si plusieurs zones du code ont les mêmes lignes de contexte, le mauvais peut être choisi. Il y a des cas réels où cela a causé la réapplication incorrecte de commits sans conflit signalé. Régler`diff.context
à une valeur plus grande peut éliminer ce type de problèmes, mais augmente les probabilités de conflits (puisque plus de lignes de contexte en correspondance seront nécessaires pour valider l’application de la rustine).
Le backend merge fonctionne avec une copie complète de chaque fichier pertinent, l’isolant de ces types de problèmes.
Étiquetage des marqueurs de conflits
Lorsqu’il y a des conflits de contenu, la machinerie de fusion tente d’annoter les marqueurs de conflit de chaque côté avec les commits d’où le contenu est venu. Comme le backend apply laisse tomber les informations originales sur les commits rebasés et leurs parents (et génère plutôt de nouveaux faux commits basés sur des informations réduties dans les rustines générées), ces commits ne peuvent pas être identifiés ; au lieu de cela, il doit revenir à un résumé de commit. Aussi, quand merge.conflictStyle
est défini à diff3
ou zdiff3
, le backend apply utilisera une « base de fustion construite » pour étiqueter le contenu de la base de fusion, et donc ne fournir aucune information sur le commit de base de fusion.
Le backend merge fonctionne avec les commits complets des deux côtés de l’historique et n’a donc pas de telles limitations.
Crochets
Historiquement, le backend apply n’appellait pas le crochet post-commit, tandis que le backend merge le faisait. Les deux ont appelé le crochet post-checkout, bien que le backend merge n’affiche pas sa sortie. De plus, les deux backends n’appellent le crochet post-checkout qu’avec le point de départ du rebasage, pas les commits intermédiaires ni le commit final. Dans chaque cas, l’appel de ces crochets était un accident d’implémentation plutôt qu’une volonté de conception (les deux backends ont été initialement mis en œuvre comme scripts shell et invoquait ainsi d’autres commandes comme git checkout
ou git commit
qui appellaient les crochets). Les deux backends devraient avoir le même comportement, bien qu’il ne soit pas entièrement clair lequel est correct, si tant est qu’il le soit. rebase va certainementarrêter d’appeler l’un de ces crochets à l’avenir.
Interruptibilité
Le backend apply a des problèmes de sécurité avec une interruption au mauvais moment ; si l’utilisateur presse Ctrl-C au mauvais moment pour essayer d’annuler le rebasage, le rebasage peut entrer dans un état où il ne peut pas être annulé avec un git rebase --abort
ultérieur. Le backend de fusion ne semble pas souffrir de la même définition . (Voir https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ pour plus de détails.)
Reformulation de commit
Lorsqu’un conflit survient en rebasant, rebase s’arrête et demande à l’utilisateur de résoudre les conflits. Comme l’utilisateur peut avoir besoin de faire des changements notables tout en résolvant les conflits, après que les conflits sont réglés et que l’utilisateur a exécuté git rebase --continue
, le rebasage devraitouvrir un éditeur et demander à l’utilisateur de mettre à jour le message de validation. Le backend merge fait cela, alors que le backend apply applique aveuglément le message de commit original.
Diverses différences
Il ya quelques différences comportementales supplémentaires que la plupart des gens considéreraient probablement peu fréquentes mais qui sont mentionnées pour être exhaustif :
-
Reflog : Les deux backends utiliseront des libellés différents pour décrire les modifications apportées au reflog, mais les deux utiliseront le mot "rebase".
-
Messages de progression, d’information et d’erreur : Les deux backends fournissent des messages d’information et de progrès légèrement différents. De plus, le backend apply écrit des messages d’erreur (comme « Vos fichiers seraient écrasés… ») sur stdout, tandis que le backend de fusion les écrit sur stderr.
-
Répertoires d’état : les deux backends conservent leur état dans différents répertoires sous
.git/
LES STRATÉGIES DE FUSION
Le mécanisme de fusion (commandes git merge
et git pull
) permet de choisir les stratégies de fusion du backend avec l’option -s
. Certaines stratégies peuvent également prendre leurs propres options, qui peuvent être passées en donnant des arguments -X<option>
à git merge
et/ou git pull
.
- ort
-
C’est la stratégie de fusion par défaut lors du tirage ou de la fusion d’une branche. Cette stratégie ne peut résoudre que deux têtes en utilisant un algorithme de fusion à trois voies. Lorsqu’il y a plus d’un ancêtre commun qui peut être utilisé pour la fusion à trois, il crée un arbre fusionné des ancêtres communs et l’utilise comme arbre de référence pour la fusion à trois. Il a été rapporté que cela permettait de réduire les conflits de fusion sans provoquer de fausses fusions, grâce à des tests effectués sur de vraies fusions tirées de l’historique de développement du noyau Linux 2.6. En outre, cette stratégie permet de détecter et de gérer les fusions impliquant des renommages. Elle ne peut actuellement pas utiliser les copies détectées. Le nom de cet algorithme est un acronyme ("Ostensibly Recursive’s Twin" : Jumeau ostensible de recurse) et vient du fait qu’il a été écrit pour remplacer l’algorithme par défaut précédent,
recursive
.La stratégie ort peut prendre les options suivantes :
- ours
-
Cette option oblige à résoudre les sections en conflit de manière autonome et propre en favorisant notre version (our). Les modifications par rapport à l’autre arbre qui n’entrent pas en conflit avec notre version se reflètent dans le résultat de la fusion. Pour un fichier binaire, tout le contenu est pris de notre côté.
Il ne faut pas la confondre avec la stratégie de fusion ours, qui ne tient même pas compte de ce que contient l’autre arbre. Elle rejette tout ce que l’autre arbre a fait, déclarant que "notre" historique (our) contient tout ce qui s’y est passé.
- theirs
-
C’est le contraire de ours ; notez que, contrairement à ours, il n’y a pas de stratégie de fusion theirs avec laquelle confondre cette option de fusion.
- ignore-space-change
- ignore-all-space
- ignore-space-at-eol
- ignore-cr-at-eol
-
Traiter les lignes avec le type de changement d’espace indiqué comme inchangées dans l’intérêt d’une fusion à trois points. Les changements d’espacement mélangés à d’autres changements de ligne ne sont pas ignorés. Voir aussi git-diff[1]
-b
,-w
,--ignore-space-at-eol
, et--ignore-cr-at-eol
.-
Si "leur" version (theirs) n’introduit que des changements d’espacement sur une ligne, "notre" version (our) est utilisée ;
-
Si "notre" version introduit des modifications dans l’espace blanc mais que "leur" version inclut un changement substantiel, "leur" version est utilisée ;
-
Dans le cas contraire, la fusion se déroule de la manière habituelle.
-
- renormalize
-
Il s’agit d’une extraction et d’un validation virtuelle des trois étapes d’un fichier lors de la résolution d’une fusion à trois points. Cette option est destinée à être utilisée lors de la fusion de branches avec différents filtres clean ou règles de normalisation de fin de ligne. Voir "Fusion de branches avec différents attributs de validation/extraction" dans gitattributes[5] pour plus de détails.
- no-renormalize
-
Désactiver l’option
renormalize
. Cela surcharge la variable de configurationmerge.renormalize
. - find-renames[=<n>]
-
Activer la détection de renommage, en fixant éventuellement le seuil de similarité. C’est la valeur par défaut. Cela surcharge la variable de configuration
merge.renames
. Voir aussi git-diff[1]--find-renames
. - rename-threshold=<n>
-
Synonyme obsolète pour
find-renames=<n>
. - subtree[=<chemin>]
-
Cette option est une forme plus avancée de stratégie subtree, où la stratégie fait une estimation de la façon dont deux arbres doivent être déplacés pour correspondre l’un à l’autre lors de la fusion. Au lieu de cela, le chemin spécifié est préfixé (ou tronqué au debut) pour faire correspondre la forme de deux arbres.
- recursive
-
Cela ne peut résoudre que deux têtes en utilisant un algorithme de fusion à trois voies. Lorsqu’il y a plus d’un ancêtre commun qui peut être utilisé pour la fusion à trois, il crée un arbre fusionné des ancêtres communs et l’utilise comme arbre de référence pour la fusion à trois. Il a été rapporté que cela permettait de réduire les conflits de fusion sans provoquer de fausses fusions, grâce à des tests effectués sur de vraies fusions tirées de l’historique de développement du noyau Linux 2.6. En outre, cela permet de détecter et de gérer les fusions impliquant des renommages. Cela n’utilise les copies détectées. C’était la stratégie par défaut lors de la résolution de deux sommets pour Git depuis la version v0.99.9k jusqu’à v2.33.0.
La stratégie recursive utilise les mêmes options que ort. Cependant, il y a trois options supplémentaires que ort ignore (non documentées ci-dessus) et qui sont potentiellement utiles avec la stratégie recursive :
- patience
-
Synonyme obsolète pour
diff-algorithm=patience
. - diff-algorithm=[patience|minimal|histogram|myers]
-
Utiliser un algorithme de diff différent lors des fusions, ce qui peut aider à éviter les erreurs de fusion dues à des lignes de correspondance sans importance (comme des accolades de fonctions distinctes). Voir aussi git-diff[1]
--diff-algorithm
. Notez queort
utilise spécifiquementdiff-algorithm=histogram
, alors querecursive
utilise par défaut le paramètre de configurationdiff.algorithm
. - no-renames
-
Désactiver la détection de renommage. Ceci annule la variable de configuration
merge.renames
. Voir aussi git-diff[1]--no-renames
.
- resolve
-
Cela ne peut résoudre que deux têtes (c’est-à-dire la branche actuelle et une autre branche dont vous avez tiré) en utilisant un algorithme de fusion à trois points. Cela essaie de détecter avec soin les ambiguïtés de la fusion croisée. Les renommages ne sont pas gérés.
- octopus
-
Cela permet de résoudre les cas à plus de deux têtes, mais refuse de faire une fusion complexe qui nécessite une résolution manuelle. C’est principalement destiné à être utilisé pour regrouper les têtes de branches thématiques. C’est la stratégie de fusion par défaut lorsque l’on tire ou fusionne plusieurs branches.
- ours
-
Cela résout un nombre quelconque de têtes, mais l’arbre résultant de la fusion est toujours celui de la tête de la branche actuelle, ignorant effectivement toutes les modifications provenant de toutes les autres branches. C’est censé être utilisé pour remplacer l’ancienne historique du développement des branches latérales. Notez que cette stratégie est différente de l’option -Xours de la stratégie de fusion recursive.
- subtree
-
Il s’agit d’une stratégie
ort
modifiée. Lors de la fusion des arbres A et B, si B correspond à un sous-arbre de A, B est d’abord ajusté pour correspondre à la structure arborescente de A, au lieu de lire les arbres au même niveau. Cet ajustement est également effectué sur l’arbre de l’ancêtre commun.
Avec les stratégies qui utilisent la fusion à trois points (y compris la fusion par défaut, ort), si une modification est effectuée sur les deux branches, mais qu’elle est ensuite inversée sur l’une des branches, ce changement sera présent dans le résultat de la fusion ; certaines personnes trouvent ce comportement déroutant. Cela se produit parce que seules les têtes et la base de la fusion sont prises en compte lors d’une fusion, et non le commit individuel. L’algorithme de fusion considère donc le changement inversé comme n’étant pas un changement du tout, et substitue la version modifiée à la place.
NOTES
Vous devriez comprendre les implications de l’utilisation de git rebase
sur un dépôt partagé. Voir la section « RATTRAPER UN REBASAGE AMONT » ci-dessous.
Lorsque le rebasage est exécuté, il exécutera d’abord un crochet pre-rebase
si il existe. Vous pouvez utiliser ce crochet pour faire des vérifications de santé et rejeter le rebasage si il n’est pas approprié. Veuillez voir le modèle de script crochet`pre-rebase` pour un exemple.
Une fois terminé, <branche>
sera la branche actuelle.
MODE INTERACTIF
Rebaser interactivement signifie que vous avez une possibilité de modifier les commits qui sont rebasés. Vous pouvez réordonner les commits, et vous pouvez les supprimer (en éliminant des rustines mauvaises ou autrement indésirables).
Le mode interactif est destiné à ce type de flux de travail :
-
avoir une merveilleuse idée
-
travailler sur le code
-
préparer une série pour propositions
-
proposer
où le point 2. se compose de plusieurs cas
a) utilisation régulière
-
finir quelque chose digne d’un commit
-
valider
b) correction indépendante
-
réaliser que quelque chose ne fonctionne pas
-
réparer ça
-
le valider
Parfois, la chose corrigée en b.2. ne peut pas être ajoutée au commit pas totalement parfait qu’elle corrige, parce que ce commit est enterré profondément dans une série de rustines. C’est exactement ce à quoi le rebasage interactif sert : utilisez-le après beaucoup de "a"s et "b"s, en réorganisant et en éditant des commits, et en combinant plusieurs commits en un.
Commencez avec le dernier commit que vous voulez retenir tel quel :
git rebase -i <après-ce-commit>
Un éditeur sera démarré avec tous les commits dans votre branche actuelle (en ignorant les commits de fusion), qui viennent après le commit donné. Vous pouvez réorganiser à votre goût les commits dans cette liste, et vous pouvez les supprimer. La liste ressemble plus ou moins à ceci :
pick deadbee Le titre de ce commit pick fa1afe1 Le titre du commit suivant ...
Les titres sont purement pour votre usage ; git rebase ne les regardera pas mais s’appuiera sur les noms de commit («deadbee» et «fa1afe1» dans cet exemple), donc ne supprimez pas ou ne modifiez pas les noms.
En remplaçant la commande "pick" par la commande "edit", vous pouvez dire à git rebase
de s’arrêter après l’application de ce commit, afin que vous puissiez modifier les fichiers et/ou le message de validation, modifier le commit, et continuer de rebaser.
Pour interrompre le rebasage (comme une commande "edit" le ferait, mais sans picorer de commit d’abord), utilisez la commande "break".
Si vous voulez simplement modifier le message de validation pour un commit, remplacez la commande "pick" par la commande "reword".
Pour abandonner un commit, remplacer la commande "pick" par "drop", ou supprimez simplement la ligne correspondante.
Si vous voulez replier deux ou plusieurs commits en un, remplacer la commande "pick" pour le second commit et les commits subséquents par "squash" ou "fixup". Si les commits avaient différents auteurs, le commit replié sera attribué à l’auteur du premier commit. Le message de commit proposé pour le commit replié est la concaténation du message du premier commit avec ceux identifiés par les commandes "squash", en omettant les messages de commits identifiés par les commandes "fixup", à moins que "fixup -c" ne soit utilisé. Dans ce cas, le message de validation proposé n’est que le message du commit appliqué par "fixup -c", et un éditeur est ouvert vous permettant de modifier le message. Le contenu (rustine) du commit "fixup -c" sont toujours incorporé dans le commit replié. S’il y a plus d’un commit "fixup -c", le message du dernier est utilisé. Vous pouvez également utiliser "fixup -C" pour obtenir le même comportement que "fixup -c" sauf sans ouvrir un éditeur.
git rebase
s’arrêtera lorsque "pick" a été remplacé par "edit" ou quand une commande échoue en raison d’erreurs de fusion. Lorsque vous avez terminé l’édition et/ou la résolution des conflits, vous pouvez continuer avec git rebase --continue
.
Par exemple, si vous voulez réorganiser les 5 derniers commits, de sorte que ce qui était HEAD~4
devient le nouveau HEAD
. Pour ce faire, vous appelez git rebase
comme ceci :
$ git rebase -i HEAD~5
Et déplacer la première rustine jusqu’à la fin de la liste.
Vous pourriez vouloir recréer des commits de fusion, par exemple si vous avez une histoire comme celle-ci :
X \ A---M---B / ---o---O---P---Q
Supposons que vous voulez rebaser la branche latérale à partir de "A" à "Q". Assurez-vous que la `HEAD`actuelle est "B", et appelez
$ git rebase -i -r --onto Q O
La réorganisation et l’édition des commits créent généralement des étapes intermédiaires non testées. Vous pouvez vérifier que votre édition d’historique n’a rien cassé en exécutant un test, ou au moins en recompilant à des points intermédiaires de l’historique en utilisant la commande "exec" (raccourci "x"). Vous pouvez le faire en créant une liste de todo comme celle-ci :
pick deadbee Implement feature XXX fixup f1a5c00 Fix to feature XXX exec make pick c0ffeee The oneline of the next commit edit deadbab The oneline of the commit after exec cd subdir; make test ...
Le rebasage interactif s’arrêtera quand une commande échouera (c.-à-d. des sorties avec statut non-0) pour vous donner l’occasion de résoudre le problème. Vous pouvez continuer avec git rebase --continue
.
La commande "exec" lance la commande dans un shell (la commande par défaut, habituellement /bin/sh), de sorte que vous pouvez utiliser des fonctions de shell (comme "cd", ">", ";" …). La commande est exécutée de la racine de l’arbre de travail.
$ git rebase -i --exec "make test"
Cette commande vous permet de vérifier que les commits intermédiaires sont compilables. La liste de todo devient ainsi :
pick 5928aea one exec make test pick 04d0fda two exec make test pick ba46169 three exec make test pick f4593f9 four exec make test
DÉCOUPAGE DE COMMITS
En mode interactif, vous pouvez marquer des commits avec l’action "edit". Cependant, cela ne signifie pas nécessairement que git rebase
s’attende à ce que le résultat de cette modification soit exactement un commit. En effet, vous pouvez défaire le commit, ou vous pouvez ajouter d’autres commits. Ceci peut être utilisé pour diviser un commit en deux :
-
Démarrez un rebasage interactif avec
git rebase -i <commit>
, où <commit> est le commit que vous voulez partager. En fait, toute plage de commits fonctionne, tant qu’elle contient ce commit. -
Marquez le commit que vous voulez diviser avec l’action "edit".
-
Au moment d’éditer ce commit, exécutez
git reset HEAD^
. L’effet est que leHEAD
est rembobiné d’un cran et que l’index est mis à jour. Cependant, l’arbre de travail reste le même. -
Maintenant ajoutez les modifications que vous voulez avoir dans le premier commit à l’index . Vous pouvez utiliser
git add
(possiblement interactivement) ougit gui
(ou les deux) pour le faire. -
Validez l’index actuel avec un message de commit approprié.
-
Répétez les deux dernières étapes jusqu’à ce que votre arbre de travail soit propre.
-
Continuez le rebasage avec
git rebase --continue
.
Si vous n’êtes pas absolument sûr que les révisions intermédiaires sont cohérentes (qu’elles compilent, passent la suite de test, etc.) vous devriez utiliser git stash
pour remiser les modifications pas encore validées après chaque commit, puis tester, et modifier le commit si des corrections sont nécessaires.
SE RATTRAPER APRÈS UN REBASAGE AMONT
Rebaser (ou réécrire sous toute autre forme) une branche sur laquelle d’autres ont basé le travail est une mauvaise idée : quiconque en aval est obligé de réparer manuellement son historique. Cette section explique comment corriger cet état du point de vue de l’aval. La vraie solution, cependant, serait d’éviter de rebaser en amont en premier lieu.
Pour illustrer, supposez que vous êtes dans une situation où quelqu’un développe une branche sous-systeme, et que vous travaillez sur un sujet qui dépend de ce sous-systeme. Vous pourriez finir avec un historique comme suit :
o---o---o---o---o---o---o---o master \ o---o---o---o---o sous-systeme \ *---*---* sujet
Si sous-systeme est rebasé sur master, il se produit ce qui suit :
o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o' sous-systeme \ *---*---* sujet
Si vous continuez maintenant le développement comme d’habitude, et finalement fusionnez sujet à sous-systeme, les commits de sous-systeme resteront dupliquées pour toujours :
o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o'--M sous-systeme \ / *---*---*-..........-*--* sujet
De telles doublons sont généralement mal vus parce qu’ils encombrent l’historique, ce qui le rend plus difficile à suivre. Pour nettoyer, vous devez transplanter les commits sur sujet au nouveau sommet de sous-systeme, c’est-à-dire rebaser sujet. Cela s’applique en cascade : toute personne en aval de sujet est obligée de rebaser aussi, et ainsi de suite !
Il existe deux types de corrections, discutées dans les sections suivantes :
- Cas facile : Les modifications sont littéralement les mêmes.
-
Cela se produit si le rebasage sur sous-systeme était un simple rebasage et n’avait aucun conflit.
- Cas dur : les modifications ne sont pas les mêmes.
-
Cela se produit si le rebasage sur sous-systeme avait des conflits, ou a utilisé
--interactive
pour omettre, éditer, écraser, ou corriger des commits ; ou si l’amont a utilisécommit --amend
oureset
, ou une commande de réécriture complète de l’historique commefilter-repo
.
Le cas facile
Ne fonctionne que si les modifications (IDs de rustines basés sur le contenu des diffs) sur sous-systeme sont littéralement les mêmes avant et après le rebasage fait sur sous-systeme
.
Dans ce cas, le correctif est facile car git rebase sait sauter les changements qui sont déjà présents dans le nouvel amont (sauf si --reapply-cherry-picks
est appliqué). Donc si vous dîtes (en supposant que vous êtes sur sujet)
$ git rebase sous-systeme
vous terminerez avec l’historique réparé
o---o---o---o---o---o---o---o master \ o'--o'--o'--o'--o' sous-systeme \ *---*---* sujet
Le cas difficile
Les choses deviennent plus compliquées si les changements de sous-systeme ne correspondent pas exactement à ceux avant le rebasage.
Note
|
Tandis qu’une "récupération de cas facile" semble parfois réussir
même dans le cas difficile, il peut y avoir des conséquences imprévues. Par
exemple, un commit qui a été enlevé via git rebase
--interactive sera ressuscité !
|
L’idée est de dire manuellement à git rebase
"où l’ancien sous-systeme s’est terminé et votre sujet a commencé", c’est-à-dire ce qu’était l’ancienne base de fusion entre eux. Vous devrez trouver un moyen de nommer le dernier commit de l’ancien sous-system, par exemple :
-
Avec le reflog de sous-system : après
git fetch
, l’ancien sommet de sous-systeme est àsous-systeme@{1}
. Les récupérations subséquentes augmenteront le nombre. (Voir git-reflog[1].) -
Par rapport au sommet de sujet : sachant que votre sujet a trois commits, l’ancien sommet de sous-systeme doit être
sujet~3
.
Vous pouvez ensuite transplanter l’ancien sous-systeme..sujet
au nouveau sommet en disant (pour le cas du reflog, et en supposant que vous êtes déjà sur sujet) :
$ git rebase --onto sous-systeme sous-systeme@{1}
L’effet de bord d’une récupération de « cas difficile » est particulièrement terrible : tout le monde en aval de sujet devra maintenant effectuer une récupération de « cas difficile » aussi !
REBASAGE DE FUSIONS
La commande de rebasage interactive a été à l’origine conçue pour gérer des séries de rustines individuelles. En tant que tel, il est logique d’exclure les commits de fusion de la liste de todo, car le développeur a peut-être fusionné le master
alors qu’il travaillait sur la branche, en attendant de rebaser tous les commits sur master
à un moment (en sautant les commits de fusion).
Cependant, il y a des raisons légitimes pour lesquelles un développeur peut vouloir recréer des commits de fusion : garder la structure de la branche (ou « topologie des commit ») lorsqu’il travaille sur plusieurs branches interconnectées.
Dans l’exemple suivant, le développeur travaille sur une branche de sujet qui refactorise la façon dont les boutons sont définis, ainsi que sur une autre branche de sujet qui utilise cette refactorisation pour mettre en œuvre un bouton « Signaler un bug ». La sortie de ‘git log --graph --format=% -5’ peut ressembler à ça :
* Merge branch 'report-a-bug' |\ | * Add the feedback button * | Merge branch 'refactor-button' |\ \ | |/ | * Use the Button class for all buttons | * Extract a generic Button class from the DownloadButton one
Le développeur pourrait vouloir rebaser ces commits sur un nouveau master
tout en gardant la topologie de la branche, par exemple lorsque la première branche de sujet devrait être intégrée dans master
beaucoup plus tôt que la seconde, par exemple, pour résoudre les conflits de fusion avec des modifications à la classe DownloadButton qui ont déjà été intégrées sur ‘master’.
Ce rebasage peut être effectué en utilisant l’option --rebase-merges
. Il générera une liste de todo qui ressemble à ceci :
label onto # Branch: refactor-button reset onto pick 123456 Extract a generic Button class from the DownloadButton one pick 654321 Use the Button class for all buttons label refactor-button # Branch: report-a-bug reset refactor-button # Use the Button class for all buttons pick abcdef Add the feedback button label report-a-bug reset onto merge -C a1b2c3 refactor-button # Merge 'refactor-button' merge -C 6f5e4d report-a-bug # Merge 'report-a-bug'
Contrairement à une base interactive régulière, il y a des commandes label
, reset
et merge
en plus des commandes pick
.
La commande label
associe une étiquette à la HEAD actuelle lorsque cette commande est exécutée. Ces étiquettes sont créées sous forme de refs local à l’arbre-de-travail (refs/rewritten/<étiquette>
) qui seront supprimées lorsque le rebasage sera terminé. De cette façon, les opérations de rebasage dans plusieurs arbre-de-travail liés au même dépôt n’interfèrent pas les uns avec les autres. Si la commande label
échoue, elle est reprogrammée immédiatement, avec un message indiquant comment procéder.
La commande reset
réinitialise la HEAD, l’index et l’abre de travail à la révision spécifiée. Il est semblable à un exec git reset --hard <étiquette>
, mais refuse d’écraser des fichiers non suivis. Si la commande reset
échoue, elle est reprogrammée immédiatement, avec un message indiquant comment modifier la liste de todo (cela arrive généralement quand une commande reset
a été insérée dans la liste de todo manuellement et contient une typo).
La commande merge
fusionnera la ou les révisions spécifiées dans ce qui est HEAD à ce moment-là. Avec -C <commit-original>
, le message de validation de la fusion spécifiée sera utilisé. Lorsque le -C
est changé en minuscule -c
, le message sera ouvert dans un éditeur après une fusion réussie afin que l’utilisateur puisse modifier le message.
Si une commande merge
échoue pour toute raison autre que des conflits de fusion (c.-à-d. lorsque l’opération de fusion n’a même pas commencé), elle est reprogrammée immédiatement.
Par défaut, la commande merge
utilisera la stratégie de fusion ort
pour les fusions normales, et octopus
pour les fusions de plusieurs branches. On peut spécifier une stratégie par défaut pour toutes les fusions en utilisant l’argument --strategy
lorsqu’on invoque rebase
, ou peut remplacer des fusions spécifiques dans la liste interactive des commandes en utilisant une commande exec
pour appeler git merge
explicitement avec un argument --strategy
. Notez que lorsque vous appelez git merge
explicitement comme cela, vous pouvez utiliser le fait que les étiquettes sont des réfs sont locales à l’arbre-de-travail (la réf refs/rewritten/onto
correspondrait à l`étiquette onto
, par exemple) afin de se référer aux branches que vous voulez fusionner.
Note : la première commande (label onto
) étiquette la révision sur laquelle les commits sont rebasés ; Le nom onto
est juste une convention, comme un référence à l’option --onto
.
Il est également possible d’introduire des commits de fusion complètement nouveaux à partir de zéro en ajoutant une commande de la forme merge <tête-de-fusion>
. Cette forme générera un message de validation provisoire et ouvrira toujours un éditeur pour laisser l’utilisateur l’éditer. Cela peut être utile, par exemple lorsqu’une branche de sujet traite plus d’un seul problème et doit être divisée en deux branches de thème ou plus. Considérez cette liste de todo :
pick 192837 Switch from GNU Makefiles to CMake pick 5a6c7e Document the switch to CMake pick 918273 Fix detection of OpenSSL in CMake pick afbecd http: add support for TLS v1.3 pick fdbaec Fix detection of cURL in CMake on Windows
Le seul commit de cette liste qui n’est pas lié à CMake peut très bien avoir été motivé par le travail sur la correction de tous ces bugs introduits en passant à CMake, mais il répond à une préoccupation différente. Pour diviser cette branche en deux branches thématiques, la liste de todo pourrait être modifiée comme ceci :
label onto pick afbecd http: add support for TLS v1.3 label tlsv1.3 reset onto pick 192837 Switch from GNU Makefiles to CMake pick 918273 Fix detection of OpenSSL in CMake pick fdbaec Fix detection of cURL in CMake on Windows pick 5a6c7e Document the switch to CMake label cmake reset onto merge tlsv1.3 merge cmake
CONFIGURATION
Warning
|
Missing See original version for this content. |
Warning
|
Missing See original version for this content. |
Warning
|
Missing See original version for this content. |
GIT
Fait partie de la suite git[1]
TRADUCTION
Cette page de manuel a été traduite par Jean-Noël Avila <jn.avila AT free DOT fr> et les membres du projet git-manpages-l10n. Veuillez signaler toute erreur de traduction par un rapport de bogue sur le site https://github.com/jnavila/git-manpages-l10n .