Supposons que votre historique git ressemble à ceci:
1 2 3 4 5
1 à 5 sont des révisions distinctes. Vous devez supprimer 3 tout en conservant 1, 2, 4 et 5. Comment procéder?
Existe-t-il une méthode efficace lorsqu'il y a des centaines de révisions après celle à supprimer?
git rebase --onto 2 3 HEAD
signifie à peu près rebaser sur 2, avec des commits entre 3 et HEAD (HEAD est facultatif, ou 5 dans ce cas)Réponses:
Pour combiner les révisions 3 et 4 en une seule révision, vous pouvez utiliser git rebase. Si vous souhaitez supprimer les modifications de la révision 3, vous devez utiliser la commande d'édition en mode de rebase interactif. Si vous souhaitez combiner les modifications en une seule révision, utilisez squash.
J'ai utilisé avec succès cette technique de squash, mais je n'ai jamais eu besoin de supprimer une révision auparavant. La documentation de git-rebase sous "Splitting commits" devrait, espérons-le, vous donner suffisamment d'idée pour le comprendre. (Ou quelqu'un d'autre pourrait le savoir).
De la documentation git :
la source
D'après ce commentaire (et j'ai vérifié que c'est vrai), la réponse de rado est très proche mais laisse git dans un état de tête détaché. Au lieu de cela, supprimez-le
HEAD
et utilisez-le pour supprimer<commit-id>
de la branche sur laquelle vous vous trouvez:la source
^
pour le~1
faire fonctionner.--strategy-option theirs
le à la fin.Voici un moyen de supprimer de manière non interactive un élément spécifique
<commit-id>
, en ne connaissant que les éléments que<commit-id>
vous souhaitez supprimer:la source
HEAD
afin d'éviter une tête détachée.Comme indiqué précédemment, git-rebase (1) est votre ami. En supposant que les commits sont dans votre
master
branche, vous feriez:Avant:
Après:
Depuis git-rebase (1):
la source
--onto master~3 master~1
?MERGE CONFLICT
erreur. J'ai utilisé le scénario mentionné dans stackoverflow.com/questions/2938301/remove-specific-commit et je ne parviens pas à supprimer le 2e commit dans cet exemple.Si tout ce que vous voulez faire est de supprimer les modifications apportées dans la révision 3, vous pouvez utiliser git revert.
Git revert crée simplement une nouvelle révision avec des modifications qui annulent toutes les modifications de la révision que vous rétablissez.
Cela signifie que vous conservez des informations sur la validation indésirable et la validation qui supprime ces modifications.
C'est probablement beaucoup plus convivial s'il est possible que quelqu'un se soit retiré de votre référentiel entre-temps, car le retour est fondamentalement juste un commit standard.
la source
Jusqu'à présent, toutes les réponses ne répondent pas à la préoccupation finale:
Les étapes suivent, mais pour référence, supposons l'historique suivant:
C : commit juste après le commit à supprimer (clean)
R : le commit à supprimer
B : commit juste avant le commit à supprimer (base)
En raison de la contrainte «des centaines de révisions», je suppose les conditions préalables suivantes:
Il s'agit d'un ensemble de contraintes assez restrictif, mais il existe une réponse intéressante qui fonctionne réellement dans ce cas d'angle.
Voici les étapes:
git branch base B
git branch remove-me R
git branch save
git rebase --preserve-merges --onto base remove-me
S'il n'y a vraiment pas de conflits, cela devrait se poursuivre sans autres interruptions. S'il y a des conflits, vous pouvez les résoudre et
rebase --continue
ou décider de vivre avec l'embarras etrebase --abort
.Maintenant, vous devriez être sur
master
qui n'a plus validé R dedans. Lasave
branche indique où vous étiez avant, au cas où vous souhaiteriez vous réconcilier.La façon dont vous souhaitez organiser le transfert de tous les autres vers votre nouvel historique dépend de vous. Vous aurez besoin de connaître
stash
,reset --hard
etcherry-pick
. Et vous pouvez supprimer lesbase
,remove-me
et lessave
branchesla source
J'ai également atterri dans une situation similaire. Utilisez un rebase interactif à l'aide de la commande ci-dessous et tout en sélectionnant, supprimez le 3e commit.
la source
Voici donc le scénario auquel j'ai fait face et comment je l'ai résolu.
voici
R
le commit que je devais supprimer, etI
c'est un seul commit qui vient aprèsR
J'ai fait un commit de retour et les ai écrasés ensemble
Lors du squash de rebase interactif, les 2 derniers commits.
la source
Les réponses de rado et de kareem ne font rien pour moi (seul le message "La branche actuelle est à jour." Apparaît). Cela peut se produire car le symbole «^» ne fonctionne pas dans la console Windows. Cependant, selon ce commentaire, le remplacement de '^' par '~ 1' résout le problème.
la source