Défaire un git rebase

est-ce que quelqu'un sait comment défaire facilement un git rebase?

Le seul moyen qui vient à l'esprit est d'aller à la manuellement:

  • git checkout le commit parent à la fois des branches
  • puis créer une branche temporaire à partir de là
  • cerise-pick tout commet à la main
  • remplacer la branche dans laquelle j'ai rebasé par la branche créée manuellement

dans ma situation actuelle cela va marcher parce que je peux facilement repérer les commits des deux branches (l'une était mes affaires, l'autre était les affaires de mon collègue).

cependant mon approche me semble sous-optimale et sujette aux erreurs (disons que je venais de rebaser avec 2 de mes propres branches).

des idées?

Clarification: je parle d'un rebase au cours duquel un tas de commits ont été rejoués. Pas un seul.

2488
demandé sur webmat 2008-09-25 21:59:22

15 réponses

la manière la plus simple serait de trouver la propagation principale de la branche comme elle était immédiatement avant le début de la rebase dans le refrog ...

git reflog

et de réinitialiser la branche courante (avec les mises en garde habituelles sur le fait d'être absolument sûr avant de se réunir à nouveau avec l'option --hard ).

supposons que l'ancien commit était HEAD@{5} dans le journal de référence:

git reset --hard HEAD@{5}

In Windows, vous pouvez avoir besoin de citer la référence:

git reset --hard "HEAD@{5}"

vous pouvez vérifier l'histoire de la vieille tête candidate en faisant simplement un git log HEAD@{5} ( fenêtres: git log "HEAD@{5}" ).

si vous n'avez pas désactivé les réflexes par branche, vous devriez pouvoir simplement faire git reflog branchname@{1} comme un rebase détache la tête de branche avant de rattacher à la tête finale. Je voudrais revérifier ceci, bien que je n'ai pas vérifié ceci récemment.

par défaut, tous les reflogs sont activés pour les dépôts non-bare:

[core]
    logAllRefUpdates = true
3449
répondu CB Bailey 2016-10-20 03:32:48

en fait, rebase sauve votre point de départ à ORIG_HEAD donc c'est aussi simple que:

git reset --hard ORIG_HEAD

cependant, les reset , rebase et merge sauvegardent tous votre pointeur original HEAD dans ORIG_HEAD donc, si vous avez fait l'une de ces commandes depuis le rebase que vous essayez de défaire alors vous devrez utiliser le reclog.

1216
répondu Pat Notz 2009-03-28 13:24:50

la réponse de Charles fonctionne, mais vous pouvez vouloir faire ceci:

git rebase --abort

pour nettoyer après le reset .

sinon, vous pouvez obtenir le message " Interactive rebase already started ".

321
répondu Allan 2017-01-10 03:12:43

réinitialiser la branche à l'objet de commit Pendu de son ancienne pointe est bien sûr la meilleure solution, car il restaure l'état précédent sans aucun effort. Mais s'il vous arrive d'avoir perdu ceux-là commet (F. ex. parce que vous avez ramassé votre dépôt en attendant, ou c'est un clone frais), vous pouvez toujours rebaser la branche à nouveau. La clé est le commutateur --onto .

disons que vous aviez une branche de sujet appelée imaginativement topic , que vous avez bifurqué de master quand la pointe de master était le 0deadbeef commit. À un certain moment sur la branche topic , vous avez fait git rebase master . Maintenant tu veux défaire ça. Voici comment:

git rebase --onto 0deadbeef master topic

cela prendra toutes les commits sur topic qui ne sont pas sur master et les rejouer sur le dessus de 0deadbeef .

avec --onto , vous pouvez réorganiser votre histoire en forme que ce soit .

amusez-vous bien. :- )

77
répondu Aristotle Pagaltzis 2008-09-26 02:47:34

en fait, j'ai mis une étiquette de sauvegarde sur la branche avant de faire toute opération non triviale (la plupart des rebases sont triviales, mais je le ferais si elle semble complexe).

alors, restaurer est aussi facile que git reset --hard BACKUP .

63
répondu Alex Gontmakher 2013-05-24 05:08:16

dans le cas vous aviez poussé votre branche vers le dépôt distant (généralement c'est son origine) et puis vous avez fait une rebase succesfull (sans fusion) ( git rebase --abort donne "pas de rebase en cours") vous pouvez facilement réinitialiser la branche en utilisant commande:

git reset --hard origin / {branchName}

exemple:

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is ahead of 'origin/{branchName}' by 135 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

$ ~/work/projects/{ProjectName} $ git reset --hard origin/{branchName}
HEAD is now at 6df5719 "Commit message".

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is up-to-date with 'origin/{branchName}.

nothing to commit, working directory clean
53
répondu Maksym 2016-02-05 10:12:49

dans le cas où vous n'avez pas terminé le rebase et au milieu de celui-ci, les travaux suivants:

git rebase --abort
50
répondu Alex 2014-10-15 20:20:39

je suis surpris que personne ne l'ait encore mentionné ici. Rebase sort de l'ancien état comme ORIG_HEAD , donc vous pouvez inverser le dernier rebase en lançant:

git reset --hard ORIG_HEAD
22
répondu Meligy 2018-08-02 12:56:51

en utilisant reflog n'a pas fonctionné pour moi.

ce qui a fonctionné pour moi était similaire à ce qui a été décrit ici . Ouvrez le fichier dans .git / logs/refs nommé d'après la branche qui a été rebasé et trouver la ligne qui contient "rebase finsihed", quelque chose comme:

5fce6b51 88552c8f Kris Leech <me@example.com> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

la Caisse de la deuxième commettre apparaît sur la ligne.

git checkout 88552c8f

une fois confirmé qu'il contenait mes modifications perdues, je me suis ramifié et j'ai laissé sortir un soupir de soulagement.

git log
git checkout -b lost_changes
15
répondu Kris 2012-02-20 13:59:06

pour les commits multiples, rappelez-vous que tout commit renvoie à toute l'histoire menant à ce commit. Ainsi, dans la réponse de Charles, lisez "le vieux commit" comme "le plus récent du vieux commit". Si vous réinitialisez ce commit, alors toute l'histoire menant à ce commit réapparaîtra. Cela devrait faire ce que vous voulez.

14
répondu Greg Hewgill 2008-09-25 21:36:50

suite à la solution de @Allan et @Zearin, j'aimerais pouvoir simplement faire un commentaire mais je n'ai pas assez de réputation, donc j'ai utilisé la commande suivante:

au lieu de git rebase -i --abort (notez le - i ) j'ai dû simplement faire git rebase --abort ( sans le - i ).

en utilisant à la fois -i et --abort en même temps provoque Git pour me montrer une liste de l'utilisation de la/des options.

donc mon statut précédent et actuel de branche avec cette solution est:

matbhz@myPc /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort

matbhz@myPc /my/project/environment (branch-123)
$
11
répondu Matheus Felipe 2015-03-11 21:26:47

si vous avez rebasé avec succès contre la branche distante et ne peut pas git rebase --abort vous pouvez toujours faire quelques trucs pour sauver votre travail et ne pas avoir des pousses forcées. Supposons que votre branche actuelle qui a été rebasée par erreur s'appelle your-branch et suit origin/your-branch

  • git branch -m your-branch-rebased # renommer la branche actuelle
  • git checkout origin/your-branch # checkout pour dernier état connu à l'origine
  • git checkout -b your-branch
  • cochez git log your-branch-rebased , comparez à git log your-branch et définissez les propagations manquantes de your-branch
  • git cherry-pick COMMIT_HASH pour s'engager dans your-branch-rebased
  • poussez vos changements. S'il vous plaît noter que deux branches locales sont associées à remote/your-branch et vous devez pousser seulement your-branch
9
répondu Sergey P. aka azure 2016-06-23 09:23:45

disons que je rebase master à ma branche de fonctionnalité et j'obtiens 30 nouveaux commits qui cassent quelque chose. J'ai découvert que souvent, il est plus facile d'enlever les mauvaises commissions.

git rebase -i HEAD~31

rebase Interactive pour les 31 dernières commits (ça ne fait pas de mal si vous choisissez beaucoup trop).

il suffit de prendre les commits dont vous voulez vous débarrasser et de les marquer avec" d "au lieu de"pick". Maintenant les commits sont supprimés, ce qui annule le rebase (si vous supprimez seulement les propagations que vous venez de recevoir lors du rebasement).

4
répondu Hardev 2017-02-09 12:25:35

si vous gâchez quelque chose dans une git rebase, par exemple git rebase --abort , alors que vous avez des fichiers non engagés, ils seront perdus et git reflog n'aidera pas. Cela m'est arrivé et vous aurez besoin de penser en dehors de la boîte ici. Si vous êtes chanceux comme moi et utilisez IntelliJ Webstorm puis vous pouvez right-click->local history et pouvez revenir à un état précédent de votre fichier/dossiers peu importe les erreurs que vous avez faites avec le logiciel de versioning. Il est toujours bon d'avoir un autre failsafe en cours d'exécution.

-2
répondu nottinhill 2018-07-18 12:25:18

pour annuler, vous pouvez entrer la commande suivante:

git -c core.quotepath=false rebase --abort
-8
répondu Kostya Andreev 2016-03-15 05:31:43