Question Annulation d'un rebas git


Est-ce que quelqu'un sait comment annuler facilement un rebas git?

La seule façon qui me vient à l'esprit est d'y aller manuellement:

  • git checkout le parent de commit aux deux branches
  • puis créer une branche de temp à partir de là
  • cherry-pick tous les commits à la main
  • remplacer la branche dans laquelle j'ai rebasé par la branche créée manuellement

Dans ma situation actuelle, ça va marcher parce que je peux facilement repérer les commits des deux branches (l'un était mon truc, l'autre était le truc de mon collègue).

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

Des idées?

Clarification: Je parle d'un rebasage au cours duquel plusieurs commits ont été rejoués. Non seulement un.


2428
2017-09-25 17:59


origine


Réponses:


Le plus simple serait de trouver la tête de la branche telle qu'elle était juste avant le début du rebasage reflog...

git reflog

et de réinitialiser la branche actuelle (avec les mises en garde habituelles d'être absolument sûr avant de remettre à --hard option).

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

git reset --hard HEAD@{5}

Dans Windows, vous devrez peut-être citer la référence:

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

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

Si vous n'avez pas désactivé par reflogs de branche, vous devriez être capable de faire simplement git reflog branchname@{1} comme une rebase détache la tête de branche avant de se rattacher à la tête finale. Je revérifierais ceci, bien que je ne l'ai pas vérifié récemment.

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

[core]
    logAllRefUpdates = true

3360
2017-09-25 19:56



En fait, rebase enregistre votre point de départ ORIG_HEAD donc c'est habituellement aussi simple que:

git reset --hard ORIG_HEAD

Cependant, le reset, rebase et merge tout enregistrer votre original HEAD pointeur dans ORIG_HEAD Par conséquent, si vous avez exécuté l'une de ces commandes depuis le rebasage que vous essayez d'annuler, vous devrez utiliser le reflet.


1166
2018-03-28 13:24



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

git rebase --abort

nettoyer après le reset.

Sinon, vous pouvez recevoir le message "Interactive rebase already started".


317
2017-07-27 18:21



Réinitialiser la branche à l'objet commit dangling de son ancien tip est bien sûr la meilleure solution, car elle restaure l'état précédent sans dépenser d'effort. Mais s'il vous arrive d'avoir perdu ces validations (par exemple parce que vous avez collecté votre dépôt dans l'intervalle, ou qu'il s'agit d'un nouveau clone), vous pouvez toujours rebaser la branche. La clé de ceci est la --onto commutateur.

Disons que vous aviez une branche sujet imaginativement appelée topic, que vous avez bifurqué master quand la pointe de master était le 0deadbeef commettre. À un moment donné, sur le topic branche, vous avez fait git rebase master. Maintenant, vous voulez annuler cela. Voici comment:

git rebase --onto 0deadbeef master topic

Cela prendra tous les engagements sur topic qui ne sont pas sur master et rejouez-les au-dessus de 0deadbeef.

Avec --onto, vous pouvez réorganiser votre histoire à peu près n'importe quelle forme.

S'amuser. :-)


74
2017-09-26 02:08



En fait, je mets une balise de sauvegarde sur la branche avant de faire une opération non triviale (la plupart des rebasages sont triviaux, mais je le ferais si cela semble complexe).

Ensuite, la restauration est aussi simple que git reset --hard BACKUP.


61
2018-05-12 20:57



Au cas où vous aviez poussé votre branche vers un référentiel distant (habituellement c'est l'origine) et ensuite vous avez fait une rebase réussie (sans fusion) (git rebase --abort donne "No rebase in progress") vous pouvez facilement réinitialiser la branche en utilisant commander:

git reset --hard origine / {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

52
2017-09-28 12:43



Dans le cas où vous n'avez pas terminé le rebase et au milieu, les travaux suivants:

git rebase --abort

48
2017-10-15 20:20



Pour les validations multiples, rappelez-vous que toute validation fait référence à l'historique précédant cette validation. Donc, dans la réponse de Charles, lisez "le vieux commit" comme "le plus récent des anciens". Si vous réinitialisez à ce commit, tout l'historique précédant ce commit réapparaîtra. Cela devrait faire ce que vous voulez.


13
2017-09-25 21:36



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

Ce qui a fonctionné pour moi était similaire à celui décrit ici. Ouvrez le fichier dans .git / logs / refs nommé après la branche qui a été rebasée et trouvez 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

Checkout le deuxième commit listé sur la ligne.

git checkout 88552c8f

Une fois confirmé que cela contenait mes changements perdus, je me suis ramifié et j'ai poussé un soupir de soulagement.

git log
git checkout -b lost_changes

13
2018-02-20 13:59