¿Cómo revertir el git commit inicial?

358

Me comprometo a un repositorio git por primera vez; Luego lamento el compromiso y quiero revertirlo. lo intento

# git reset --hard HEAD~1

Recibo este mensaje:

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.

Este commit es el primer commit del repositorio. ¿Alguna idea de cómo deshacer la confirmación inicial de git?

Chau Chee Yang
fuente

Respuestas:

566

Solo necesita eliminar la rama en la que se encuentra. No se puede usar git branch -Dya que esto tiene un control de seguridad para no hacerlo. Puedes usar update-refpara hacer esto.

git update-ref -d HEAD

No , no use rm -rf .gitni nada de esto, ya que esto eliminar por completo toda su repositorio incluyendo todas las demás ramas, así como la rama que usted está tratando de restablecer.

CB Bailey
fuente
1
Intenté esto mientras estaba en un rebase, quería dividir el primer commit, luego lo hice git status, y para mi sorpresa, ¡git dijo fatal: Not a git repository (or any parent up to mount point ...)!
Matt Fenwick el
1
Esto no funcionó para mí. Cree archivos que incluyan algunos que deben ignorarse pero no .gitignore. git add ., git commit -m "initial commit", git update-ref -D HEAD, Cree una .gitignore, el aviso de que git todavía está viendo los archivos que agregó anteriormente que deben ignorarse. En otras palabras git update-ref -d HEAD, no me llevó de regreso al estado antes de la confirmación inicial.
gman
1
Pero ese es el punto de la pregunta original. Volviendo al estado justo antes de la confirmación inicial.
gman
2
git reset --hard HEAD~1eliminaría los archivos agregados para todos los otros commits. Claramente, la pregunta es cómo llegar al mismo estado en que ese comando funciona en todos los demás casos. Vea este resumen para probar que su solución no funciona gist.github.com/greggman/522fa69a21d6cfb3ff0b
gman
11
En caso de que alguien se confunde por los comentarios de gman: git update-ref -d HEAD no realmente revertir comprometen la inicial, pero mantiene todos los cambios previamente comprometidos añadido al índice. Si también desea eliminar esos cambios, simplemente ejecute lo siguiente git reset --hard. Incluso si está incompleta, esta respuesta es la mejor, así que evite usarla rm -fr .git(a menos que sepa lo que está haciendo).
rsenna
62

Puede eliminar el HEAD y restaurar su repositorio a un nuevo estado, donde puede crear una nueva confirmación inicial:

git update-ref -d HEAD

Después de crear una nueva confirmación, si ya ha empujado al control remoto, deberá forzarlo al control remoto para sobrescribir la confirmación inicial anterior:

git push --force origin
frazras
fuente
1
Vale la pena señalar ... este es el comando correcto, pero no elimina HEAD ... elimina la referencia (ubicada bajo .git \ refs \ heads) que el archivo .git \ HEAD ha extraído. Después de ejecutar este comando, aún puede encontrar el archivo HEAD apuntando al archivo refs / heads / <name> que eliminó, pero si sigue esa ruta verá que la referencia de los cabezales ya no existe.
DanK
15

Esta pregunta se vinculó desde esta publicación de blog y se propuso una solución alternativa para las versiones más nuevas de Git:

git branch -m master old_master
git checkout --orphan master
git branch -D old_master

Esta solución supone que:

  1. Solo tiene una confirmación en su mastersucursal
  2. No hay una rama llamada, old_masterasí que soy libre de usar ese nombre.

Cambiará el nombre de la rama existente old_mastery creará una nueva rama huérfana master (como se crea para los nuevos repositorios) después de lo cual puede eliminar libremente old_master... o no. Depende de usted.

Nota: Mover o copiar una rama de git conserva su reflog (vea este código ) mientras elimina y luego crea una nueva rama la destruye. Dado que desea volver al estado original sin historial, es probable que desee eliminar la rama, pero otros pueden considerar esta pequeña nota.

tonto
fuente
11

En las condiciones estipuladas en la pregunta:

  • El commit es el primer commit en el repositorio.
  • Lo que significa que se han ejecutado muy pocos comandos:
    • una git init,
    • presumiblemente algunas git addoperaciones,
    • y una git commit,
    • ¡y eso es todo!

Si se cumplen esas condiciones previas, la forma más sencilla de deshacer la confirmación inicial sería:

rm -fr .git

del directorio donde lo hiciste git init. Luego puede rehacer git initpara recrear el repositorio de Git y rehacer las adiciones con cualquier cambio que sea razonable que haya lamentado no haber hecho la primera vez, y rehacer la confirmación inicial.

¡PELIGRO! Esto elimina el directorio del repositorio de Git.

Elimina el directorio del repositorio de Git de forma permanente e irrecuperable, a menos que tenga copias de seguridad en algún lugar. Bajo las condiciones previas, no tiene nada que desee mantener en el repositorio, por lo que no está perdiendo nada. Todos los archivos que agregó todavía están disponibles en los directorios de trabajo, suponiendo que aún no los haya modificado y no los haya eliminado, etc. Sin embargo, hacer esto es seguro solo si no tiene nada más en su repositorio. En las circunstancias descritas en la pregunta "confirmar repositorio por primera vez, luego arrepentirse", es seguro. Sin embargo, muy a menudo no es seguro.

También es seguro hacer esto para eliminar un repositorio clonado no deseado; no daña el repositorio del que fue clonado. Desecha todo lo que has hecho en tu copia, pero no afecta al repositorio original de lo contrario.

Tenga cuidado, pero es seguro y efectivo cuando se cumplen las condiciones previas.

Si ha hecho otras cosas con su repositorio que desea preservar, entonces esta no es la técnica adecuada: su repositorio ya no cumple con las condiciones previas para que esto sea apropiado.

Jonathan Leffler
fuente
99
Este es un mal consejo. ¿Qué pasa si hay otras cosas en el repositorio que no quieres perder?
Matt Fenwick
55
Entonces no sería la confirmación inicial, ¿verdad? Solo hay una confirmación inicial.
Jonathan Leffler
99
"Entonces no sería la confirmación inicial" - en realidad, sí lo sería. Estás descuidando el caso muy común de múltiples ramas. Ver la respuesta de Charles.
Matt Fenwick
2
Útil, sin embargo, debe venir con una advertencia.
Simon Bengtsson
55
Esto realmente funciona. La respuesta aceptada no. Ver comentario
gman
3

No puedes Entonces:

rm -rf .git/
git init
git add -A
git commit -m 'Your new commit message'
ma11hew28
fuente
1
Trató de decir git reset --hard, entonces ¿por qué lo haría git add -A?
Aristóteles Pagaltzis
3

Lanzaré lo que funcionó para mí al final. Necesitaba eliminar la confirmación inicial en un repositorio ya que los datos en cuarentena se habían extraviado, la confirmación ya se había enviado.

Asegúrese de estar actualmente en la rama correcta.

git checkout master

git update-ref -d HEAD

git commit -m "Initial commit

git push -u origin master

Esto fue capaz de resolver el problema.

Importante

Esto estaba en un repositorio interno que no era de acceso público, si su repositorio era de acceso público, suponga que cualquier cosa que necesite revertir ya ha sido eliminada por otra persona.

Eduardo
fuente
1

Me pregunto por qué "enmendar" no es una sugerencia y ha sido tachado por @damkrat, ya que enmendar me parece la forma correcta de resolver de la manera más eficiente el problema subyacente de arreglar el compromiso incorrecto, ya que no existe el propósito de no tener una inicial cometer. Como algunos destacaron, solo debe modificar la rama "pública" como maestra si nadie ha clonado su repositorio ...

git add <your different stuff>
git commit --amend --author="author name <[email protected]>"-m "new message"
Ricardo
fuente
- el autor solo se requiere si alguien corrige la autoría del compromiso
Richard
0

git reset: realiza cambios duros, luego haz

git add -A
git commit --amend --no-edit 

o

git add -A
git commit --amend -m "commit_message"

y entonces

git push origin master --force

--force reescribirá esa confirmación a la que se ha restablecido en el primer paso.

No hagas esto, porque estás a punto de ir en contra de la idea de los sistemas VCS y git en particular. El único buen método es crear una nueva rama y eliminar ramas innecesarias. Ver git help branchpara más información.

Damkrat
fuente
-1

Todo lo que tienes que hacer es revertir la confirmación.

git revert {commit_id}'

Entonces empujalo

git push origin -f
abdallah Nofal
fuente
No es posible hacer eso a la primera confirmación.
Usuario que no es usuario