Pregunta

Cuando trabajé un poco con mi código fuente, hice lo habitual y luego lo envié a un repositorio remoto.Pero luego me di cuenta de que olvidé organizar mis importaciones en el código fuente.Entonces hago el comando de modificación para reemplazar la confirmación 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).

¿Fue útil?

Solución

De hecho, una vez presioné con --force y .git repositorio y Linus lo regañó GRAN TIEMPO.En general, esto creará muchos problemas para otras personas.Una respuesta sencilla es "No lo hagas".

Veo que otros dieron la receta para hacerlo de todos modos, así que no las repetiré aquí.Pero aquí tienes un consejo para recuperarte de la situación. después ha eliminado la confirmación modificada con --force (o +master).

  1. Usar git reflog para encontrar el antiguo compromiso que modificaste (llámalo old, y llamaremos al nuevo compromiso que creaste modificando new).
  2. Crear una fusión entre old y new, registrando el árbol de new, como git checkout new && git merge -s ours old.
  3. Fusiona eso con tu maestro con git merge master
  4. Actualiza tu master con el resultado con git push . HEAD:master
  5. Saque el resultado.

Luego, las personas que tuvieron la mala suerte de basar su trabajo en el compromiso que usted borró modificando y forzando un envío verán la fusión resultante y verán 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.

Otros consejos

Estás viendo una función 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 presionen al mismo repositorio aproximadamente al mismo tiempo no sabrían que se está realizando una nueva confirmación al mismo tiempo y que quien presionó por última vez perdería el trabajo del impulsor anterior sin que ninguno de ellos se dé 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 utilizando el interruptor -f.

git push -f origin master

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 'rechazado remoto'):

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

Para evitar esto, debe cambiar la configuración del repositorio remoto o, como un truco sucio, puede eliminar y volver a crear la rama así:

git push origin :master
git push origin master

En general, el último parámetro para git push usa el formato <local_ref>:<remote_ref>, donde local_ref es el nombre de la rama en el repositorio local y remote_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 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:master en esta situación es la abreviatura de <=>.

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, el " obvio " La forma de hacerlo, suponiendo que no haya intentado forzar el empuje, es tirar primero. Esto extrae el cambio que modificó (y ya no tiene) para que lo tenga nuevamente.

Una vez que haya resuelto cualquier conflicto, puede presionar nuevamente.

Entonces:

git pull

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

git push

Tal vez obtendrá una confirmación adicional con el sujeto que informa sobre una " Fusión trivial " ;.

Respuesta corta:No envíe confirmaciones modificadas a un repositorio público.

Respuesta larga:Algunos comandos de Git, como git commit --amend y git rebase, En realidad, reescribe el gráfico histórico.Esto está bien siempre y cuando no hayas publicado tus cambios, pero una vez que lo hagas, no deberías estar trasteando con el historial, porque si alguien ya recibió tus cambios, cuando intente extraerlos nuevamente, podría fallar. .En lugar de modificar una confirmación, simplemente debería realizar una nueva confirmación con los cambios.

Sin embargo, si realmente desea impulsar una confirmación modificada, puede hacerlo de esta manera:

$ git push origin +master:master

El líder + sign forzará que se produzca el envío, incluso si no da como resultado un compromiso de "avance rápido".(Una confirmación de avance rápido ocurre cuando los cambios que está impulsando son un descendiente directo de los cambios que ya están en el repositorio público.)

Aquí hay una manera muy simple y limpia de impulsar sus cambios después de que ya haya realizado un 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 encabezado de rama a confirmación principal.
  • Guarde esta última confirmación.
  • Forzar el empuje al control remoto. El control remoto ahora no tiene la última confirmación.
  • Abre tu escondite.
  • Comprometerse limpiamente.
  • Presione al control remoto.

Recuerde cambiar " origin " y " maestro " si aplica esto a una sucursal o control remoto diferente.

Lo resolví descartando mi confirmación local modificada 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

Tuve el mismo problema.

  • Modificó accidentalmente el último commit que ya fue empujado
  • Hice muchos cambios a nivel local, cometió unas cinco veces
  • Intenté empujar, recibí un error, entró en pánico, fusionó el control remoto, recibí muchos archivos que no son mis, empujé, fallé, etc.

Como Git-novato, pensé que estaba completo FUBAR .

Solución: algo así como @bara sugirió + creó una rama de respaldo 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 commit en lugar de 5), pero me salvó el trabajo de un día.

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.

 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 presionó 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

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 usa el empuje de fuerza directamente, puede terminar con problemas de código que otros desarrolladores están trabajando en la misma rama. Por lo tanto, para evitar esos conflictos, debe extraer el código de su sucursal antes de hacer el empuje forzado :

 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ó.

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

En TortoiseGit, puede hacer lo mismo en " Push ... " opciones " Fuerza: puede descartar " y marcando " cambios conocidos " ;.

  

Force (puede descartar cambios conocidos) permite el repositorio remoto para aceptar un empuje más seguro sin avance rápido. Esto puede hacer que el repositorio remoto pierda confirmaciones; úsalo con cuidado. Esto puede evitar perder 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 forzado. De lo contrario, será rechazado. Dado que git no tiene etiquetas de seguimiento remoto, las etiquetas no se pueden sobrescribir con esta opción.

Aquí hay una manera muy simple y limpia de impulsar sus cambios después de haber realizado un git add "your files" y git commit --amend:

git push origin master -f

o:

git push origin master --force

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:

git push -f origin branch_name

También asegúrese de extraer el código del control remoto ya que alguien más de su equipo podría haber pasado a la misma rama.

git pull origin branch_name

Este es uno de los casos en los que tenemos que forzar el envío de la confirmación al control remoto.

Tuve que solucionar este problema al extraer del repositorio remoto y tratar los conflictos de fusión que surgieron, cometer y luego presionar. Pero siento que hay una mejor manera.

Seguí haciendo lo que Git me dijo que hiciera. Entonces:

  • No se puede presionar debido a la confirmación modificada.
  • Hago un tirón como se sugiere.
  • La fusión falla. así que lo arreglo manualmente.
  • Crear una nueva confirmación (etiquetada " fusionar ") y empujarlo.
  • Parece que funciona!

Nota: La confirmación modificada fue la última.

Aquí, cómo solucioné una edición en una confirmación anterior:

  1. Guarde su trabajo hasta ahora.
  2. Guarde los cambios por ahora si los realiza: git stash Ahora su copia de trabajo está limpia en el estado de su última confirmación.
  3. Realice las ediciones y correcciones.
  4. Confirmar los cambios en "enmendar" modo: git commit --all --amend
  5. Su editor aparecerá solicitando un mensaje de registro (de forma predeterminada, el mensaje de registro anterior).Guarde y salga del editor cuando esté satisfecho con él.

    Los nuevos cambios se agregan a la confirmación anterior.Compruébalo tú mismo con git log y git diff HEAD^

  6. Vuelva a aplicar los cambios ocultos, si los realizó: git stash apply

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top