Dado un repositorio git con dos ramas master
y feature
. Al volver a basar la rama de características en la parte superior del maestro usando rebase master
digamos ese archivo a.txt
contiene un conflicto que debe resolverse antes de que la reorganización pueda continuar.
Sé que puedo resolver el conflicto en tres pasos:
- abierto
a.txt
en mi editor resolver manualmente el conflicto - llamar
git add a.txt
para decirle a git que he resuelto manualmente el conflicto - llamar
git rebase --continue
mover la rebase hacia adelante
¿Hay alguna manera de evitar el paso 1 diciéndole a git que quiero la versión del archivo de la rama maestra o quiero la versión del archivo de la rama de funciones sin tener que realizar los pasos 1 y 2 anteriores?
Torek
Sí. De hecho, hay más de una manera de hacerlo.
Los comandos rebase y merge (y cherry-pick, para el caso) toman todos los mismos strategy
y -X
banderas para pasar a la maquinaria subyacente de git merge. Para el recursive
estrategia, -Xours
y -Xtheirs
elegir uno u otro “lado” de los archivos en el caso de que se fusione un archivo modificado en ambas ramas.
O, esto es bastante diferente, en los casos en que fusionar se detiene con un conflictopuedes usar git checkout
con el --ours
o --theirs
banderas, para elegir la versión de un lado o del otro. (Puedes hacer esto con otros comandos; aquí, me quedaré con --ours
y --theirs
ya que estos coinciden con los argumentos de los comandos que usan la maquinaria de combinación).
Por supuesto, esto es diferente porque puede cambiar las opciones:
$ git checkout main
Switched to branch 'main'
$ git merge branch
... conflicts in files A and B ...
$ git checkout --ours -- A # takes main:A
$ git checkout --theirs -- B # takes branch:B
Tenga en cuenta que esto es bastante diferente del “nuestro estrategia” (lo anterior muestra el “recursive
estrategia con la ours
opción”). Con el “nuestro estrategia“, ocurre algo completamente diferente. Comencemos sin él, haciendo la misma combinación nuevamente:
$ git checkout main && git merge branch
... conflicts ...
$ git checkout --ours -- A B # take main:A and main:B
Digamos que hay un tercer archivo, C
, ese git puede fusionarse por sí solo. Cuando haces lo anterior, git se fusiona C
y tu tomas main:A
y main:B
. Si fueras a usar git merge --strategy=ours branch
sin embargo, git tomaría main:A
, main:B
y main:C
. descartaría la branch:C
cambios en lugar de fusionarlos automáticamente.
he usado git merge
anterior porque hace que las cosas “nuestras” y “suyas” “funcionen bien”. Sin embargo, no me gusta la forma en que git los nombra, porque cuando estás haciendo una rebase, la versión nuestra/suya se intercambia, porque la rebase funciona cambiando a la rama “otra” y haciendo una serie de selecciones. Eso es:
$ git checkout mine; git rebase theirs
funciona debajo haciendo el equivalente (muy) aproximado de:
$ git checkout theirs; git cherry-pick theirs..mine
y luego, barajar las etiquetas de las ramas para que esa rama theirs
en realidad no se mueve. (No es tan malo internamente 🙂 pero logra hacer --ours
significa “suyo” y --theirs
significa “nuestro”, lo cual es bastante malo externamente.)
-
gracias por explicar por qué la rebase cambia entre las etiquetas nuestras y de ellos.
– ams
31 de enero de 2014 a las 22:22
-
@torek Siempre me encantan tus respuestas. P: es
git merge --strategy=ours
igual agit merge --ours --file_with_conflict1 --file_with_conflict2 ... --file_with_conflict_n
donde ‘file_with_conflict1’, … ‘file_with_conflict_n’ son todos los archivos con conflictos de combinación?– Diana
22 de enero a las 2:17
-
@Diana:
git merge
no toma--ours
. ¿Estás pensando engit merge-file
? (Su uso es diferente, pero tiene--ours
.)– torek
22 de enero a las 2:58
-
@torek ¡Vaya! lo siento reformule mi pregunta aquí: a.
git merge --strategy=ours
b.git merge
despuésgit checkout --ours --file_with_conflict1 --file_with_conflict2 ... --file_with_conflict_n
donde ‘file_with_conflict1’, … ‘file_with_conflict_n’ son todos los archivos con conflictos de combinación? ¿Son (a) y (b) equivalentes?– Diana
24 de enero a las 14:57
-
@Diana: Ah. No porque
git merge
sin que-s ours
intenta fusiones para cada archivo. Algunos de estos tendrán éxito sin conflicto, combinando así el trabajo. Otros tendrán conflictos; lagit checkout --ours
pues esos archivos desecharán su trabajo, llevándose sólo el nuestro. Entonces obtendremos una mezcla: algunos archivos exclusivamente de nosotros (donde cambiamos un archivo y ellos no lo hicieron, o donde hubo un conflicto), algunos exclusivamente de ellos (donde ellos cambiaron un archivo y nosotros no lo hicimos), y algunos combinados (donde merge pudo combinar el trabajo sin conflictos). Pero con-s
nuestro, Git lo hará ignorar su trabajo.– torek
24 de enero a las 16:37
ash wilson
Puedes usar:
git checkout --ours -- path/to/file
O:
git checkout --theirs -- path/to/file
…durante una fusión o reorganización para elegir una versión particular de un archivo en conflicto; porque rebasar es un poco extraño, --theirs
en este caso seria feature
la versión de, --ours
sería master
‘s.
-
en realidad, tu no Necesitar
git add
, porque la comprobación escribe “a través del índice”, copiando la versión nuestra o de ellos en la “ranura 0” del índice antes de escribirla en el árbol de trabajo. (Haciendogit add
aunque es inofensivo).– torek
31 de enero de 2014 a las 22:10
-
¿Ah, de verdad? Pensé que también tenía que escenificarlo, escenificarlo como una resolución. Actualizaré la respuesta, gracias!
– Ceniza Wilson
31 de enero de 2014 a las 22:12
Creo que lo que estás buscando, que se librará de los tres pasos, es
git rebase master -X theirs
que resolverá automáticamente los conflictos a favor de feature
(la sucursal actualmente desprotegida), o
git rebase master -X ours
El sentido de ours
y theirs
es contrario a la intuición como argumentos para rebase, como se indica en la descripción de la opción en http://git-scm.com/docs/git-rebase
-
Si hay dos archivos en conflicto a.txt y b.txt, es posible que desee seleccionar a.txt de la rama maestra y b.txt, es posible que desee fusionarlos manualmente. ¿Los comandos que sugiere se aplican a todos los archivos en conflicto?
– ams
31 de enero de 2014 a las 22:07
-
En ese caso, la respuesta de Ash Wilson es la indicada 🙂
– GreenAsJade
31 de enero de 2014 a las 22:09