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. Sólo quiero que mi versión local tenga prioridad sobre la remota.
¿Cómo puedo hacer esto con Git?
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 upstream
un empujón forzado.
Digamos que cloné su repositorio y agregué algunas confirmaciones como esta:
D----E tema / A----B----C desarrollo
Pero luego la development
rama 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-lease
opció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-lease
leyendo cualquiera de los siguientes:
git push
documentación- Git: ¿Cómo ignorar el avance rápido y revertir el origen [rama] a una confirmación anterior?
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 -f
bandera 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>.push
y 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 --force
está determinado por la push.default
configuración de Git:
git push --force
A partir de Git 2.0, la configuración predeterminada,
simple
básicamente, simplemente enviará su rama actual a su contraparte remota ascendente. El control remoto está determinado por la configuración de la sucursalbranch.<remote>.remote
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, 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.default
configuraciones leyendo git help config
o 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-lease
leyendo cualquiera de los siguientes:
git push
documentación- Git: ¿Cómo ignorar el avance rápido y revertir el origen [rama] a una confirmación anterior?
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
master
encendidoorigin/master
- fusione su rama dedicada
master
, manteniendo siempre las confirmaciones de la rama dedicada (lo que significa crear nuevas revisiones además de lasmaster
cuales reflejarán su rama dedicada).
Consulte " comando git para hacer una rama como otra " para conocer estrategias para simular un archivogit merge --strategy=theirs
.
De esa manera, puedes pasar el maestro al control remoto sin tener que forzar nada.
Funciona para mi:
git push --set-upstream <remote> <branch> -f
git push -f
es 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-lease
hace 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-lease
exactamente 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-lease
efectivamente solo le permite forzar el envío si nadie más ha enviado los cambios al control remoto mientras tanto. Es --force
con el cinturón de seguridad puesto.