theirs origin force git merge

origin - ¿Cuál es el significado preciso de "nuestro" y "de ellos" en git?



git merge--abort (5)

Del uso de git checkout :

-2, --ours checkout our version for unmerged files -3, --theirs checkout their version for unmerged files -m, --merge perform a 3-way merge with the new branch

Al resolver conflictos de fusión, puede hacer git checkout --theirs some_file , y git checkout --ours some_file para restablecer el archivo a la versión actual y las versiones entrantes respectivamente.

Si ha realizado el git checkout --ours some_file o el git checkout --theirs some_file y desea restablecer el archivo a la versión de combinación de 3 vías del archivo, puede hacer el git checkout --merge some_file .

Esto puede parecer una pregunta demasiado básica, pero he buscado respuestas y ahora estoy más confundido que antes.

¿Qué significa "nuestro" y "suyo" en git cuando se fusiona mi rama con la otra? Ambas ramas son "nuestras".

En un conflicto de fusión, ¿es "nuestro" siempre la parte superior de las dos versiones que se muestran?

¿El "nuestro" siempre se refiere a la rama a la que HEAD apuntaba cuando comenzó la fusión? Si es así, ¿por qué no usar una referencia posesiva clara como "rama actual" en lugar de usar un pronombre posesivo como "nuestro" que sea referencialmente ambiguo (dado que ambas ramas son técnicamente nuestras)?

¿O simplemente use el nombre de la sucursal (en lugar de decir "nuestro" solo diga "maestro local" o algo así)?

La parte más confusa para mí es si especifico en el archivo .gitattributes de una rama específica. Digamos que en la rama de prueba tengo el siguiente archivo .gitattributes:

config.xml merge=ours

Ahora pago y apunto HEAD para dominar y luego fusionar en la prueba . Como master es nuestro y los atributos .gitattributes de test no están desprotegidos, ¿tendrá algún efecto? Si tiene un efecto, ya que el maestro ahora es "nuestro", ¿qué pasará?


El " nuestro " en Git se refiere a la rama de trabajo original que tiene una parte autorizada / canónica de la historia de git.

El '' suyo '' se refiere a la versión que contiene el trabajo para volver a crear (cambios que se reproducirán en la rama actual).

Esto puede parecer intercambiado a personas que no son conscientes de que hacer rebase (por ejemplo, git rebase ) en realidad está poniendo su trabajo en espera (que es el suyo ) para poder reproducir la historia canónica / principal que es nuestra , porque estamos relanzar nuestros cambios como trabajo de terceros.

La documentación para git-checkout se aclaró más en Git> = 2.5.1 según f303016 commit :

--ours --theirs

Cuando revise las rutas desde el índice, revise la etapa # 2 (''la nuestra'') o # 3 (''la suya'') para las rutas no fusionadas.

Tenga en cuenta que durante git rebase y git pull --rebase , ''nuestro'' y ''suyo'' pueden aparecer intercambiados; --ours proporciona la versión de la rama en la que se vuelven a --theirs los cambios, mientras que --theirs le da la versión de la rama que contiene el trabajo que se está volviendo a crear.

Esto se debe a que rebase se usa en un flujo de trabajo que trata el historial en el control remoto como el canónico compartido, y trata el trabajo realizado en la rama que está reorganizando como el trabajo de terceros que se integrará, y usted asume temporalmente el rol del guardián de la historia canónica durante el rebase. Como el guardián de la historia canónica, debe ver la historia desde el control remoto como la ours (es decir, "nuestra historia canónica compartida"), mientras que lo que hizo en su lado se ramifica como la theirs (es decir, "el trabajo de un contribuyente encima" )

Para git-merge se explica de la siguiente manera:

la nuestra

Esta opción obliga a los trozos en conflicto a que se resuelvan automáticamente limpiamente al favorecer nuestra versión. Los cambios del otro árbol que no entran en conflicto con nuestro lado se reflejan en el resultado de la fusión. Para un archivo binario, todo el contenido se toma de nuestro lado.

Esto no debe confundirse con la estrategia de fusión nuestra, que ni siquiera mira lo que contiene el otro árbol. Descarta todo lo que hizo el otro árbol, declarando que nuestra historia contiene todo lo que sucedió en él.

suyo

Esto es lo opuesto al nuestro.

Además, aquí se explica cómo usarlos:

El mecanismo de fusión (comandos git merge y git pull ) permite elegir las estrategias de fusión de back-end con la opción -s . Algunas estrategias también pueden tomar sus propias opciones, que pueden pasarse dando argumentos -X<option> para git merge y / o git pull .

Entonces, a veces puede ser confuso, por ejemplo:

  • git pull origin master donde -Xours es nuestra -Xtheirs local, -Xtheirs es la suya (remota)
  • git pull origin master -r donde -Xours es suyo (remoto), -Xtheirs es nuestro

Entonces, el segundo ejemplo es opuesto al primero, porque estamos cambiando nuestra rama por encima de la remota, por lo que nuestro punto de partida es remoto y nuestros cambios se tratan como externos.

Similar para las estrategias de git merge ( -X ours y -X theirs ).


Sé que esto ha sido respondido, pero este problema me confundió tantas veces que he puesto un pequeño sitio web de referencia para ayudarme a recordar: https://nitaym.github.io/ourstheirs/

Aquí están los conceptos básicos:

Fusiones

$ git checkout master $ git merge feature

Si desea seleccionar la versión en master :

$ git checkout --ours codefile.js

Si desea seleccionar la versión en feature :

$ git checkout --theirs codefile.js

Rebases:

$ git checkout feature $ git rebase master

Si desea seleccionar la versión en master :

$ git checkout --ours codefile.js

Si desea seleccionar la versión en feature :

$ git checkout --theirs codefile.js

(Esto es para archivos completos, por supuesto)


Sospecho que estás confundido aquí porque es fundamentalmente confuso. Para empeorar las cosas, todo lo nuestro / lo suyo cambia de roles (se vuelve hacia atrás) cuando estás haciendo un rebase.

En última instancia, durante una git merge , la rama "nuestra" se refiere a la rama en la que se está fusionando:

git checkout merge-into-ours

y la rama "suya" se refiere a la rama (única) que está fusionando:

git merge from-theirs

y aquí "el nuestro" y "el suyo" tienen algún sentido, ya que aunque "el suyo" es probablemente tuyo de todos modos, "el suyo" no es el que estabas cuando ejecutaste git merge .

Si bien el uso del nombre real de la sucursal puede ser bastante bueno, se desmorona en casos más complejos. Por ejemplo, en lugar de lo anterior, puede hacer:

git checkout ours git merge 1234567

donde te estás fusionando por raw commit-ID. Peor aún, incluso puedes hacer esto:

git checkout 7777777 # detach HEAD git merge 1234567 # do a test merge

en cuyo caso no hay nombres de sucursal involucrados!

Creo que es de poca ayuda aquí, pero de hecho, en la sintaxis de gitrevisions , puede referirse a una ruta individual en el índice por número, durante una fusión en conflicto

git show :1:README git show :2:README git show :3:README

La etapa n. ° 1 es el antecesor común de los archivos, la etapa n. ° 2 es la versión de la rama de destino y la etapa n. ° 3 es la versión de la que se está fusionando.

La razón por la cual las nociones "nuestra" y "suyas" se intercambian durante el rebase es que el rebase funciona haciendo una serie de selecciones de cereza, en una rama anónima (modo HEAD separado). La rama de destino es la rama anónima, y ​​la rama de fusión es la rama original (previa al rebase): entonces "- nuestro" significa que el rebase anónimo se está construyendo mientras que "- el suyo" significa "nuestra rama está rebaseada" .

En cuanto a la entrada gitattributes: podría tener un efecto: "el nuestro" realmente significa "usar la etapa # 2" internamente. Pero como observa, en realidad no está en su lugar en ese momento, por lo que no debería tener un efecto aquí ... bueno, no a menos que lo copie en el árbol de trabajo antes de comenzar.

Además, por cierto, esto se aplica a todos los usos de los nuestros y los suyos, pero algunos están en un nivel de archivo completo ( -s ours para una estrategia de fusión; git checkout --ours durante un conflicto de fusión) y algunos están en una pieza- por pieza ( -X ours o -X theirs durante una fusión -s recursive ). Lo que probablemente no ayuda con nada de la confusión.

Sin embargo, nunca se me ocurrió un nombre mejor para estos. Y: ¡vea la respuesta de VonC a otra pregunta, donde git mergetool presenta aún más nombres para estos, llamándolos "local" y "remoto"!


  • La nuestra : esta es la sucursal en la que se encuentra actualmente.
  • La suya : esta es la otra rama que se utiliza en su acción.

Entonces, si está en la versión de sucursal / 2.5 y combina la función de sucursal / botones nuevos en él, entonces el contenido que se encuentra en la versión / 2.5 es a lo que se refiere el nuestro y el contenido que se encuentra en la función / botones nuevos es a lo que se refiere. a. Durante una acción de fusión, esto es bastante sencillo.

El único problema del que se enamora la mayoría de las personas es el caso de rebase . Si realiza una re-base en lugar de una fusión normal, los roles se intercambian. ¿Cómo es eso? Bueno, eso es causado únicamente por la forma en que funciona el rebase. Piensa en rebase para trabajar así:

  1. Todas las confirmaciones que ha realizado desde su último tirón se trasladan a una rama propia, nombremos BranchX .
  2. Comprueba el encabezado de su rama actual, descartando cualquier cambio local que haya tenido, pero de esa manera recupera todos los cambios que otros han empujado para esa rama.
  3. Ahora, cada commit en BranchX se selecciona de manera antigua a nueva en su rama actual.
  4. BranchX se elimina nuevamente y, por lo tanto, nunca aparecerá en ningún historial.

Por supuesto, eso no es realmente lo que está sucediendo, pero es un buen modelo mental para mí. Y si observa 2 y 3, comprenderá por qué los roles se intercambian ahora. A partir de 2, su rama actual es ahora la rama del servidor sin ninguno de sus cambios, por lo que esta es la nuestra (la rama en la que se encuentra). Los cambios que realizó ahora están en una rama diferente que no es la actual ( BranchX ) y, por lo tanto, estos cambios (a pesar de ser los cambios que realizó) son suyos (la otra rama utilizada en su acción).

Eso significa que si te unes y quieres que tus cambios siempre ganen, le dirías a git que siempre elija "el nuestro", pero si cambias de opinión y quieres que todos tus cambios siempre ganen, le dices a git que siempre elija "el suyo".