¿Existe una versión "de ellos" de "git merge -s ours"?

Resuelto elmarco asked hace 15 años • 21 respuestas

Al fusionar la rama del tema "B" en "A" usando git merge, obtengo algunos conflictos. Sé que todos los conflictos se pueden resolver usando la versión "B".

Estoy consciente de git merge -s ours. Pero lo que quiero es algo como git merge -s theirs.

¿Por qué no existe? ¿Cómo puedo lograr el mismo resultado después de la combinación conflictiva con los gitcomandos existentes? ( git checkoutcada archivo no fusionado de B)

La "solución" de simplemente descartar cualquier cosa de la rama A (el punto de confirmación de fusión con la versión B del árbol) no es lo que estoy buscando.

elmarco avatar Oct 06 '08 18:10 elmarco
Aceptado

Una alternativa similar es la opción --strategy-option(forma corta -X), que acepta theirs. Por ejemplo:

git checkout branchA
git merge -X theirs branchB

Sin embargo, esto es más equivalente a -X oursque -s ours. La diferencia clave es que -Xrealiza una fusión recursiva regular, resolviendo cualquier conflicto usando el lado elegido, mientras que -s ourscambia la fusión para ignorar completamente el otro lado.

En algunos casos, el principal problema al utilizarlo -X theirsen lugar de lo hipotético -s theirsson los archivos eliminados. En este caso, simplemente ejecute git rmcon el nombre de los archivos que se eliminaron:

git rm {DELETED-FILE-NAME}

Después de eso, es -X theirsposible que funcione como se esperaba.

Por supuesto, realizar la eliminación real con el git rmcomando evitará que se produzca el conflicto en primer lugar.

Alan W. Smith avatar Jul 29 '2010 15:07 Alan W. Smith

Una solución posible y probada para fusionar la sucursalB en nuestra sucursalA registrada:

# in case branchA is not our current branch
git checkout branchA

# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB    

# make temporary branch to merged commit
git branch branchTEMP         

# get contents of working tree and index to the one of branchB
git reset --hard branchB

# reset to our merged commit but 
# keep contents of working tree and index
git reset --soft branchTEMP

# change the contents of the merged commit
# with the contents of branchB
git commit --amend

# get rid off our temporary branch
git branch -D branchTEMP

# verify that the merge commit contains only contents of branchB
git diff HEAD branchB

Para automatizarlo, puede incluirlo en un script usando ramaA y ramaB como argumentos.

Esta solución conserva el primer y segundo padre de la confirmación de fusión, tal como se esperaría de git merge -s theirs branchB.

Paul Pladijs avatar Feb 11 '2011 13:02 Paul Pladijs

Las versiones anteriores de git te permitían usar la estrategia de fusión "de ellos":

git pull --strategy=theirs remote_branch

Pero desde entonces esto se eliminó, como lo explica en este mensaje Junio ​​Hamano (el mantenedor de Git). Como se indica en el enlace, en su lugar harías esto:

git fetch origin
git reset --hard origin

Sin embargo, tenga en cuenta que esto es diferente a una fusión real. Probablemente tu solución sea la opción que realmente estás buscando.

Pat Notz avatar Oct 06 '2008 13:10 Pat Notz

No está del todo claro cuál es el resultado deseado, por lo que existe cierta confusión sobre la forma "correcta" de hacerlo en las respuestas y sus comentarios. Intento dar una visión general y ver las siguientes tres opciones:

Intente fusionar y use B para conflictos

Esta no es la "versión de ellos para git merge -s ours" sino la "versión de ellos para git merge -X ours" (que es la abreviatura de git merge -s recursive -X ours):

git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB

Esto es lo que hace, por ejemplo, la respuesta de Alan W. Smith .

Utilice contenido de B únicamente

Esto crea una confirmación de fusión para ambas ramas, pero descarta todos los cambios branchAy solo conserva el contenido de branchB.

# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB

# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA

# Set branchA to current commit and check it out.
git checkout -B branchA

Tenga en cuenta que la fusión confirma que el primer padre ahora es el de branchBy solo el segundo es el de branchA. Esto es lo que hace, por ejemplo, la respuesta de Gandalf458 .

Use contenido de B únicamente y mantenga el orden principal correcto

Esta es la verdadera "versión de ellos para git merge -s ours". Tiene el mismo contenido que la opción anterior (es decir, solo el de branchB) pero el orden de los padres es correcto, es decir, el primer padre proviene de branchAy el segundo de branchB.

git checkout branchA

# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB

# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB

# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA

# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA

# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD

Esto es lo que hace la respuesta de Paul Pladijs (sin requerir una sucursal temporal).

Casos especiales

Si la confirmación de branchBes un antepasado de branchA, git mergeno funciona (simplemente sale con un mensaje como " Ya actualizado ").

git commit-treeEn este u otros casos similares/avanzados se puede utilizar el comando de bajo nivel .

siegi avatar Dec 07 '2014 00:12 siegi