Cómo fusionar la rama actual en otra rama

182

Tengo dos ramas, maestro y dev. Siempre trabajo en desarrollo y solo verifico el código en la rama maestra una vez que ha sido aprobado para uso de producción. Cuando lo hago, tengo que hacer lo siguiente:

git checkout master
git merge dev
git checkout dev

Eso es muy detallado, y como lo hago con frecuencia, me gustaría minimizarlo. ¿Hay algún comando git que pueda usar para fusionar mi desarrollador de sucursal actual con el otro maestro de sucursal sin tener que verificar primero la rama maestra? Tal vez algo como:

git merge dev to master

sería grandioso. Miré a través de la documentación de git y no vi nada.

Chris
fuente
1
¿Has intentado usar git push para esto?
Jay Sullivan
11
¿Qué pasa con las sugerencias de empuje? Eso es para actualizar controles remotos , no fusionarse dentro del propio repositorio.
Cascabel
44
Jefromi tiene razón, empujar no es útil aquí. Estoy hablando de otra sucursal local, no de una sucursal remota.
Chris
2
Lo que es peor es cuando usted tiene cambios locales no confirmadas: git stash, git checkout master, git merge dev, git checkout dev, git stash pop.
Mu Mind
2
Buena pregunta. También quería esto porque quería ingresar a una rama no actual. Quería evitar cambiar de rama porque tengo un proceso que inicia una compilación si algún archivo en el árbol de trabajo cambia.
Kelvin

Respuestas:

94

1) Agregue un alias remoto para su repositorio local, por ejemplo:

git remote add self file:///path/to/your/repository

(O en ventanas git remote add self C:\path\to\your\repository)

2. Presione hacia el autocontrol remoto, por ejemplo:

git push self dev:master
zerome
fuente
2
Submódulos! Esto no solo resuelve el problema de la pregunta formulada, sino que también resuelve el problema de cambiar de rama cuando se tiene solo un submódulo. Gran consejo!
eddiemoya
2
+1 Esto es creativo y no toca el árbol de trabajo en absoluto. Solo una aclaración: /path/to/your/repositoryes la ruta a su árbol de trabajo, es decir, no incluya el .gitdirectorio. Además, esto debería ser evidente: el control remoto tendrá que actualizarse si mueve el repositorio.
Kelvin
No tengo suerte de que esto funcione en Windows ... git remote add self file:///c/projectssolo vuelve con las notas de uso
Maslow
2
@ JosephK.Strauss Primero puede fusionar master en la rama actual ( dev) y luego empujar el commit de fusión usando git push self dev:master.
Leonid Shvechikov
44
¿Por qué el alias remoto? .trabajado bien para mí: git push . head:master.
Geon
60

La respuesta actual más votada por @zerome es buena, pero es un poco innecesariamente detallada.

En la base de tu repositorio de git puedes hacer esto: git push . dev:master

Una solución más generalizada que funcionaría en cualquier parte del árbol sería:

git push $(git rev-parse --show-toplevel) dev:master
Kevin Lyda
fuente
3
git push . dev:master¡simplifiqué mucho mi vida! La mejor respuesta hasta ahora, gracias
Jeremy Belolo
vas a empujar el maestro combinado a un repositorio remoto como github? ahorre un paso haciendogit push origin dev:master
Alex R
1
¿Es posible replicar el merge --no-ffcomportamiento con esto?
exhuma
1
Recibo un nombre remoto no válido "." en Windows ¿Todavía necesito hacer git remote add self file:///myRepo?
kiewic
1
Pero esto realmente no hace una fusión ... Funcionará si el desarrollador está por delante del maestro, pero ¿y si no lo está?
Thomas Levesque
44

Su mejor opción sería usar un alias, colocado en su gitconfig global ( ~/.gitconfig):

[alias]
    merge-to = "!f() { git checkout $1 && git merge $2 && git checkout -; }; f"

para que pueda invocarlo desde cualquier repositorio como

git merge-to master dev
Cascabel
fuente
3
¿Qué pasaría si la fusión no es automática, pero requiere resolución de fusión? (En este caso, supongo que no se realiza ningún trabajo en master, por lo que no sucedería, pero aún así) ...
Stein G. Strindhaug
@Stein: Como lo usé &&, no ;, fallaría la fusión y no trataría de cambiar. Esperemos que el usuario sea lo suficientemente inteligente como para ver el mensaje "fusión fallida" y tratarlo.
Cascabel
66
Prefiero esta merge-to = "!f() { export tmp_branch=rama git | grep '*' | tr -d '*' ; git checkout $1 && echo git merge $tmp_branch && echo git checkout $tmp_branch; unset $tmp_branch; }; f", no me permite tener que escribir en la rama estoy actualmente, por lo que si desea fusionar deven mastery estoy en deveste momento yo sólo escribogit merge-to master
Steve
2
Mejor versión con backticks correctos y sin eco:merge-to = "!f() { export tmp_branch=`git branch | grep '* ' | tr -d '* '`; git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset $tmp_branch; }; f"
Simon Epskamp
2
el comando no establecido no es correcto. arreglado es: merge-to = "! f () {export tmp_branch = git branch | grep '* ' | tr -d '* '; git checkout $ 1 && git merge --no-ff $ tmp_branch && git checkout $ tmp_branch; unset tmp_branch;}; f"
sassman
38

Una pequeña modificación del alias Jefromi que no requiere que escriba la rama actual.

Así que lo utilice como: git merge-to dev.

Esto cambiará a la devrama, se fusionará con CURRENT y luego volverá a cambiar.

Por ejemplo, suponiendo que esté en la masterrama, fusionará el maestro en dev y seguirá estando en el maestro.

Definitivamente va a mis archivos de puntos :)

[alias]
  merge-to = "!gitmergeto() { export tmp_branch=`git branch | grep '* ' | tr -d '* '` && git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset tmp_branch; }; gitmergeto"
Dmytrii Nagirniak
fuente
6

Esto es viejo, pero ...

Combinando las soluciones de @ kevin-lyda y @ dmytrii-nagirniak anteriores. Este alias fusiona la rama actual en la rama especificada. Utiliza el método de control remoto con y usa comandos git para obtener el contexto.

[alias]
    merge-to = "!gitmergeto() { git push \"`git rev-parse --show-toplevel`\" `git rev-parse --abbrev-ref HEAD`:$1; } && gitmergeto"

Para ser utilizado como:

git merge-to other-branch-name
tField
fuente
4

Para fusionar la rama actual en otra rama sin verificar la otra rama:

Combinación de avance rápido

Esto es realmente facil. Por definición, una combinación de avance rápido simplemente significa que el puntero de la rama se mueve hacia adelante en el árbol de confirmación. Entonces, todo lo que necesita hacer es simular eso:

git branch -f master dev

Advertencias: Esto supone que masterapunta a una confirmación que también está en una devrama o en alguna otra rama. ¡Si no lo hace, corre el riesgo de perder el trabajo! A diferencia de git mergelo que creará una confirmación de fusión (o queja) cuando el avance rápido no es posible, este método obliga silenciosamente al puntero de la rama a apuntar a otra confirmación.

Esto también supone que eres el único que trabaja en el repositorio y / o sabes lo que estás haciendo.

Consejo: Si hiciste una git fetchy tienes nuevas confirmaciones origin/master, puedes mover la masterrama sin retirar usando:

git branch -f master origin/master

Fusionar mediante merge commit

Esto no siempre es posible. Para crear una confirmación de fusión, debe realizar una operación de fusión. Y para realizar una operación de fusión, debe tener confirmaciones en la otra rama que no están en la rama actual.

Si tiene commits en la masterrama que no están en la devrama, puede:

Descargo de responsabilidad: esto es simplemente una prueba de concepto, solo para mostrar que a veces es posible fusionar a la otra rama sin verificar. Si desea usarlo todos los días, probablemente quiera crear un alias para él utilizando la redirección de shell o hacer un script de shell para ello. Por otra parte, también puede hacer un script de shell para el proceso más corto que se muestra en la pregunta.

git checkout -b temp
git merge --no-ff -e master
git branch -f master temp
git checkout dev
git branch -D temp

Explicación:

  1. Echa un vistazo a una rama temporal que apunta a la misma confirmación que la rama actual.
  2. Fusionarse masteren la rama temporal e iniciar el editor de mensajes de confirmación. Si desea que el compromiso de fusión se vea como si hubiera fusionado la devrama master, edítelo a partir de esto:

    Merge branch 'master' into temp
    

    a esto:

    Merge branch 'dev'
    

    Consejo: puede usar en -m "Merge branch 'dev'"lugar de -eser más rápido.

  3. Actualizar el master puntero de rama para apuntar a la confirmación de fusión.
  4. Echa un vistazo a la devsucursal.
  5. Forzar la eliminación de la rama temporal.

Esto todavía toca su árbol de trabajo, pero mínimamente. No hace retroceder el árbol hasta el estado original mastersolo para traer los cambios de desarrollo una vez más. Puede que a algunos no les importe, pero para otros puede ser importante.

ADTC
fuente
1

Muchas veces vienes de la rama en la que te gustaría fusionar la rama actual. En ese caso podrías hacer:

git co - && git merge @{-1}

por ejemplo:

git checkout somebranch      // (while on master)

// add some commits

git co - && git merge @{-1}  // will merge somebranch into master
Tieme
fuente
1

Mi solución es similar a las otras respuestas, con las siguientes diferencias:

  • la función se divide en varias líneas para facilitar la lectura
  • la función llama set -expara que se imprima cada comando y si el comando falla, la función sale de inmediato
  • alias pasa sus argumentos excepto el primero (rama de destino) a git merge
  • la función incluye un comando nulo : git mergeque garantiza que la finalización de tabulación funcione con algunas configuraciones de shell (por ejemplo, gitfastde oh-my-zsh)
[alias]
  merge-to = "!f() { : git merge ; \
      set -ex ; \
      local this=$(git rev-parse --abbrev-ref HEAD) ; \
      local target=$1 ; \
      shift ; \
      git checkout $target ; \
      git merge $this \"$@\" ; \
      git checkout $this ; \
    } ; f"
artm
fuente