OK, yo pensaba que esto era una simple git escenario, ¿qué me estoy perdiendo?

Tengo un master rama y un feature rama. Tengo que hacer algún trabajo en master, algunos en feature y, a continuación, algunos más en master. Termino con algo como esto (lexicográfica del pedido implica la orden de commits):

A--B--C------F--G  (master)
       \    
        D--E  (feature)

Yo no tengo ningún problema para git push origin master para mantener el control remoto master actualizados, ni con git push origin feature (cuando en feature) para mantener una copia de seguridad remota para mi feature trabajo. Hasta ahora, estamos bien.

Pero ahora quiero rebase feature en la parte superior de la F--G se compromete en el maestro, así que me git checkout feature y git rebase master. Sigue siendo buena. Ahora tenemos:

A--B--C------F--G  (master)
                 \
                  D'--E'  (feature)

Problema: el momento quiero copia de seguridad de la nueva rebasada feature ramificada con git push origin feature, el empuje es rechazado desde el árbol ha cambiado debido al reajuste. Este problema sólo puede resolverse con git push --force origin feature.

Odio utilizando --force sin estar seguro de que lo necesito. Así, lo necesito? ¿El reajuste necesariamente implica que el próximo push debe ser --forceful?

Esta rama de la característica no está compartida con otros desarrolladores, así que no tengo problema de facto con el empuje de fuerza, no voy a perder los datos, la pregunta es más bien conceptual.

InformationsquelleAutor Yuval Adam | 2012-01-20

11 Comentarios

  1. 564

    El problema es que git push se supone que la rama remota puede ser remitido a su sucursal local, que es que toda la diferencia entre lo local y remoto de las ramas es en el local para tener un poco de nuevo se compromete al final como que:

    Z--X--R         <- origin/some-branch (can be fast-forwarded to Y commit)
           \        
            T--Y    <- some-branch
    

    Al realizar git rebase comete D y E se aplican a la nueva base y los nuevos commits son creados. Eso significa que después de reajuste usted tiene algo así como que:

    A--B--C------F--G--D'--E'   <- feature-branch
           \  
            D--E                <- origin/feature-branch
    

    En que la situación de la rama remota no puede ser reenviado a los locales. Aunque, en teoría, la rama local se pueden combinar en remoto (obviamente, usted no la necesita en ese caso), pero como git push realiza en avance rápido fusiona lanza y el error.

    Y lo --force opción es simplemente ignorar el estado de la rama remota y configuración para confirmar que usted está empujando dentro de ella. Así git push --force origin feature-branch simplemente reemplaza origin/feature-branch con local feature-branch.

    En mi opinión, reajuste la característica de ramas en master y de la fuerza empujando de nuevo a un repositorio remoto está bien siempre y cuando usted es el único que funciona en esa rama.

    • Para ser honesto, tirando y la fusión de la versión original de la rama de característica en la pasa uno un poco elimina toda idea de reajuste.
    • Tal vez yo no he entendido correctamente, pero si se tira de rama, de reajuste en fresco, la rama principal, no se puede empujar sin fuerza, porque remoto versión de la rama de característica no puede ser enviado a su nuevo (reajustado) versión de la rama de característica. Eso es exactamente lo OP que describe en su pregunta. Si después del reajuste, pero antes de empujar, hacer git pull feature-branch, esta fuerza va a generar una nueva combinación de commit (por la fusión de local y remota de las versiones de la rama de característica). Así que ya sea que usted obtiene una innecesaria de mezcla después del reajuste, o empujar con --force.
    • Ah, yo creo que lo tengo. Estás describiendo el mismo enfoque que en Marcos Longair la respuesta. Pero sí genera una combinación de cometer. Puede ser útil en algunos casos, pero yo uso rebase sobre todo en mi propia característica de las ramas (de ahí push --force no es un problema), para mantener la cometa de la historia lineal sin ningún tipo de mezcla compromete a todos.
    • Esto también va a mostrar, la idea completa con un DVCS es que nunca empuje en la misma rama. Tire de los cambios que otros han hecho, que nunca debe ser enviado a usted. Usted sólo pulsar para evitar los firewalls (y para fines de copia de seguridad), por lo que la empujó a la rama debe sólo es el reflejo de su trabajo, no ser la autoridad de la rama. En mi humilde opinión, la fuerza de empuje debe ser el predeterminado, pero supongo que mucha gente está empujando en la misma rama para que a un final feliz. 🙂
    • El problema con la «fuerza de empuje», que se puede, de hecho, «las cosas» (antes de la cometa), algo que normalmente NUNCA debe ser posible en cualquier Sistema de Control de versiones ➪ Por esa razón, en menos de una «master-ish» rama debe tener la configuración de no aceptar la fuerza empuja, para limitar los posibles daños. (Nombre de cualquiera de los siguientes: gruñón/despidió a los empleados, propia idiotez, cansado&exceso de trabajo ‘decisiones’… ).
    • Pensé que esto iba a solucionar mi problema, que parece similar, sin embargo: $ git push --force origin myBranch devuelve «Todo lo que hasta la fecha» y seguido inmediatamente por git checkout myBranch da el mismo «cambiado a la rama ‘ingresar’ a Su rama está por delante de ‘el origen/característica/ingresar’ por 34 comete.«
    • --force-with-lease como @hardev sugerido es una gran opción
    • Por favor, tenga en cuenta que --force-with-lease es mucho más seguro que --force, y es la cosa correcta a hacer en este escenario.
    • «git push origin +my_branch» también ayudará.

  2. 336

    Lugar de usar -f o –la fuerza de los desarrolladores deben utilizar

    --force-with-lease
    

    ¿Por qué? Porque comprueba la rama remota para los cambios que es absolutamente una buena idea. Imaginemos que James y Lisa están trabajando en la misma rama de característica y Lisa ha empujado a un commit. James ahora reajusta su sucursal local y es rechazado cuando tratando de empujar. Por supuesto James piensa que esto es debido a reajuste y usos de la fuerza y la iba a volver a escribir todas Lisa cambios. Si James tenía utiliza la opción –force-con-el contrato de arrendamiento se hubiera recibido una advertencia de que no se comete el hecho por alguien más. No veo por qué alguien haría uso de la opción –force en lugar de –force-con-contrato de arrendamiento cuando se empuja después de un reajuste.

    • Gran explicación. git push --force-with-lease me ha ahorrado un montón.
    • Este es un comentario útil, pero no es realmente una respuesta a la pregunta.
    • Esta es la respuesta, reajuste a maestro/a desarrollar crea un problema, esto es exactamente por qué –force-con-contrato de arrendamiento existe.
    • Esto debe ser aceptado respuesta. Resuelve exactamente el problema descrito – fuerza de empuje sin forzar si alguien comprometido en el ínterin.
    • Creo que tanto la aceptación de la respuesta y esta la dirección de la pregunta. El aceptó respuesta explica por qué usted necesita a la fuerza. Y esto explica por qué --force-with-lease responde a la preocupación de la utilización de --force
  3. 41

    Que me gustaría utilizar en su lugar «checkout-b», y es más fácil de entender.

    git checkout myFeature
    git rebase master
    git push origin --delete myFeature
    git push origin myFeature
    

    al eliminar a evitar empujar en una salida de la rama que contiene diferentes SHA ID.
    Estoy borrando la rama remota en este caso.

    • Esto funciona muy bien, especialmente si su equipo tiene un git gancho que rechaza toda git push –fuerza de comandos.
    • gracias por que funcionaba bien. Aquí hay más detalles sobre los que he leído para entender mejor. Esto es muy útil cuando no se desea o no puede hacer una fuerza de empuje. Eliminar Ramas Remotas y Reajuste
    • Esto tiene el mismo resultado como push --force, por lo que es sólo una manera de conseguir alrededor de un repositorio git prevención de --force. Como tal, no creo que esto es siempre una buena idea – la repo permite push --force, o por una buena razón es que la desactiva. Nabi la respuesta es más apropiado si --force está deshabilitado en el mando a distancia repo, ya que no tiene el riesgo de perder las confirmaciones de otros desarrolladores o causando problemas.
  4. 19

    Una solución a esto es hacer lo que msysGit del reajuste de mezcla script no – después del reajuste, de mezcla en el antiguo jefe de feature con -s ours. Se termina con la confirmación gráfico:

    A--B--C------F--G (master)
           \         \
            \         D'--E' (feature)
             \           /
              \       --
               \    /
                D--E (old-feature)
    

    … y el empuje de feature será un avance rápido.

    En otras palabras, usted puede hacer:

    git checkout feature
    git branch old-feature
    git rebase master
    git merge -s ours old-feature
    git push origin feature
    

    (No probado, pero creo que es lo correcto…)

    • Creo que la razón más común para el uso de git rebase (en lugar de la fusión de master de nuevo en su rama) es hacer limpia lineal comete la historia. Con su enfoque comete la historia se pone aún peor. Y como reajuste crea un nuevo cometa, sin referencia alguna a sus versiones anteriores, yo no estoy seguro de que el resultado de esta fusión será la adecuada.
    • El punto entero de la merge -s ours es que artificialmente se añade un padre referencia a la versión anterior. Seguro, la historia no tenga un aspecto limpio, pero el interrogador parece ser particularmente molesto por tener que forzar el empuje de la feature rama, y esto se pone alrededor de eso. Si desea reajustar, es más o menos uno o el otro. 🙂 Más en general, creo que es interesante que la msysgit proyecto hace esto….
    • Por cierto, he +1ed su respuesta, que es claramente la de la derecha – pensé que podría ser interesante también.
    • Definitivamente es muy interesante, al menos para mí. Gracias. He visto ours estrategia de antes, pero pensaba que sólo se aplica a la situación de conflicto de forma automática la resolución mediante cambios en nuestra rama. Resultó que funciona de forma diferente. Y trabajando de ese modo es muy útil si usted necesita rebasada la versión (por ejemplo, para repo mantenedor para aplicar de forma limpia a master), pero quieren evitar la fuerza de empuje (si montón de otras ppl, por alguna razón, está utilizando su rama).
  5. 15

    Puede o no puede ser el caso de que sólo hay un desarrollador de esta rama, que es ahora (después de que el rebase) no en línea con el origen o característica.

    Como tal, me gustaría sugerir a utilizar la siguiente secuencia:

    git rebase master
    git checkout -b feature_branch_2
    git push origin feature_branch_2
    

    Sí, nueva rama, esto debería solucionar esto sin la opción –force, que creo que en general es una de las principales git inconveniente.

    • Lo siento decir pero: «Mantener la generación de ramas» para evitar que la fuerza primordial existentes no ayuda «lonely característica de los desarrolladores» (que se puede reemplazar) o múltiples personas que trabajan en una rama de característica (la necesidad de comunicar que la rama de «incremento» y decirle a moverse, la gente). — Es más como manual de control de versiones («thesis_00.doc, thesis_01.doc, …»), dentro de un sistema de control de versiones…
    • Además, esto no ayuda cuando tienes un github PR abiertos en un nombre de la sucursal, tendrías que crear un nuevo PR para el nuevo nombre de la sucursal que le empujó.
    • La mitad de la verdad de mi experiencia. para un solo desarrollador, sí, sólo la fuerza de empuje es bastante fácil, pero es el hábito que podría morder más tarde. + un nuevo dev unido? o tal vez algún sistema de CI que no está usando –hard reset? para un equipo de colaboradores, creo comunicar el nuevo nombre de la sucursal es bastante fácil, esto puede ser fácilmente el guión como bien + para un equipo, yo sugeriría que se reajuste local o cuando la rama está listo para la mezcla, no durante el trabajo del día a día, el extra cometer es menos de un problema de tratar con reajuste/conflictos como resultado.
    • para PR, de nuevo, creo que esto sería un error de reajuste, me gustaría realmente desea ver el único compromete con el PR correcciones. Un rebase (calabaza) que debería ocurrir sólo más tarde como parte de la combinación de maestro y cuando el PR está todo hecho y listo (así que no hay de PR tiene que ser abierto).
  6. 12

    Otros han respondido a su pregunta. Si usted rebase de una rama que se necesita fuerza para empujar esa rama.

    De reajuste y un repositorio compartido generalmente no se llevan bien. Esta es la reescritura de la historia. Si los demás están usando esa rama o han ramificado a partir de esa rama, a continuación, reajuste será bastante desagradable.

    En general, de reajuste funciona bien para la sucursal local de gestión. De la rama remota de gestión que funciona mejor con explícita fusiones (–no-ff).

    También evitar la fusión de maestro en una rama de la característica. En lugar de eso nos rebase maestro, pero con un nuevo nombre de la sucursal (e.g la adición de un sufijo de versión). Esto evita el problema de reajuste en el repositorio compartido.

    • Puede agregar un ejemplo, por favor ?
  7. 11

    Mi manera de evitar que la fuerza de empuje es crear una nueva rama y continuo trabajo en el que la nueva rama y después de un poco de estabilidad, quitar la antigua rama que fue rebasada:

    • De reajuste comprobado la sucursal local
    • De la ramificación de la reajustado rama a una nueva rama
    • Empujando esa rama como una nueva rama a control remoto. y la eliminación de la antigua rama remota
    • Por qué no hay amor por esta opción? Es sin duda el más limpio, más sencillo, más seguro.
    • Porque tengo cerca de 200 sistemas de seguimiento el nombre de la sucursal y tiene que ser un nombre específico para la tarea, y si me pongo a hacer rama cambia el nombre a cada empujón me la voy a perder mi mente.
    • Yo no lo he probado, pero no la eliminación de la antigua rama (remoto) antes de empujar y empujar la nueva sucursal con la misma edad de nombre a resolver su problema?
    • Eso es exactamente lo que –force-con-el contrato de arrendamiento no, excepto que también se verifica que no hay nuevos commits que no son suyas.
  8. 8

    Lo que está mal con un git merge master en el feature rama? Esto para conservar el trabajo que tenía, mientras que lo mantiene separado de la línea principal de la sucursal.

    A--B--C------F--G
           \         \
            D--E------H
    

    Edición: Ah lo siento no leer su declaración del problema. Usted tendrá fuerza a medida que se realiza un rebase. Todos los comandos que modifican la historia tendrá la --force argumento. Esta es una prueba de fallas para evitar la pérdida de trabajo (el antiguo D y E se perdería).

    Así que se realizó una git rebase que hizo que el árbol parece (aunque parcialmente oculto como D y E ya no en nombre de la rama):

    A--B--C------F--G
           \         \
            D--E      D'--E'
    

    Así, cuando tratando de empujar a su nuevo feature rama (con D' y E' en ella), perdería D y E.

    • No hay nada malo con eso, y sé que el trabajo. Simplemente no lo necesito. Como he dicho, la cuestión es más conceptual que práctica.
    • Lo siento, véase mi edición de una respuesta.
  9. 4

    La siguiente me funciona:

    git push -f origin branch_name

    y no quita nada de mi código.

    Pero, si quieres evitar esto, entonces usted puede hacer lo siguiente:

    git checkout master
    git pull --rebase
    git checkout -b new_branch_name
    

    entonces usted puede cherry-pick todos sus envíos a la nueva rama.
    git cherry-pick COMMIT ID
    y, a continuación, empuje su nueva sucursal.

    • -f es un alias para --force, que es lo que la pregunta está tratando de evitar, si es posible.
    • Gracias @PresidentEvil he actualizado mi respuesta.
  10. 2

    Para mí siguientes pasos obras:

    1. git checkout myFeature
    2. git rebase master
    3. git push --force-with-lease
    4. git branch -f master HEAD
    5. git checkout master
    6. git pull
    

    Después de hacer todo lo anterior, podemos eliminar myFeature rama así por el comando siguiente:

    git push origin --delete myFeature
    
  11. 1

    Como el OP no entender el problema, solo busca una mejor solución…

    ¿Qué tal esto como una práctica ?

    • Tienen en función de real-desarrollar rama (donde nunca rebase y de la fuerza de empuje, para que sus compañeros la característica de que los desarrolladores no los odio). Aquí, regularmente agarrar los cambios de principal con una combinación. Messier historia, sí, pero la vida es fácil y nadie consigue es interrumpido en su trabajo.

    • Tener una segunda característica-desarrollar rama, donde uno función de miembro del equipo regularmente empuja a todos los de la característica se compromete a que, de hecho pasa, de hecho forzada. Por lo que casi de manera limpia basada en una bastante reciente maestro de cometer. En función completa, push que se ramifican en la parte superior de la maestra.

    Podría ser un patrón de nombre para este método ya.

Dejar respuesta

Please enter your comment!
Please enter your name here