Me estoy fusionando en una rama remota que puede tener muchos conflictos. ¿Cómo puedo saber si tendrá conflictos o no?
No veo nada como un --dry-run
encendido git-merge
.
Me estoy fusionando en una rama remota que puede tener muchos conflictos. ¿Cómo puedo saber si tendrá conflictos o no?
No veo nada como un --dry-run
encendido git-merge
.
Respuestas:
Como se señaló anteriormente, pase la --no-commit
bandera, pero para evitar una confirmación de avance rápido, también pase --no-ff
, así:
$ git merge --no-commit --no-ff $BRANCH
Para examinar los cambios organizados:
$ git diff --cached
Y puede deshacer la fusión, incluso si es una fusión de avance rápido:
$ git merge --abort
git merge --only-if-there-wont-be-any-conflicts
o git diff --show-conflicts <commit>
sería realmente útil. Es una pena que todavía no sea posible, o me estoy perdiendo algo
git pull --ff-only
!
Simplemente tuve que implementar un método que encuentra automáticamente conflictos entre un repositorio y su control remoto. Esta solución se fusiona en la memoria para que no toque el índice ni el árbol de trabajo. Creo que esta es la forma más segura posible de resolver este problema. Así es como funciona:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
( mergebase es la identificación hexadecimal que merge-base imprimió en el paso anterior)Ahora suponga que desea fusionar el maestro remoto con su maestro local, pero puede usar cualquier rama. git merge-tree
ejecutará la fusión en la memoria e imprimirá el resultado en la salida estándar. Grep para el patrón <<
o >>
. O puede imprimir el resultado en un archivo y verificarlo. Si encuentra una línea que comienza con 'cambiado en ambos', lo más probable es que haya un conflicto.
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
simplemente increíble! +100
+<<<<<<< .our
por lo tanto, uso una expresión grep comogrep -q '^+<* \.our$'
Mi solución simple de fuerza bruta para esto es:
Crear una rama "pre-master" (del maestro, por supuesto)
Combina todas las cosas que quieras en este pre-master.
Entonces puedes ver cómo ocurrió la fusión sin tocar al maestro.
De todos modos, seguiría el consejo de @ orange80.
git merge --abort
si hay conflictos, git reset --hard HEAD~1
si hubo una fusión o git reset --hard origin/master
. Crear otra rama te da una sensación de seguridad, pero si aprendes cómo funciona git, entenderás que es un miedo fuera de lugar. Cuando la preocupación es por no cambiar la copia de trabajo, esto no ofrece solución.
git merge --no-commit
no abortará una fusión si se puede reenviar rápidamente. git merge --abort
no funciona si se fusionó. Si desea escribir esto como un script, es incómodo, ya git merge
que no responde con códigos de error lo suficientemente buenos como para explicar los diferentes tipos de conflictos. Trabajar con una rama nueva evita que un script roto deje su repositorio en un estado que requiera intervención manual. Claro que no puedes perder nada. Pero es más fácil construir de otra manera.
Deshacer una fusión con git es tan fácil que ni siquiera debería preocuparse por la ejecución en seco:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
EDITAR: Como se señala en los comentarios a continuación, si tiene cambios en su directorio de trabajo o área de preparación, probablemente desee guardarlos antes de hacer lo anterior (de lo contrario, desaparecerán después de lo git reset
anterior)
git branch --contains HEAD
o incluso más directamente, solo usegit merge --ff-only
--dry-run
no "simplemente comprobaría si una fusión se adelantará". Devolvería el resultado exacto que haría una fusión: archivos, conflictos, etc. Si will ff no es realmente interesante, ¿verdad?
git stash; git reset --hard
? @BrianPhillips
Hice un alias para hacer esto y funciona de maravilla, hago esto:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
Ahora solo llamo
git mergetest <branchname>
Para averiguar si hay conflictos.
Simplemente diferencie su rama actual contra la rama remota, esto le dirá qué va a cambiar cuando haga una extracción / fusión.
#see diff between current master and remote branch
git diff master origin/master
Yo uso el comando request-pull git para hacerlo. Le permite ver cada cambio que sucedería al fusionar, pero sin hacer nada en sus repositorios locales o remotos .
Por ejemplo, imagine que desea fusionar una rama llamada "feature-x" en su rama maestra
git request-pull master origin feature-x
le mostrará un resumen de lo que sucedería (sin hacer nada):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Si agrega el -p
parámetro, también obtendrá el texto completo del parche, exactamente como si estuviera haciendo un git diff en cada archivo modificado.
master
y origin
hacer en las opciones de línea de comandos, y ¿qué pasa si estoy, por ejemplo, en un local branch1
y quiero hacer un request-pull
en una rama de característica local branch2
? ¿Aún lo necesito origin
? Por supuesto, uno siempre puede leer la documentación.
Me sorprende que nadie haya sugerido usar parches todavía.
Digamos que usted desea probar una combinación de your_branch
a master
(estoy suponiendo que haya master
comprobado):
$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch
Eso debería hacer el truco.
Si obtienes errores como
error: patch failed: test.txt:1
error: test.txt: patch does not apply
eso significa que el parche no tuvo éxito y una fusión produciría conflictos. Sin salida significa que el parche está limpio y podrá fusionar fácilmente la rama
Tenga en cuenta que esto realmente no cambiará su árbol de trabajo (aparte de crear el archivo de parche, por supuesto, pero puede eliminarlo de forma segura después). De la documentación de git-apply:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Nota para cualquiera que sea más inteligente / más experimentado con git que yo: avíseme si me equivoco aquí y este método muestra un comportamiento diferente al de una fusión regular. Parece extraño que en los más de 8 años que ha existido esta pregunta nadie sugiera esta solución aparentemente obvia.
git diff master your_branch | git apply --check
.
Esto puede ser interesante: de la documentación:
Si intentó una fusión que resultó en conflictos complejos y desea comenzar de nuevo, puede recuperarse con git merge --abort .
Pero también puedes hacerlo de la manera ingenua (pero lenta):
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Nota: no funcionará simplemente clonando a / tmp, necesitará una copia para asegurarse de que los cambios no confirmados no entren en conflicto).
cp -r repository/.git /tmp/repository/.git
, cd /tmp/repository
, git reset --hard
, git add --all
, git reset --hard
(por si acaso), git status
(para comprobar que está limpio).
Soy consciente de que esta es una pregunta antigua, pero es la primera en aparecer en una búsqueda de Google.
Git introdujo una opción --ff-only al fusionar.
De: http://git-scm.com/docs/git-merge
--ff-only
Negarse a fusionar y salir con un estado distinto de cero a menos que el HEAD actual ya esté actualizado o la fusión se pueda resolver como un avance rápido.
Hacer esto intentará fusionarse y avanzar rápidamente, y si no puede, aborta y le indica que no se pudo realizar el avance rápido, pero deja intacta su rama de trabajo. Si puede avanzar rápidamente, realizará la fusión en su rama de trabajo. Esta opción también está disponible en git pull
. Por lo tanto, puede hacer lo siguiente:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Uso git log para ver qué ha cambiado en una rama de características desde la rama maestra
git log does_this_branch..contain_this_branch_changes
por ejemplo, para ver qué confirmaciones hay en una rama de características que se ha / no se ha fusionado para dominar:
git log master..feature_branch
Si desea avanzar rápidamente de B a A, debe asegurarse de que git log B..A no muestre nada, es decir, A no tiene nada que B no tenga. Pero incluso si B..A tiene algo, es posible que pueda fusionarse sin conflictos, por lo que lo anterior muestra dos cosas: que habrá un avance rápido y, por lo tanto, no obtendrá un conflicto.
Mi solución es fusionarme al revés.
En lugar de fusionar su rama en la rama "objetivo" remota, combine esa rama con la suya.
git checkout my-branch
git merge origin/target-branch
Verá si hay conflictos y puede planificar cómo resolverlos.
Después de eso, puede abortar la fusión a través de git merge --abort
o (si no hubo conflictos y se ha producido la fusión) retroceder a la confirmación anterior a través degit reset --hard HEAD~1