force - git push-u origin master
Forzar "git push" para sobrescribir archivos remotos (4)
Quiero enviar mis archivos locales y tenerlos en un repositorio remoto, sin tener que lidiar con conflictos de combinación. Solo quiero que mi versión local tenga prioridad sobre la remota.
¿Cómo puedo hacer esto con Git?
Quieres forzar empuje
Lo que básicamente quieres hacer es forzar el empuje de tu 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 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 de respuestas largas a continuación.
Advertencia: la fuerza de inserción sobrescribirá la rama remota con el estado de la rama que está presionando. Asegúrese de que esto es lo que realmente desea hacer antes de usarlo; de lo contrario, puede sobrescribir los compromisos que realmente desea mantener.
Fuerza empujando detalles
Especificando el remoto y la rama
Puede especificar completamente ramas específicas y un 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 se omite la rama para empujar la rama, Git lo resolverá en función de sus ajustes de configuración. En las versiones de Git posteriores a 2.0, un nuevo repositorio tendrá configuraciones predeterminadas para impulsar la rama actualmente retirada:
git push <remote> --force
mientras que antes de 2.0, los nuevos repos tendrán configuraciones predeterminadas para impulsar múltiples sucursales locales. Los ajustes en cuestión son el remote.<remote>.push
y push.default
settings (ver más abajo).
Omitiendo el mando a distancia y la rama.
Cuando se omiten tanto el control remoto como la rama, el comportamiento de solo git push --force
está determinado por la configuración de configuración de push.default
Git:
git push --force
A partir de Git 2.0, la configuración predeterminada,
simple
, básicamente solo empujará su sucursal actual a su contraparte remota ascendente. El control remoto está determinado por la ramificación de labranch.<remote>.remote
setting, y predeterminado al repositorio de origen.Antes de la versión 2.0 de Git, la configuración predeterminada, la
matching
, básicamente solo empuja todas las sucursales locales a sucursales con el mismo nombre en el control remoto (que de forma predeterminada es origen).
Puede leer más configuraciones push.default
leyendo git help config
o una versión en línea de la página de manual de git-config (1) .
Forzar el empuje de forma más segura con - --force-with-lease
Forzar empujando con un "arrendamiento" permite que el empuje forzoso falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha encontrado en su rama de seguimiento remoto), lo cual es útil si no quiere sobrescribir accidentalmente las confirmaciones de otra persona que ni siquiera sabía, y solo quiere sobrescribir las suyas propias:
git push <remote> <branch> --force-with-lease
Puede aprender más detalles sobre cómo usar --force-with-lease
leyendo cualquiera de los siguientes:
Debería poder forzar su revisión local al repositorio remoto usando
git push -f <remote> <branch>
(por ejemplo, git push -f origin master
). Si se deja desactivado <remote>
y <branch>
se forzará el empuje de todas las ramas locales que han establecido --set-upstream
.
Solo tenga cuidado, si otras personas comparten este repositorio, su historial de revisiones entrará en conflicto con el nuevo. Y si tienen algún compromiso local después del punto de cambio, se volverán inválidos.
Actualización : Pensé que añadiría una nota al margen. Si está creando cambios que otros revisarán, entonces no es infrecuente crear una rama con esos cambios y reajustarlos periódicamente para mantenerlos actualizados con la rama de desarrollo principal. Solo deja que otros desarrolladores sepan que esto sucederá periódicamente para que sepan qué esperar.
Actualización 2 : Debido al número cada vez mayor de espectadores, me gustaría agregar información adicional sobre qué hacer cuando la upstream
experimente un impulso de fuerza.
Digamos que he clonado tu repo y he añadido algunos comentarios como:
D----E topic / A----B----C development
Pero más tarde, la rama de development
se ve afectada por una rebase
, lo que provocará que reciba un error como cuando ejecuto 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 solucionar los conflictos y commit
, pero eso me dejaría con un historial de cometer realmente feo:
C----D----E----F topic / / A----B--------------C'' development
Puede parecer atractivo utilizar git pull --force
pero tenga cuidado porque eso lo dejará con compromisos desamparados:
D----E topic A----B----C'' development
Así que probablemente la mejor opción es hacer un git pull --rebase
. Esto requerirá que resuelva cualquier conflicto como antes, pero para cada paso, en lugar de cometer, 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", como lo mencionó Cupcake en su respuesta :
Forzar empujando con un "arrendamiento" permite que el empuje forzoso falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha encontrado en su rama de seguimiento remoto), lo cual es útil si no quiere sobrescribir accidentalmente las confirmaciones de otra persona que ni siquiera sabía, y solo quiere sobrescribir las suyas propias:
git push <remote> <branch> --force-with-lease
Puede aprender más detalles sobre cómo usar
--force-with-lease
leyendo cualquiera de los siguientes:
Otra opción (para evitar cualquier empuje forzado que pueda ser problemático para otros contribuyentes) es:
- Pon tus nuevos compromisos en una rama dedicada.
- reinicia tu
master
enorigin/master
- fusione su rama dedicada para
master
, manteniendo siempre los compromisos de la rama dedicada (lo que significa crear nuevas revisiones en la parte superior delmaster
que reflejará su rama dedicada).
Consulte el " comando git para hacer una rama como otra " para conocer las estrategias para simular unagit merge --strategy=theirs
.
De esa manera, puedes empujar el maestro a remoto sin tener que forzar nada.
git push -f es un poco destructivo porque restablece los cambios remotos que haya hecho cualquier otra persona en el equipo. Una opción más segura es {git push --force-with-lease}.
Lo que {--force-with-lease} hace es negarse a actualizar una sucursal a menos que sea el estado que esperamos; Es decir, nadie ha actualizado la rama aguas arriba. En la práctica, esto funciona al verificar que la referencia ascendente es lo que esperamos, porque las referencias son hashes e codifican implícitamente la cadena de padres en su valor. Puede decirle a {--force-with-lease} exactamente qué buscar, pero por defecto verificará la referencia remota actual. Lo que esto significa en la práctica es que cuando Alice actualiza su rama y la empuja hacia el repositorio remoto, se actualizará el jefe de referencia de la rama. Ahora, a menos que Bob haga un tirón desde el control remoto, su referencia local al control remoto estará desactualizada. Cuando va a empujar usando {--force-with-lease}, git verificará la referencia local contra el nuevo control remoto y se negará a forzar el empuje. {--force-with-lease} efectivamente solo te permite forzar y empujar si nadie más ha introducido cambios en el control remoto mientras tanto. Está {--force} con el cinturón de seguridad puesto.