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
ygit 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 laours
(es decir, "nuestra historia canónica compartida"), mientras que lo que hizo en su lado se ramifica como latheirs
(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
ygit 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>
paragit merge
y / ogit 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í:
- Todas las confirmaciones que ha realizado desde su último tirón se trasladan a una rama propia, nombremos BranchX .
- 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.
- Ahora, cada commit en BranchX se selecciona de manera antigua a nueva en su rama actual.
- 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".