Cuando trabajé un poco con mi código fuente, hice mi compromiso habitual y luego ingresé a un repositorio remoto. Pero luego noté que olvidé organizar mis importaciones en el código fuente. Entonces hago el comando de modificación para reemplazar el commit anterior:
> git commit --amend
Lamentablemente, la confirmación no se puede devolver al repositorio. Se rechaza así:
> git push origin
To //my.remote.repo.com/stuff.git/
! [rejected] master -> master (non-fast forward)
error: failed to push some refs to '//my.remote.repo.com/stuff.git/'
¿Qué tengo que hacer? (Puedo acceder al repositorio remoto).
git
git-commit
amend
Spoike
fuente
fuente
git push -force
más cuidado .Respuestas:
En realidad, una vez empujó con
--force
y.git
repositorio y regañaron por Linus BIG TIME . En general, esto creará muchos problemas para otras personas. Una respuesta simple es "No lo hagas".Veo que otros dieron la receta para hacerlo de todos modos, así que no los repetiré aquí. Pero aquí hay un consejo para recuperarse de la situación después de haber eliminado la confirmación modificada con --force (o + master).
git reflog
para encontrar el compromiso anterior que modificó (llámeloold
, y llamaremos al nuevo compromiso que creó modificandonew
).old
ynew
, registrando el árbol denew
, comogit checkout new && git merge -s ours old
.git merge master
git push . HEAD:master
Entonces las personas que tenían la desgracia de haber basado su trabajo en el commit que obliterado por la que se modifica y forzando un empuje verá la fusión resultante verá que usted a favor de
new
másold
. Sus fusiones posteriores no verán los conflictos entreold
ynew
que resultaron de su modificación, por lo que no tienen que sufrir.fuente
git reflog
para encontrarloEstás viendo una característica de seguridad de Git. Git se niega a actualizar la rama remota con su rama, porque la confirmación principal de su rama no es un descendiente directo de la confirmación principal actual de la rama a la que está presionando.
Si este no fuera el caso, entonces dos personas que presionan al mismo repositorio aproximadamente al mismo tiempo no sabrían que hay una nueva confirmación entrando al mismo tiempo y el que presionó al último perdería el trabajo del empujador anterior sin ninguno de los dos. ellos dándose cuenta de esto.
Si sabe que usted es la única persona que presiona y desea presionar una confirmación modificada o una confirmación que revierte la rama, puede 'forzar' a Git a actualizar la rama remota mediante el
-f
interruptor.Incluso esto puede no funcionar ya que Git permite que los repositorios remotos rechacen los empujes no rápidos en el extremo utilizando la variable de configuración
receive.denynonfastforwards
. Si este es el caso, el motivo de rechazo se verá así (tenga en cuenta la parte 'remoto rechazado'):Para evitar esto, debe cambiar la configuración del repositorio remoto o, como un truco sucio, puede eliminar y volver a crear la rama de esta manera:
En general, el último parámetro
git push
utiliza el formato<local_ref>:<remote_ref>
, dondelocal_ref
es el nombre de la rama en el repositorio local yremote_ref
es el nombre de la rama en el repositorio remoto. Este par de comandos usa dos shorthands.:master
tiene un local_ref nulo, lo que significa empujar una rama nula hacia el lado remotomaster
, es decir, eliminar la rama remota. Un nombre de rama sin ningún:
medio empuja la rama local con el nombre dado a la rama remota con el mismo nombre.master
en esta situación es la abreviatura demaster:master
.fuente
git gc
vez que los reflogs hayan expirado, se eliminarán los objetos viejos. Nadie que clone el repositorio obtendrá objetos a los que ya no se pueda acceder tan pronto como se haya actualizado la rama.Discurso rápido: el hecho de que nadie haya publicado la respuesta simple aquí demuestra la desesperada hostilidad del usuario exhibida por la CLI de Git.
De todos modos, la forma "obvia" de hacer esto, suponiendo que no haya intentado forzar el empuje, es tirar primero. Esto tira del cambio que modificó (y ya no tiene) para que lo tenga nuevamente.
Una vez que haya resuelto cualquier conflicto, puede presionar nuevamente.
Entonces:
Si obtiene errores en la extracción, tal vez algo está mal en la configuración de su repositorio local (tuve una referencia incorrecta en la sección de la rama .git / config).
Y después
Tal vez obtendrá un compromiso adicional con el tema que habla sobre una "fusión trivial".
fuente
git push -f
ogit reset
es la única forma de ir aquí.Respuesta corta: no empuje los compromisos modificados a un repositorio público.
Respuesta larga: algunos comandos de Git, como
git commit --amend
ygit rebase
, en realidad reescriben el gráfico del historial. Esto está bien siempre y cuando no haya publicado sus cambios, pero una vez que lo haga, realmente no debería estar revisando el historial, porque si alguien ya recibió sus cambios, entonces cuando intenten volver a hacerlo, podría fallar . En lugar de enmendar una confirmación, debe hacer una nueva confirmación con los cambios.Sin embargo, si realmente desea impulsar una confirmación modificada, puede hacerlo así:
El
+
signo inicial obligará a que se produzca el impulso, incluso si no resulta en una confirmación de "avance rápido". (Una confirmación de avance rápido ocurre cuando los cambios que está presionando son un descendiente directo de los cambios que ya están en el repositorio público).fuente
git push -f
.Aquí hay una manera muy simple y limpia de impulsar sus cambios después de que ya haya realizado un
commit --amend
:Que hace lo siguiente:
Recuerde cambiar "origen" y "maestro" si aplica esto a una rama o control remoto diferente.
fuente
git add
antes de mi confirmación para incluir los cambios.git reset --soft "HEAD^"
. El resto funciona bien.Lo resolví descartando mi confirmación local modificada y agregando los nuevos cambios en la parte superior:
fuente
Yo tuve el mismo problema.
Como Git-novato, pensé que era completo FUBAR .
Solución: algo así como @bara sugirió + creó una rama de respaldo local
Tal vez no sea una solución rápida y limpia, y perdí mi historial (1 commit en lugar de 5), pero salvó un día de trabajo.
fuente
Si no ha insertado el código en su rama remota (GitHub / Bitbucket), puede cambiar el mensaje de confirmación en la línea de comando como se muestra a continuación.
Si está trabajando en una rama específica, haga esto:
Si ya ha introducido el código con un mensaje incorrecto, debe tener cuidado al cambiar el mensaje. es decir, después de cambiar el mensaje de confirmación e intentar presionarlo nuevamente, terminará teniendo problemas. Para suavizarlo, siga los siguientes pasos.
Lea la respuesta completa antes de hacerlo.
Nota importante: cuando usa el empuje de fuerza directamente, puede terminar con problemas de código que otros desarrolladores están trabajando en la misma rama. Entonces, para evitar esos conflictos, debe extraer el código de su rama antes de hacer que la fuerza empuje :
Esta es la mejor práctica al cambiar el mensaje de confirmación, si ya se envió.
fuente
--force
, vea la respuesta aceptadaSi sabe que nadie ha retirado su confirmación no modificada, use la
--force-with-lease
opción degit push
.En TortoiseGit, puede hacer lo mismo en las opciones "Empujar ..." "Forzar: puede descartar" y marcar "cambios conocidos".
fuente
Obtiene este error porque el control remoto de Git ya tiene estos archivos de confirmación. Tienes que forzar a empujar la rama para que esto funcione:
También asegúrese de extraer el código del control remoto ya que otra persona de su equipo podría haber pasado a la misma rama.
Este es uno de los casos en los que tenemos que forzar el envío de la confirmación al control remoto.
fuente
Aquí hay una manera muy simple y limpia de impulsar sus cambios después de que ya haya realizado un
git add "your files"
ygit commit --amend
:o:
fuente
Si está utilizando Visual Studio Code, puede probar esta extensión para que sea más fácil.
https://marketplace.visualstudio.com/items?itemName=cimdalli.git-commit-amend-push-force
Como puedes entender por su nombre, ejecuta comandos consecutivamente
git commit --amend
git push --force
fuente
Tuve que solucionar este problema al extraer del repositorio remoto y lidiar con los conflictos de fusión que surgieron, cometer y luego presionar. Pero siento que hay una mejor manera.
fuente
Seguí haciendo lo que Git me dijo que hiciera. Entonces:
Nota: La confirmación modificada fue la última.
fuente
Lo siguiente funcionó para mí cuando cambié el Autor y el Comprador de una confirmación.
git push -f origin master
Git fue lo suficientemente inteligente como para darse cuenta de que se trataba de confirmaciones de deltas idénticas que solo diferían en la sección de metainformación.
Tanto los jefes locales como los remotos señalaron los compromisos en cuestión.
fuente
Aquí, cómo arreglé una edición en una confirmación anterior:
git stash
ahora su copia de trabajo está limpia en el estado de su última confirmación.git commit --all --amend
Su editor aparecerá pidiendo un mensaje de registro (por defecto, el mensaje de registro anterior). Guarde y salga del editor cuando esté satisfecho con él.
Los nuevos cambios se agregan al antiguo commit. Compruébelo usted mismo con
git log
ygit diff HEAD^
Vuelva a aplicar sus cambios escondidos, si se hicieron:
git stash apply
fuente