Deshacer una rebase de git


¿Alguien sabe cómo deshacer fácilmente un rebase de git?

La única manera que viene a la mente es ir a ella manualmente:

  • git checkout el padre de confirmación para ambas ramas
  • luego crea una rama temporal desde allí
  • cherry-elige todas las confirmaciones a mano
  • reemplace la rama en la que rebasé por la rama creada manualmente

En mi situación actual esto va a funcionar porque puedo detectar fácilmente confirmaciones de ambas ramas (una fue mi cosas, el otro era cosas de mi colega).

Sin embargo, mi enfoque me parece subóptimo y propenso a errores (digamos que acabo de rebasado con 2 de mis propias ramas).

¿Alguna idea?

Aclaración: Estoy hablando de un rebase durante el cual un montón de commits fueron reproducidos. No sólo uno.

Author: webmat, 2008-09-25

15 answers

La forma más fácil sería encontrar el commit head de la rama como estaba inmediatamente antes de que comenzara el rebase en el reflog ...

git reflog

Y restablecer la rama actual (con las advertencias habituales sobre estar absolutamente seguro antes de resetear con la opción --hard).

Supongamos que el antiguo commit estaba HEAD@{5} en el registro de ref:

git reset --hard HEAD@{5}

En Windows, es posible que necesite citar la referencia:

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

Puede consultar el historial del candidato vieja cabeza por sólo hacer un git log HEAD@{5} (Ventanas: git log "HEAD@{5}").

Si no has desactivado los reflogs por rama, deberías poder simplemente hacer git reflog branchname@{1} como un rebase separa el cabezal de rama antes de volver a conectarlo al cabezal final. Me gustaría volver a comprobar esto, aunque como no he verificado esto recientemente.

Por defecto, todos los reflogs están activados para repositorios no desnudos:

[core]
    logAllRefUpdates = true
 3449
Author: CB Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-20 03:32:48

En realidad, rebase guarda su punto de partida en ORIG_HEAD por lo que esto suele ser tan simple como:

git reset --hard ORIG_HEAD

Sin embargo, el reset, rebase y merge todos guardan su puntero HEAD original en ORIG_HEAD por lo tanto, si ha hecho cualquiera de esos comandos desde el rebase que está tratando de deshacer, entonces tendrá que usar el reflog.

 1216
Author: Pat Notz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-28 13:24:50

La respuesta de Carlos funciona, pero es posible que desee hacer esto:

git rebase --abort

Para limpiar después de la reset.

De lo Contrario, puede recibir el mensaje "Interactive rebase already started".

 321
Author: Allan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-10 03:12:43

Restablecer la rama al objeto de confirmación colgando de su tip antiguo es, por supuesto, la mejor solución, porque restaura el estado anterior sin gastar ningún esfuerzo. Pero si usted ha perdido esas confirmaciones (f.ex. debido a que recopiló su repositorio en el ínterin, o este es un clon nuevo), siempre puede volver a cambiar la base de la rama de nuevo. La clave para esto es el interruptor --onto.

Digamos que tienes una rama temática imaginativamente llamada topic, que se ramificó master cuando la punta de master era la 0deadbeef commit. En algún momento mientras estaba en la rama topic, lo hizo git rebase master. Ahora quieres deshacer esto. He aquí cómo:

git rebase --onto 0deadbeef master topic

Esto tomará todas las confirmaciones en topic que no están en master y las repetirá encima de 0deadbeef.

Con --onto, puedes reorganizar tu historial en prácticamente cualquier forma.

Diviértete. :-)

 77
Author: Aristotle Pagaltzis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-26 02:47:34

En realidad pongo una etiqueta de copia de seguridad en la rama antes de hacer cualquier operación no trivial (la mayoría de las rebases son triviales, pero lo haría si se ve en cualquier lugar complejo).

Entonces, restaurar es tan fácil como git reset --hard BACKUP.

 63
Author: Alex Gontmakher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-24 05:08:16

En caso de que haya enviado su rama al repositorio remoto (generalmente es el origen) y luego haya hecho un rebase exitoso (sin combinar) (git rebase --abort da "No hay rebase en progreso") puede fácilmente restablecer la rama utilizando orden:

Git reset origin hard origin / {branchName}

Ejemplo:

$ ~/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
Author: Maksym,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-05 10:12:49

En caso de que no hayas completado la rebase y en el medio de ella, lo siguiente funciona:

git rebase --abort
 50
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-15 20:20:39

Me sorprende que nadie haya mencionado esto aquí todavía. Rebase deja el estado anterior como ORIG_HEAD, por lo que puede revertir la última rebase ejecutando:

git reset --hard ORIG_HEAD
 22
Author: Meligy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-02 12:56:51

Usar reflog no funcionó para mí.

Lo que funcionó para mí fue similar a como se describe aquí. Abre el archivo .git / logs / refs lleva el nombre de la rama que se rebase y encuentra la línea que contiene "rebase finsihed", algo así como:

5fce6b51 88552c8f Kris Leech <[email protected]> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

Checkout el segundo commit listado en la línea.

git checkout 88552c8f

Una vez confirmado que esto contenía mis cambios perdidos, me ramifiqué y dejé escapar un suspiro de alivio.

git log
git checkout -b lost_changes
 15
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-20 13:59:06

Para múltiples commits, recuerde que cualquier commit hace referencia a todo el historial previo a ese commit. Así que en la respuesta de Charles, lee "el antiguo commit "como" el más nuevo de los antiguos commits". Si restableces ese commit, entonces todo el historial que conduce a ese commit volverá a aparecer. Esto debería hacer lo que quieras.

 14
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-25 21:36:50

Siguiendo la solución de @Allan y @Zearin, me gustaría simplemente hacer un comentario, pero no tengo suficiente reputación, así que he utilizado el siguiente comando:

En Lugar de hacer git rebase -i --abort (nota de la -i) tuve que hacer simplemente git rebase --abort (sin el -i).

Usar -i y --abort al mismo tiempo hace que Git me muestre una lista de uso/opciones.

Así que mi estado de rama anterior y actual con esta solución es:

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

matbhz@myPc /my/project/environment (branch-123)
$
 11
Author: Matheus Felipe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-11 21:26:47

Si has rebasado con éxito la rama remota y no puedes git rebase --abort todavía puedes hacer algunos trucos para guardar tu trabajo y no tener empujones forzados. Supongamos que su rama actual que fue rebasada por error se llama your-branch y está rastreando origin/your-branch

  • git branch -m your-branch-rebased # cambiar el nombre de la rama actual
  • git checkout origin/your-branch # checkout al estado más reciente que se conoce como origen
  • git checkout -b your-branch
  • marque git log your-branch-rebased, compare con git log your-branch y defina confirmaciones que faltan en your-branch
  • git cherry-pick COMMIT_HASH para cada commit en your-branch-rebased
  • envía tus cambios. Tenga en cuenta que dos ramas locales están asociadas con remote/your-branch y debe empujar solo your-branch
 9
Author: Sergey P. aka azure,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-23 09:23:45

Digamos que rebase master a mi rama de características y obtengo 30 nuevas confirmaciones que rompen algo. He encontrado que a menudo es más fácil simplemente eliminar las confirmaciones malas.

git rebase -i HEAD~31

Rebase interactivo para los últimos 31 commits (no hace daño si eliges demasiados).

Simplemente tome las confirmaciones de las que desea deshacerse y márquelas con "d" en lugar de "pick". Ahora los commits se eliminan deshaciendo efectivamente el rebase (si eliminas solo los commits que acabas de recibir cuando rebase).

 4
Author: Hardev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-09 12:25:35

Si estropeas algo dentro de una rebase de git, por ejemplo git rebase --abort, mientras tienes archivos sin confirmar, se perderán y git reflog no ayudará. Esto me pasó a mí y tendrá que pensar fuera de la caja aquí. Si tiene suerte como yo y usa IntelliJ Webstorm, entonces puede right-click->local history y puede revertir a un estado anterior de su archivo/carpetas sin importar los errores que haya cometido con el software de control de versiones. Siempre es bueno tener otro a prueba de fallos en ejecución.

 -2
Author: nottinhill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-18 12:25:18

Para cancelar, puede ingresar el siguiente comando:

git -c core.quotepath=false rebase --abort
 -8
Author: Kostya Andreev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-15 05:31:43