tag - Resolver los conflictos de fusión de Git en favor de sus cambios durante un tirón
resolver conflictos git (9)
¿Cómo resuelvo un conflicto de combinación de git en favor de cambios realizados?
Básicamente, necesito eliminar todos los cambios conflictivos de un árbol de trabajo sin tener que pasar por todos los conflictos con un git mergetool
mientras git mergetool
todos los cambios sin conflictos. Preferiblemente hacer esto mientras tira, no después.
de https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging
Esto básicamente hará una fusión falsa. Registrará un nuevo compromiso de fusión con ambas sucursales como padres, pero ni siquiera verá la sucursal en la que se está fusionando. Simplemente registrará como resultado de la combinación del código exacto en su sucursal actual.
$ git merge -s ours mundo
Fusión hecha por la estrategia ''nuestra''.
$ git diff HEAD HEAD~
Puede ver que no hay diferencia entre la rama en la que estábamos y el resultado de la fusión.
A menudo, esto puede ser útil para engañar a Git para que piense que una rama ya está fusionada cuando se realiza una fusión más adelante. Por ejemplo, supongamos que se bifurcó en una rama de lanzamiento y ha realizado algún trabajo en él que querrá volver a fusionar en su rama maestra en algún momento. Mientras tanto, algunas correcciones de errores en el maestro se deben incluir en la rama de lanzamiento. Puede fusionar la rama de corrección de errores en la rama de lanzamiento y también fusionar -su es la misma rama en su rama maestra (aunque la solución ya está allí), de modo que cuando vuelva a combinar la rama de lanzamiento, no haya conflictos con la solución de errores.
Una situación que he encontrado útil si quiero que el maestro refleje los cambios de una nueva rama de tema. Me he dado cuenta de que -Xtheirs no se fusiona sin conflictos en algunas circunstancias ... por ejemplo,
$ git merge -Xtheirs topicFoo
CONFLICT (modify/delete): js/search.js deleted in HEAD and modified in topicFoo. Version topicFoo of js/search.js left in tree.
En este caso la solución que encontré fue
$ git checkout topicFoo
desde topicFoo, primero fusione en master usando la estrategia -s ours, esto creará el compromiso falso que es solo el estado de topicFoo. $ git merge -s nuestro maestro
compruebe la confirmación de fusión creada
$ git log
Ahora revisa la rama maestra
$ git checkout master
fusione la rama de tema de nuevo, pero esta vez use la estrategia recursiva de -Xtheirs, esto le presentará una rama maestra con el estado de topicFoo.
$ git merge -X theirs topicFoo
De acuerdo, imagínate el escenario en el que estaba:
Intenta una merge
, o tal vez una cherry-pick
, y se detiene con
$ git cherry-pick 1023e24
error: could not apply 1023e24... [Commit Message]
hint: after resolving the conflicts, mark the corrected paths
hint: with ''git add <paths>'' or ''git rm <paths>''
hint: and commit the result with ''git commit''
Ahora, ve el archivo en conflicto y realmente no quiere mantener sus cambios. En mi caso anterior, el archivo entró en conflicto solo en una nueva línea que mi IDE había agregado automáticamente. Para deshacer los cambios y aceptar los suyos, la forma más fácil es:
git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php
Lo contrario de esto (para sobrescribir la versión entrante con su versión) es
git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php
Sorprendentemente, no pude encontrar esta respuesta muy fácilmente en la Red.
El git pull -X theirs
respuestas puede crear un feo compromiso de combinación, o emitir un
error: sus cambios locales en los siguientes archivos se sobrescribirían mediante la combinación:
Si desea simplemente ignorar cualquier modificación local a los archivos del repositorio, por ejemplo, en un cliente que siempre debería ser un reflejo de un origen, ejecute esto (reemplace el master
con la rama que desea):
git fetch && git reset --hard origin/master
¿Como funciona? git fetch
hace git pull
pero sin fusionar . Luego, git reset --hard
hace que tu árbol de trabajo coincida con el último commit. Todos los cambios locales a los archivos en el repositorio serán discarded , pero los nuevos archivos locales quedarán solos.
Para resolver todos los conflictos con la versión en una rama en particular:
git diff --name-only --diff-filter=U | xargs git checkout ${branchName}
Por lo tanto, si ya está en el estado de fusión y desea mantener la versión maestra de los archivos en conflicto:
git diff --name-only --diff-filter=U | xargs git checkout master
Por favor, no que a veces esto no funcione :
git checkout --su ruta / a / archivo
o
git checkout - theirs ruta / a / archivo
Hice esto en su lugar, asumiendo que HEAD es nuestra y MERGE_HEAD es de ellos.
git checkout HEAD -- path/to/file
o:
git checkout MERGE_HEAD -- path/to/file
Después de hacer esto y estamos bien:
git add .
Si desea comprender más, vea la maravillosa publicación de torek aquí: git checkout --ours no elimina archivos de la lista de archivos sin combinar
Puedes usar la opción de estrategia recursiva "de ellos":
git merge --strategy-option theirs
Del man :
ours
This option forces conflicting hunks to be auto-resolved cleanly by
favoring our version. Changes from the other tree that do not
conflict with our side are reflected to the merge result.
This should not be confused with the ours merge strategy, which does
not even look at what the other tree contains at all. It discards
everything the other tree did, declaring our history contains all that
happened in it.
theirs
This is opposite of ours.
Nota: como dice la página de manual, la opción de estrategia de fusión "nuestra" es muy diferente de la estrategia de fusión "nuestra".
Si ya está en estado de conflicto, y desea aceptar todos los suyos:
git checkout --theirs .
git add .
Si quieres hacer lo contrario:
git checkout --ours .
git add .
Esto es bastante drástico, así que asegúrate de que realmente quieres eliminar todo así antes de hacerlo.
Usuarios de IDE de Código VS (Git integrado):
Si desea aceptar todos los cambios entrantes en el archivo de conflicto , realice los siguientes pasos.
1. Go to command palette - Ctrl + Shift + P
2. Select the option - Merge Conflict: Accept All Incoming
Del mismo modo, puede hacer para otras opciones como Aceptar todos los dos, Aceptar todos los actuales, etc.
git pull -s recursive -X theirs <remoterepo or other repo>
O, simplemente, para el repositorio predeterminado:
git pull -X theirs
Si ya estás en estado conflictivo ...
git checkout --theirs path/to/file