Forzar "git push" para sobrescribir archivos remotos
768
Quiero insertar 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.
No está claro si solo desea anular los archivos .git o la copia de trabajo asociada. Si es el repositorio de git, git push es la respuesta. Si desea actualizar la copia de trabajo remota, debe usar un gancho posterior a la recepción
Pierre-Olivier Vares
@ Mike que me funciona por alguna razón ... es de extrañar lo que estaba pasando con el OP
Una causa probable, el empuje forzado no funciona, es que puede haberse desactivado explícitamente en el repositorio remoto (para garantizar que nada se pierda debido a contribuyentes idiotas y / o malignos): utilícelo config receive.denyNonFastforwardspara averiguarlo.
Frank Nocke
Respuestas:
1088
Debería poder forzar su revisión local al repositorio remoto utilizando
git push -f <remote> <branch>
(por ejemplo git push -f origin master) Dejando <remote>y <branch>forzará empujar todas las ramas locales que se han establecido --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 compromisos locales después del punto de cambio, serán invalidados.
Actualización : pensé que agregaría una nota al margen. Si está creando cambios que otros revisarán, entonces no es raro crear una rama con esos cambios y volver a redactar 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 upstreamexperimentas un impulso forzado.
Digamos que he clonado su repositorio y he agregado algunas confirmaciones como esta:
D ---- E tema
/ /
A ---- B ---- C desarrollo
Pero más tarde, la developmentrama se golpea con un rebase, lo que hará que reciba un error así cuando ejecuto git pull:
Desembalaje de objetos: 100% (3/3), hecho.
De <repo-location>
* desarrollo de sucursal -> FETCH_HEAD
Auto-fusión <archivos>
CONFLICTO (contenido): fusionar conflicto en <ubicaciones>
La fusión automática falló; arregle conflictos y luego confirme el resultado.
Aquí podría solucionar los conflictos y commit, pero eso me dejaría con un historial de cometer realmente feo:
C ---- D ---- E ---- F tema
/ /
A ---- B -------------- C 'desarrollo
Puede parecer atractivo de usar, git pull --forcepero ten cuidado porque eso te dejará con compromisos varados:
D ---- E tema
A ---- B ---- C 'desarrollo
Entonces, 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 comprometerlo lo usaré git rebase --continue. Al final, el historial de confirmación se verá mucho mejor:
El empuje forzado con un "arrendamiento" permite que el empuje forzado falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha traído a su rama de seguimiento remoto), lo cual es útil si no desea sobrescribir accidentalmente los compromisos de otra persona que aún no conocía, y solo desea sobrescribir los suyos:
git push <remote> <branch> --force-with-lease
Puede obtener más detalles sobre cómo usar --force-with-leaseleyendo cualquiera de los siguientes:
Como esta es la respuesta seleccionada, comentaré aquí. Usar la fuerza no es un problema cuando trabajas solo. Por ejemplo, mi host en la nube comienza con su propio git. Si trabajo localmente y construyo un proyecto, y quiero ponerlo en mi host en la nube (OpenShift), tengo dos proyectos git separados. Mi local y mi OpenShift uno. Recibo mi local tal como me gusta, pero ahora quiero obtener una vista previa en mi OpenShift. Luego empujas a OpenShift por primera vez, usando la -fbandera. Básicamente, coloca tu git local en OpenShift.
Wade
128
Quieres forzar empujar
Lo que básicamente quieres hacer es forzar el empuje de tu rama local para sobrescribir la remota.
Si desea una explicación más detallada de cada uno de los siguientes comandos, consulte mi sección de detalles a continuación. Básicamente tiene 4 opciones diferentes para forzar el empuje con Git:
Si desea una explicación más detallada de cada comando, consulte mi sección de respuestas largas a continuación.
Advertencia: el empuje forzado sobrescribirá la rama remota con el estado de la rama que está presionando. Asegúrese de que esto es lo que realmente quiere hacer antes de usarlo, de lo contrario, puede sobrescribir las confirmaciones que realmente desea mantener.
Forzar detalles de empuje
Especificar el control remoto y la rama
Puede especificar completamente ramas específicas y un control remoto. La -fbandera es la versión corta de--force
Cuando se omite la bifurcación a la bifurcación, Git la resolverá según la configuración de configuración. En las versiones de Git posteriores a 2.0, un nuevo repositorio tendrá una configuración predeterminada para impulsar la rama actualmente desprotegida:
git push <remote> --force
mientras que antes de 2.0, los nuevos repositorios tendrían 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).
Omitiendo el control remoto y la rama
Cuando se omiten tanto el control remoto como la rama, el comportamiento de solo git push --forceestá determinado por la push.defaultconfiguración de configuración de Git:
git push --force
A partir de Git 2.0, la configuración predeterminada, simplebásicamente empujará su rama actual a su contraparte remota ascendente. El control remoto está determinado por la branch.<remote>.remoteconfiguración de la sucursal y, de lo contrario, el repositorio de origen es el predeterminado.
Antes de Git versión 2.0, la configuración predeterminada matching, básicamente, empuja todas sus sucursales locales a sucursales con el mismo nombre en el control remoto (que por defecto es el origen).
Fuerza a empujar de manera más segura con --force-with-lease
El empuje forzado con un "arrendamiento" permite que el empuje forzado falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha traído a su rama de seguimiento remoto), lo cual es útil si no desea sobrescribir accidentalmente los compromisos de otra persona que aún no conocía, y solo desea sobrescribir los suyos:
git push <remote> <branch> --force-with-lease
Puede obtener más detalles sobre cómo usar --force-with-leaseleyendo cualquiera de los siguientes:
Tienes razón, pero esto solo debería usarse en situaciones excepcionales .
Scott Berrevoets
1
@ScottBerrevoets " Preferiría presionar lo que tengo y dejar que se sobrescriba de forma remota en lugar de integrarse " . Le di al OP exactamente lo que me pidió.
Lo sé, pero OP puede no ser consciente de las consecuencias de hacer esto. Técnicamente respondiste la pregunta, pero creo que una advertencia para no hacer esto no está fuera de lugar.
Scott Berrevoets
1
@ScottBerrevoets Estoy tratando de que un moderador combine mi respuesta en el canónico, porque menciono la nueva --force-with-leaseopción;)
Otra opción (para evitar cualquier empuje forzado que pueda ser problemático para otros contribuyentes) es:
ponga sus nuevos commits en una rama dedicada
restablecer masterelorigin/master
combine su rama dedicada master, manteniendo siempre los compromisos de la rama dedicada (lo que significa crear nuevas revisiones además de las mastercuales reflejarán su rama dedicada).
Ver " comando git para hacer una rama como otra " para estrategias para simular a git merge --strategy=theirs.
De esa manera, puede empujar el maestro al control remoto sin tener que forzar nada.
@alexkovelsky Cualquier impulso forzado reescribiría el historial, lo que obligaría a otros usuarios del repositorio a restablecer su propio repositorio local para que coincida con las confirmaciones recientemente enviadas. Este enfoque solo crea nuevas confirmaciones y no requiere un impulso forzado.
VonC
1
Sugiero que agregue un encabezado a su respuesta: "No desea forzar el empuje" :)
alexkovelsky
@alexkovelsky Buen punto. He editado la respuesta en consecuencia.
VonC
4
git push -f es un poco destructivo porque restablece cualquier cambio remoto que haya realizado cualquier otra persona en el equipo. Una opción más segura es {git push --force-with-lease}.
Lo que hace {--force-with-lease} 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 comprobando que la referencia ascendente es lo que esperamos, porque las referencias son hashes y codifican implícitamente la cadena de padres en su valor. Puede decirle a {--force-with-lease} exactamente qué verificar, pero de forma predeterminada 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, el cabezal de referencia de la rama se actualizará. Ahora, a menos que Bob haga una extracció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 le permite forzar-empujar si nadie más ha empujado los cambios al control remoto mientras tanto. Es {--force} con el cinturón de seguridad puesto.
git push origin --force
te funcionó?config receive.denyNonFastforwards
para averiguarlo.Respuestas:
Debería poder forzar su revisión local al repositorio remoto utilizando
(por ejemplo
git push -f origin master
) Dejando<remote>
y<branch>
forzará empujar todas las ramas locales que se han establecido--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 compromisos locales después del punto de cambio, serán invalidados.
Actualización : pensé que agregaría una nota al margen. Si está creando cambios que otros revisarán, entonces no es raro crear una rama con esos cambios y volver a redactar 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
upstream
experimentas un impulso forzado.Digamos que he clonado su repositorio y he agregado algunas confirmaciones como esta:
Pero más tarde, la
development
rama se golpea con unrebase
, lo que hará que reciba un error así cuando ejecutogit pull
:Aquí podría solucionar los conflictos y
commit
, pero eso me dejaría con un historial de cometer realmente feo:Puede parecer atractivo de usar,
git pull --force
pero ten cuidado porque eso te dejará con compromisos varados:Entonces, 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 comprometerlo lo usarégit rebase --continue
. Al final, el historial de confirmación se verá mucho mejor:Actualización 3: También puede usar la
--force-with-lease
opción como un impulso de fuerza "más seguro", como lo menciona Cupcake en su respuesta :fuente
-f
bandera. Básicamente, coloca tu git local en OpenShift.Quieres forzar empujar
Lo que básicamente quieres hacer es forzar el empuje de tu rama local para sobrescribir la remota.
Si desea una explicación más detallada de cada uno de los siguientes comandos, consulte mi sección de detalles a continuación. Básicamente tiene 4 opciones diferentes para forzar el empuje con Git:
Si desea una explicación más detallada de cada comando, consulte mi sección de respuestas largas a continuación.
Advertencia: el empuje forzado sobrescribirá la rama remota con el estado de la rama que está presionando. Asegúrese de que esto es lo que realmente quiere hacer antes de usarlo, de lo contrario, puede sobrescribir las confirmaciones que realmente desea mantener.
Forzar detalles de empuje
Especificar el control remoto y la rama
Puede especificar completamente ramas específicas y un control remoto. La
-f
bandera es la versión corta de--force
Omitiendo la rama
Cuando se omite la bifurcación a la bifurcación, Git la resolverá según la configuración de configuración. En las versiones de Git posteriores a 2.0, un nuevo repositorio tendrá una configuración predeterminada para impulsar la rama actualmente desprotegida:
mientras que antes de 2.0, los nuevos repositorios tendrían configuraciones predeterminadas para impulsar múltiples sucursales locales. Las configuraciones en cuestión son las configuraciones
remote.<remote>.push
ypush.default
(ver más abajo).Omitiendo el control remoto y la rama
Cuando se omiten tanto el control remoto como la rama, el comportamiento de solo
git push --force
está determinado por lapush.default
configuración de configuración de Git:A partir de Git 2.0, la configuración predeterminada,
simple
básicamente empujará su rama actual a su contraparte remota ascendente. El control remoto está determinado por labranch.<remote>.remote
configuración de la sucursal y, de lo contrario, el repositorio de origen es el predeterminado.Antes de Git versión 2.0, la configuración predeterminada
matching
, básicamente, empuja todas sus sucursales locales a sucursales con el mismo nombre en el control remoto (que por defecto es el origen).Puede leer más
push.default
configuraciones leyendogit help config
o una versión en línea de la página de manual de git-config (1) .Fuerza a empujar de manera más segura con
--force-with-lease
El empuje forzado con un "arrendamiento" permite que el empuje forzado falle si hay nuevas confirmaciones en el control remoto que no esperaba (técnicamente, si aún no las ha traído a su rama de seguimiento remoto), lo cual es útil si no desea sobrescribir accidentalmente los compromisos de otra persona que aún no conocía, y solo desea sobrescribir los suyos:
Puede obtener más detalles sobre cómo usar
--force-with-lease
leyendo cualquiera de los siguientes:git push
documentaciónfuente
--force-with-lease
opción;)
Otra opción (para evitar cualquier empuje forzado que pueda ser problemático para otros contribuyentes) es:
master
elorigin/master
master
, manteniendo siempre los compromisos de la rama dedicada (lo que significa crear nuevas revisiones además de lasmaster
cuales reflejarán su rama dedicada).Ver " comando git para hacer una rama como otra " para estrategias para simular a
git merge --strategy=theirs
.De esa manera, puede empujar el maestro al control remoto sin tener que forzar nada.
fuente
git push -f es un poco destructivo porque restablece cualquier cambio remoto que haya realizado cualquier otra persona en el equipo. Una opción más segura es {git push --force-with-lease}.
Lo que hace {--force-with-lease} 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 comprobando que la referencia ascendente es lo que esperamos, porque las referencias son hashes y codifican implícitamente la cadena de padres en su valor. Puede decirle a {--force-with-lease} exactamente qué verificar, pero de forma predeterminada 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, el cabezal de referencia de la rama se actualizará. Ahora, a menos que Bob haga una extracció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 le permite forzar-empujar si nadie más ha empujado los cambios al control remoto mientras tanto. Es {--force} con el cinturón de seguridad puesto.
fuente
Funciona para mi:
fuente
Pasos simples usando tortoisegit
GIT asigna archivos locales y se compromete con el repositorio de git.
Pasos:
1) el alijo cambia el nombre del alijo
2) tirar
3) stash pop
4) confirme 1 o más archivos y proporcione la descripción de los cambios de confirmación del autor del conjunto y la fecha
5) empujar
fuente