Forzar "git push" para sobrescribir archivos remotos


Quiero enviar mis archivos locales y tenerlos en un repositorio remoto, sin tener que lidiar con conflictos de fusión. Solo quiero que mi versión local tenga prioridad sobre la remota.

¿Cómo puedo hacer esto con Git?

 563
Author: opensas, 2012-05-09

4 answers

Debería poder forzar su revisión local al repositorio remoto usando

git push -f <remote> <branch>

(por ejemplo, git push -f origin master). Dejando off <remote> y <branch> forzará a empujar todas las ramas locales que han establecido --set-upstream.

Solo tenga cuidado, si otras personas están compartiendo este repositorio, su historial de revisiones entrará en conflicto con el nuevo. Y si tienen confirmaciones locales después del punto de cambio, se volverán inválidas.

Update : Pensé en añadir una nota al margen. Si usted es creando cambios que otros revisarán, entonces no es raro crear una rama con esos cambios y rebase periódicamente para mantenerlos actualizados con la rama de desarrollo principal. Solo haz saber a otros desarrolladores que esto sucederá periódicamente para que sepan qué esperar.

Actualización 2 : Debido al creciente número de espectadores, me gustaría agregar información adicional sobre qué hacer cuando su upstream experimenta un empuje de fuerza.

Di que he clonado tu repo y han añadido algunos commits como así:

            D----E  topic
           /
A----B----C         development

Pero más tarde la rama development se golpea con un rebase, lo que hará que reciba un error como este cuando corro git pull:

Unpacking objects: 100% (3/3), done.
From <repo-location>
 * branch            development     -> FETCH_HEAD
Auto-merging <files>
CONFLICT (content): Merge conflict in <locations>
Automatic merge failed; fix conflicts and then commit the result.

Aquí podría arreglar los conflictos y commit, pero eso me dejaría con un historial de commits realmente feo:

       C----D----E----F    topic
      /              /
A----B--------------C'  development

Puede parecer tentador usar git pull --force pero ten cuidado porque eso te dejará con commits varados:

            D----E   topic

A----B----C'         development

Así que probablemente la mejor opción es hacer un git pull --rebase. Este me requerirá resolver cualquier conflicto como antes, pero para cada paso en lugar de confirmar usaré git rebase --continue. Al final el historial de confirmaciones se verá mucho mejor:

            D'---E'  topic
           /
A----B----C'         development

Actualización 3: También puede usar la opción --force-with-lease como una fuerza "más segura" empuje, como se menciona por Cupcake en su respuesta:

El empuje de fuerza con un" lease " permite que el empuje de fuerza falle si hay son nuevas confirmaciones en el control remoto que no esperabas (técnicamente, si aún no de seguimiento remoto todavía), que es útil si no desea sobrescribir accidentalmente el de otra persona confirmaciones que ni siquiera sabías todavía, y solo quieres sobrescribir el suyo propio:

git push <remote> <branch> --force-with-lease

Puede obtener más información sobre cómo usar --force-with-lease leyendo cualquiera de lo siguiente:

 805
Author: Trevor Norris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:21

Quieres forzar el empuje

Lo que básicamente quieres hacer es forzar el push de tu rama local, con el fin de sobrescribir la remota.

Si desea una explicación más detallada de cada uno de los siguientes comandos, consulte la sección mis detalles a continuación. Básicamente tienes 4 opciones diferentes para forzar el empuje con Git:

git push <remote> <branch> -f
git push origin master -f # Example

git push <remote> -f
git push origin -f # Example

git push -f

git push <remote> <branch> --force-with-lease

Si desea una explicación más detallada de cada comando, consulte la sección mis respuestas largas a continuación.

Advertencia: fuerza empujar sobrescribirá la rama remota con el estado de la rama que estás empujando. Asegúrese de que esto es lo que realmente desea hacer antes de usarlo, de lo contrario puede sobrescribir las confirmaciones que realmente desea mantener.

Fuerza empujando detalles

Especificando el remoto y la rama

Puede especificar completamente ramas específicas y un control remoto. La bandera -f es la versión corta de --force

git push <remote> <branch> --force
git push <remote> <branch> -f

Omitiendo la rama

Cuando la rama a push branch se omite, Git lo averiguará en función de sus ajustes de configuración. En versiones Git después 2.0, un nuevo repo tendrá la configuración predeterminada para empujar la actualidad, check-out rama:

git push <remote> --force

Antes de la versión 2.0, los nuevos repositorios tendrán la configuración predeterminada para enviar varias ramas locales. Los ajustes en cuestión son los ajustes remote.<remote>.push y push.default (ver más abajo).

Omitiendo el remoto y la rama

Cuando se omiten tanto el remoto como la rama, el comportamiento de just git push --force está determinado por su push.default configuración de Git:

git push --force
  • A partir de Git 2.0, la configuración predeterminada, simple, básicamente solo empujará su rama actual a su contador remoto ascendente. El remoto está determinado por la configuración branch.<remote>.remote de la rama, y de lo contrario el valor predeterminado es el repositorio de origen.

  • Antes de la versión 2.0 de Git, la configuración predeterminada, matching, básicamente solo empuja todas tus ramas locales a ramas con el mismo nombre en el remoto (que el valor predeterminado es origin).

Puedes leer más configuraciones de push.default leyendo git help config o una versión en línea de la Página de Manual de git-config(1) .

Fuerza empujando de forma más segura con --force-with-lease

Force pushing con un "lease" permite que el force push falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha obtenido en su rama de seguimiento remoto), lo que es útil si no desea sobrescribir accidentalmente a alguien los commits de else que ni siquiera sabías todavía, y solo quieres sobrescribir los tuyos:

git push <remote> <branch> --force-with-lease

Puede obtener más detalles sobre cómo usar --force-with-lease leyendo cualquiera de los siguientes:

 102
Author: Community,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:31

Otra opción (para evitar cualquier empuje forzado que puede ser problemático para otros contribuyentes) es:

  • ponga sus nuevas confirmaciones en una rama dedicada
  • restablezca su master en origin/master
  • fusiona tu rama dedicada a master, manteniendo siempre las confirmaciones de la rama dedicada (lo que significa crear nuevas revisiones encima de master que reflejarán tu rama dedicada).
    Ver " git command for making one branch like another " para las estrategias para simular un git merge --strategy=theirs.

De esa manera, puede empujar master al control remoto sin tener que forzar nada.

 25
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 06:59:06

Git push-f es un poco destructivo porque restablece cualquier cambio remoto que haya sido realizado por cualquier otra persona en el equipo. Una opción más segura es {git push} force-with-lease}.

Lo que hace {force force-with-lease} es negarse a actualizar una rama a menos que sea el estado que esperamos; es decir, nadie ha actualizado la rama aguas arriba. En la práctica, esto funciona comprobando que la referencia de origen es lo que esperamos, porque las referencias son hashes, e implícitamente codifican la cadena de padres en su valor. Puedes dile a {force force-with-lease} exactamente qué comprobar, pero por defecto comprobará la referencia remota actual. Lo que esto significa en la práctica es que cuando Alice actualiza su rama y la envía al repositorio remoto, se actualizará el cabezal de referencia de la rama. Ahora, a menos que Bob haga una extracción desde el control remoto, su referencia local al control remoto estará desactualizada. Cuando vaya a push usando {force force-with-lease}, git comprobará la referencia local con el nuevo control remoto y se negará a forzar el push. {force force-with-lease} efectivamente solo le permite forzar el empuje si nadie más ha empujado los cambios hasta el control remoto en el ínterin. Es fuerza con el cinturón puesto.

 2
Author: Lando Ke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-05 11:32:34