Pregunta ¿Cómo envío el compromiso modificado al repositorio remoto de Git?


Cuando trabajé un poco con mi código fuente, hice mi commit usual y luego fui a un repositorio remoto. Pero luego noté que olvidé organizar mis importaciones en el código fuente. Así que hago el comando de modificación para reemplazar la confirmación anterior:

> git commit --amend

Lamentablemente, la confirmación no puede ser devuelta 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/'

¿Que debería hacer? (Puedo acceder al repositorio remoto).


525
2017-10-31 10:23


origen


Respuestas:


De hecho, una vez empujé con --force y .git repositorio y fue regañado por Linus GRAN TIEMPO. 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 has expulsado la confirmación modificada con --force (o + master).

  1. Encuentra el compromiso anterior que enmendó (llámalo old, y llamaremos al nuevo commit que creaste al enmendar new)
  2. Crea una fusión entre old y new, grabando el árbol de new, me gusta git checkout new && git merge -s ours old.
  3. Combina eso con tu maestro con git merge master
  4. Actualice su maestro con el resultado con git push . HEAD:master
  5. Empuje el resultado.

Luego las personas que tuvieron la mala suerte de haber basado su trabajo en el compromiso que borraron al enmendar y forzar un empuje (que es estás siendo un chico muy muy malo) verá que la fusión resultante verá que usted está a favor new encima old. Sus fusiones posteriores no verán los conflictos entre old y new que resultó de su enmienda, para que no tengan que sufrir.


409
2018-01-11 07:36



Está viendo una característica de seguridad de Git. Git se niega a actualizar la bifurcación remota con su bifurcación, porque la confirmación de la bifurcación de su bifurcación no es un descendiente directo de la confirmación del jefe actual de la bifurcación que usted está presionando.

Si este no fuera el caso, entonces dos personas empujando hacia el mismo repositorio aproximadamente al mismo tiempo no sabrían que había un nuevo compromiso entrando al mismo tiempo y quien empujó último perdería el trabajo del empujador anterior sin ninguno de los dos. ellos dándose cuenta de esto.

Si sabes que eres la única persona que está presionando y quieres presionar una confirmación modificada o presionar una confirmación que haga retroceder la rama, puedes 'forzar' a Git a actualizar la rama remota usando el -f cambiar.

git push -f origin master

Incluso esto puede no funcionar, ya que Git permite que los repositorios remotos rechacen las ejecuciones no rápidas al final usando la variable de configuración receive.denynonfastforwards. Si este es el caso, el motivo de rechazo será similar a este (tenga en cuenta la parte 'rechazada remotamente'):

 ! [remote rejected] master -> master (non-fast forward)

Para evitar esto, o necesita cambiar la configuración del repositorio remoto o como un hack sucio puede eliminar y volver a crear la rama de esta manera:

git push origin :master
git push origin master

En general, el último parámetro para git push usa el formato <local_ref>:<remote_ref>, dónde local_ref es el nombre de la sucursal en el repositorio local y remote_ref es el nombre de la sucursal en el repositorio remoto. Este par de comando usa dos shorthands. :mastertiene un local_ref nulo que significa empujar una rama nula al lado remoto master, es decir, eliminar la rama remota. Un nombre de rama sin : significa empujar la rama local con el nombre dado a la rama remota con el mismo nombre. master en esta situación es la abreviatura de master:master.


239
2017-10-31 21:58



Demonios rápidos: el hecho de que nadie haya publicado la respuesta simple aquí demuestra la desesperada hostilidad del usuario exhibida por Git CLI.

De todos modos, la forma "obvia" de hacer esto, suponiendo que no has intentado forzar el impulso, es tirar primero. Esto extrae el cambio que enmendó (y que ya no tiene) para que lo tenga de nuevo.

Una vez que haya resuelto cualquier conflicto, puede volver a presionar.

Asi que:

git pull

Si obtiene errores en la extracción, tal vez algo esté mal en su configuración de repositorio local (tuve una referencia incorrecta en la sección de la rama .git / config).

Y después

git push

Tal vez obtendrás un compromiso extra con el sujeto contando sobre una "fusión trivial".


191
2017-10-31 14:35



Respuesta corta: no inserte confirmaciones modificadas en un repositorio público.

Respuesta larga: algunos comandos de Git, como git commit --amend y git rebase, en realidad reescribe el gráfico de historial. Esto está bien siempre y cuando no hayas publicado los cambios, pero una vez que lo haces, realmente no deberías estar rebuscando con el historial, porque si alguien ya obtuvo tus cambios, entonces cuando intenten tirar nuevamente, podría fallar . En lugar de modificar una confirmación, solo debe hacer una nueva confirmación con los cambios.

Sin embargo, si realmente desea insertar una confirmación modificada, puede hacerlo así:

$ git push origin +master:master

El líder + sign forzará la inserción, incluso si no da como resultado una confirmación de "avance rápido". (Una confirmación de avance rápido ocurre cuando los cambios que está presionando son descendiente directo de los cambios que ya están en el repositorio público).


90
2018-06-21 14:41



Aquí hay una manera muy simple y limpia de impulsar sus cambios después de que ya haya hecho una commit --amend:

git reset --soft HEAD^
git stash
git push -f origin master
git stash pop
git commit -a
git push origin master

Que hace lo siguiente:

  • Restablecer el encabezado de la rama a la confirmación principal.
  • Stash este último compromiso.
  • Fuerza empujar al control remoto. El control remoto ahora no tiene el último compromiso.
  • Pop su escondite.
  • Comprométase limpiamente
  • Empujar a control remoto.

Recuerde cambiar "origen" y "maestro" si aplica esto a una rama o control remoto diferente.


36
2017-09-24 15:46



Lo he resuelto descartando mi compromiso modificado local y agregando los nuevos cambios en la parte superior:

# Rewind to commit before conflicting
git reset --soft HEAD~1

# Pull the remote version
git pull

# Add the new commit on top
git add ...
git commit
git push

21
2018-02-20 10:24



Yo tuve el mismo problema.

  • Enmendado accidentalmente el último compromiso que ya fue empujado
  • Realicé muchos cambios localmente, comprometidos unas cinco veces
  • Intenté presionar, recibí un error, entré en pánico, me fusioné con el control remoto, obtuve muchos archivos que no eran de mi, empujados, fallidos, etc.

Como un Git-newbie, pensé que estaba completo FUBAR.

Solución: algo así como @bara sugirió + creó una rama de copia de seguridad local

# Rewind to commit just before the pushed-and-amended one.
# Replace <hash> with the needed hash.
# --soft means: leave all the changes there, so nothing is lost.
git reset --soft <hash>

# Create new branch, just for a backup, still having all changes in it.
# The branch was feature/1234, new one - feature/1234-gone-bad
git checkout -b feature/1234-gone-bad

# Commit all the changes (all the mess) not to lose it & not to carry around
git commit -a -m "feature/1234 backup"

# Switch back to the original branch
git checkout feature/1234

# Pull the from remote (named 'origin'), thus 'repairing' our main problem
git pull origin/feature/1234

# Now you have a clean-and-non-diverged branch and a backup of the local changes.
# Check the needed files from the backup branch
git checkout feature/1234-gone-bad -- the/path/to/file.php

Tal vez no sea una solución rápida y limpia, y perdí mi historial (1 compromiso en lugar de 5), pero me ahorró un día de trabajo.


7
2018-06-07 00:03



Si sabe que nadie ha retirado su confirmación sin enmendar, use la --force-with-lease opción de git push.

En TortoiseGit, puede hacer lo mismo en las opciones "Empujar ..." "Forzar: puede descartar" y verificar "cambios conocidos".

Fuerza (puede descartar cambios conocidos) permite que el repositorio remoto acepte un envío más seguro no rápido. Esto puede causar que el repositorio remoto pierda commits; Úselo con cuidado. Esto puede evitar la pérdida de cambios desconocidos de otras personas en el control remoto. Comprueba si la rama del servidor apunta a la misma confirmación que la rama de seguimiento remoto (cambios conocidos). En caso afirmativo, se realizará un empuje de fuerza. De lo contrario, será rechazado. Dado que git no tiene etiquetas de seguimiento remoto, las etiquetas no se pueden sobrescribir utilizando esta opción.


4
2018-01-18 08:29



Aquí hay una manera muy simple y limpia de impulsar sus cambios después de que ya haya hecho una git add "your files" y git commit --amend:

git push origin master -f

o:

git push origin master --force

2
2018-01-13 07:20



Si no ha insertado el código en su sucursal remota (GitHub / Bitbucket) puede cambiar el mensaje de confirmación en la línea de comando como se muestra a continuación.

 git commit --amend -m "Your new message"

Si está trabajando en una rama específica, haga esto:

git commit --amend -m "BRANCH-NAME: new message"

Si ya ha insertado 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 volver a presionarlo, terminará teniendo problemas. Para hacerlo sin problemas, siga los siguientes pasos.

Por favor, lea la respuesta completa antes de hacerlo

git commit --amend -m "BRANCH-NAME : your new message"

git push -f origin BRANCH-NAME                # Not a best practice. Read below why?

Nota IMPORTANTE: Cuando utiliza la fuerza directamente puede terminar con problemas de código que otros desarrolladores están trabajando en la misma rama. Para evitar esos conflictos, debe extraer el código de su sucursal antes de hacer el fuerza empujar:

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

Esta es la mejor práctica al cambiar el mensaje de confirmación, si ya se envió.


2
2018-01-21 06:35