¿Cómo puedo revertir 1 commit?

127

Tengo 2 commits que no presioné:

$ git status
# On branch master
# Your branch is ahead of 'faves/master' by 2 commits.

¿Cómo puedo hacer retroceder el primero (el más antiguo), pero conservar el segundo?

 $ git log
commit 3368e1c5b8a47135a34169c885e8dd5ba01af5bb
...

commit baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e
...

De aquí:

http://friendfeed.com/harijay/742631ff/git-question-how-do-i-rollback-commit-just-want

¿Solo necesito hacer:

git reset --hard baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e

¿Es decir?

n179911
fuente
3
Esta pregunta parece estar fuera de tema porque se trata de una herramienta de programación. Pertenece a Stack Overflow.
Peter Mortensen
@PeterMortensen De acuerdo. Esto es de alcance para SuperUser
Kolob Canyon

Respuestas:

95

La forma más segura y probablemente más limpia de hacerlo es volver a crear una base interactiva.

git rebase -i HEAD^^

O,

git rebase -i baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e^

Desde allí, puede aplastar las confirmaciones, que reúne una o más confirmaciones en la confirmación anterior. Para eliminar por completo una confirmación del historial, elimine la línea de la lista.

Puede revertir una confirmación con, git revertpero agregará más mensajes de confirmación al historial, lo que puede ser indeseable. Use el -nparámetro para decirle a Git que no confirme la reversión de inmediato. Puede cambiar el nombre de forma interactiva y aplastarlos hasta una comisión anterior para mantener las cosas limpias.

Si las dos confirmaciones con las que está trabajando aquí afectan los mismos archivos, puede ver un conflicto de fusión.

Restablecer el repositorio con git reset --harddebe hacerse con cuidado, ya que no se puede deshacer.

La reescritura del historial debe hacerse con cuidado.

jtimberman
fuente
¿Cómo puedo eliminar un commit durante 'git rebase'? Solo hay 3 comandos: escoger, editar, aplastar. No hay borrar AFAIK.
n179911
8
elimine la línea de la lista por completo, y elimina esa confirmación
jtimberman
cuando quería revertir el cambio no quería dejar rastro de él. Si también desea no dejar rastro de su reversión, esta es la mejor manera de hacerlo.
Phillip Whelan
"La forma más segura y probablemente más limpia de hacer es rebasar de manera interactiva" Tal vez no si no usa vim. Tuve suerte y descubrí mi salida de ese desastre. Todavía votando porque debería aprender vim :-)
isimmons
Sugeriría usar rebaselo menos posible. Si trabajas con otros, simplemente hazlo revert.
boldnik
52

Esto si de http://nakkaya.com/2009/09/24/git-delete-last-commit/ y funcionó para mí

Git Eliminar último compromiso

De vez en cuando a altas horas de la noche, cuando me quedé sin café, cometo cosas que no debería haber hecho. Luego paso los próximos 10 a 15 minutos buscando en Google cómo eliminar el último compromiso que hice. Entonces, después de la tercera vez, quería grabarlo para poder consultarlo más tarde.

Si ha cometido basura pero no ha presionado,

git reset --hard HEAD~1

HEAD ~ 1 es una abreviatura de commit antes de head. Alternativamente, puede consultar el SHA-1 del hash al que desea restablecer. Tenga en cuenta que al usar --hard cualquier cambio en los archivos rastreados en el árbol de trabajo, ya que se pierde el commit antes del encabezado.

Si no desea eliminar el trabajo que ha realizado, puede usar la --softopción que eliminará la confirmación pero dejará todos los archivos modificados "Cambios a confirmar", como lo indicaría el estado de git.

Ahora, si ya presionó y alguien tiró, que suele ser mi caso, no puede usar git reset. Sin embargo, puedes hacer un git revert,

git revert HEAD

Esto creará una nueva confirmación que revierte todo lo introducido por la confirmación accidental.

iStryker
fuente
2
Con la opción --soft, es perfecto para cambiar el nombre de un archivo y accidentalmente "git commit -a" en lugar de usar "git add" primero.
Aaron Harun
8

No. git-reset --hard te devolverá a la historia. Lo que estás buscando es git revert, que deshacerá cualquier confirmación.

Peltier
fuente
44
Bueno, esto funciona pero también contamina el registro de confirmación. Si estos commits no fueron empujados / extraídos ya, es mejor limpiarlos con un rebase interactivo. La capacidad de cambiar el historial es una de las principales ventajas de git sobre otros sistemas de control de versiones.
knweiss
6

Acabo de hacer esto:

git rebase -i HEAD^^

Lo arruiné así que lo hice

git rebase --abort

Luego lo hizo de nuevo. Luego tuve que empujar así:

git push origin master -f

Y destruyó los commits más nuevos que el commit al que había retrocedido. Funcionó muy bien.

hamstar
fuente
4

No, git reset --hard baf8d5eeliminará el 3368e1ccommit y HEAD estará en el baf8d5eposterior.

Si desea mantener el 3368e1ccompromiso y eliminar el bad8d5ecompromiso, la solución más fácil es hacer un " git rebase -i HEAD~2" (es decir, un rebase interactivo de los dos últimos compromisos). Este comando iniciará su editor de mensajes de confirmación y verá una línea para cada una de las últimas dos confirmaciones. Allí simplemente borra la bad8d5elínea de confirmación y guarda. git reescribirá su historial y la segunda confirmación se habrá ido.

Hay otros comandos útiles que se pueden utilizar en el editor de mensajes de confirmación como squash, edit, etc. rebase interactivo es muy poderoso!

¡No haga esto si alguien ya vio estos commits (push o pull de su repositorio)!

Knweiss
fuente
1
git reset --hard {ref}

es la única forma de deshacer una confirmación si solo hay otra confirmación en el repositorio (por ejemplo, confirmación inicial y 1 más). El resto de las formas (revertir, rebase) se niegan a trabajar, al menos a partir de git 1.7.5.1.

Si sigue el comando git resetcon a, git gcentonces git eliminará los datos de confirmación anteriores del repositorio por completo.

enjugador de goma
fuente
1
git checkout <treeish> -- /path/to/dir

Eso traerá de vuelta el directorio del "árbol" dado para el / path / to / dir

lokeshpahal
fuente
0

Conseguí que esto funcionara editando manualmente los códigos hash de los últimos commits de los archivos HEAD dentro de la carpeta del repositorio:

"centralRepository\refs\heads\master"
"centralRepository\refs\heads\branch2"

Antes de eso, nunca pude impulsar para originar las operaciones UNMERGE que hice localmente. Siguió diciendo que "no pudo empujar algunas referencias" al Repositorio Central.

Leandro M
fuente