Forzar "git push" para sobrescribir archivos remotos

Resuelto opensas asked hace 12 años • 6 respuestas

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

¿Cómo puedo hacer esto con Git?

opensas avatar May 09 '12 12:05 opensas
Aceptado

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

git push -f <remote> <branch>

(p.ej git push -f origin master). Dejando fuera <remote>y <branch>forzaremos el empuje de todas las sucursales locales que tengamos establecidas --set-upstream.

Solo tenga en cuenta que si otras personas comparten este repositorio, su historial de revisiones entrará en conflicto con el nuevo. Y si tienen confirmaciones locales después del punto de cambio, dejarán de ser válidas.

Actualización : pensé en agregar una nota al margen. Si está creando cambios que otros revisarán, no es raro crear una rama con esos cambios y cambiar la base periódicamente para mantenerlos actualizados con la rama de desarrollo principal. Simplemente informe 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 experimentas upstreamun empujón forzado.

Digamos que cloné su repositorio y agregué algunas confirmaciones como esta:

            D----E tema
           /
A----B----C desarrollo

Pero luego la developmentrama recibe un rebase, lo que hará que reciba un error como este cuando ejecuto git pull:

Desembalaje de objetos: 100% (3/3), hecho.
Desde <ubicación-repositorio>
 * desarrollo de sucursales -> FETCH_HEAD
Fusión automática de <archivos>
CONFLICTO (contenido): fusionar conflictos en <ubicaciones>
La fusión automática falló; solucionar conflictos y luego confirmar el resultado.

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

       C----D----E----F tema
      / /
A----B--------------C' desarrollo

Puede parecer atractivo de usar git pull --force, pero ten cuidado porque eso te dejará con confirmaciones varadas:

            D----E tema

A----B----C' desarrollo

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

            D'---E' tema
           /
A----B----C' desarrollo

Actualización 3: También puedes usar la --force-with-leaseopción como un empujón forzado "más seguro", como lo menciona Cupcake en su respuesta :

Forzar el envío con un "arrendamiento" permite que el envío forzado falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha recuperado en su rama de seguimiento remoto), lo cual es útil si no deseas sobrescribir accidentalmente las confirmaciones de otra persona que ni siquiera conocías todavía, y solo deseas sobrescribir las tuyas propias:

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

Puede obtener más detalles sobre cómo usarlo --force-with-leaseleyendo cualquiera de los siguientes:

  • git pushdocumentación
  • Git: ¿Cómo ignorar el avance rápido y revertir el origen [rama] a una confirmación anterior?
Trevor Norris avatar May 09 '2012 05:05 Trevor Norris

Quieres forzar el empujón

Básicamente, lo que desea hacer es forzar el envío de su sucursal local para sobrescribir la remota.

Si desea una explicación más detallada de cada uno de los siguientes comandos, consulte la sección de detalles a continuación. Básicamente tienes 4 opciones diferentes para forzar el push 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 mi sección de respuestas largas a continuación.

Advertencia: forzar el envío sobrescribirá la rama remota con el estado de la rama que estás enviando. Asegúrese de que esto es lo que realmente desea hacer antes de usarlo; de lo contrario, puede sobrescribir las confirmaciones que realmente desea conservar.

Forzar detalles de empuje

Especificación del control remoto y la sucursal

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

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

Omitiendo la rama

Cuando se omite la rama, Git lo resolverá según su configuración. En las versiones de Git posteriores a la 2.0, un nuevo repositorio tendrá configuraciones predeterminadas para enviar la rama actualmente desprotegida:

git push <remote> --force

mientras que antes de 2.0, los nuevos repositorios tendrán configuraciones predeterminadas para impulsar múltiples sucursales locales. Las configuraciones en cuestión son las configuraciones remote.<remote>.pushy push.default(ver más abajo).

Omitir el control remoto y la sucursal

Cuando se omiten tanto el control remoto como la rama, el comportamiento de just git push --forceestá determinado por la push.defaultconfiguración de Git:

git push --force
  • A partir de Git 2.0, la configuración predeterminada, simplebásicamente, simplemente enviará su rama actual a su contraparte remota ascendente. El control remoto está determinado por la configuración de la sucursal branch.<remote>.remotey, de lo contrario, el valor predeterminado es el repositorio de origen.

  • Antes de la versión 2.0 de Git, la configuración predeterminada, matchingbásicamente, simplemente empuja todas sus ramas locales a ramas con el mismo nombre en el control remoto (que por defecto es origen).

Puede leer más push.defaultconfiguraciones leyendo git help configo una versión en línea de la página del manual de git-config(1) .

Fuerce el empuje de manera más segura con--force-with-lease

Forzar el envío con un "arrendamiento" permite que el envío forzado falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha recuperado en su rama de seguimiento remoto), lo cual es útil si no deseas sobrescribir accidentalmente las confirmaciones de otra persona que ni siquiera conocías todavía, y solo deseas sobrescribir las tuyas propias:

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

Puede obtener más detalles sobre cómo usarlo --force-with-leaseleyendo cualquiera de los siguientes:

  • git pushdocumentación
  • Git: ¿Cómo ignorar el avance rápido y revertir el origen [rama] a una confirmación anterior?
 avatar Jul 15 '2014 21:07

Otra opción (para evitar cualquier presión forzada que pueda resultar problemática para otros contribuyentes) es:

  • coloque sus nuevos compromisos en una rama dedicada
  • reinicia tu masterencendidoorigin/master
  • fusione su rama dedicada master, manteniendo siempre las confirmaciones de la rama dedicada (lo que significa crear nuevas revisiones además de las mastercuales reflejarán su rama dedicada).
    Consulte " comando git para hacer una rama como otra " para conocer estrategias para simular un archivo git merge --strategy=theirs.

De esa manera, puedes pasar el maestro al control remoto sin tener que forzar nada.

VonC avatar May 09 '2012 06:05 VonC

Funciona para mi:

git push --set-upstream <remote> <branch> -f
Jithish P N avatar Jul 30 '2019 18:07 Jithish P N

git push -fes un poco destructivo porque restablece cualquier cambio remoto que haya realizado cualquier otra persona del equipo. Una opción más segura es

git push --force-with-lease

Lo que --force-with-leasehace es negarse a actualizar una rama a menos que esté en el estado que esperamos; es decir, nadie ha actualizado la rama en sentido ascendente. En la práctica, esto funciona verificando que la referencia ascendente sea la que esperamos, porque las referencias son hashes e implícitamente codifican la cadena de padres en su valor.

Puede saber --force-with-leaseexactamente qué buscar, pero de forma predeterminada 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 encabezado de referencia de la rama. Ahora, a menos que Bob extraiga el control remoto, su referencia local al control remoto estará desactualizada. Cuando vaya a empujar usando --force-with-lease, git comparará la referencia local con el nuevo control remoto y se negará a forzar el empuje. --force-with-leaseefectivamente solo le permite forzar el envío si nadie más ha enviado los cambios al control remoto mientras tanto. Es --forcecon el cinturón de seguridad puesto.

Lando Ke avatar Jul 05 '2017 11:07 Lando Ke