Comment fusionner la branche actuelle dans une autre branche


182

J'ai deux branches, master et dev. Je travaille toujours sur le développement et je n'enregistre le code dans la branche principale qu'une fois qu'il a été approuvé pour une utilisation en production. Lorsque je le fais, je dois faire ce qui suit:

git checkout master
git merge dev
git checkout dev

C'est terriblement verbeux, et comme je le fais souvent, j'aimerais le minimiser. Y a-t-il une commande git que je peux utiliser pour fusionner de mon développement de branche actuel vers l'autre branche master sans avoir à vérifier la branche master au préalable? Quelque chose comme peut-être:

git merge dev to master

serait génial. J'ai parcouru la documentation git et je n'ai rien vu.


1
Avez-vous essayé d'utiliser git push pour cela?
Jay Sullivan

11
Qu'est-ce que les suggestions de push? C'est pour mettre à jour les télécommandes , pas pour fusionner dans son propre référentiel.
Cascabel

4
Jefromi a raison, push n'est pas utile ici. Je parle d'une autre succursale locale, pas d'une succursale distante.
Chris

2
Pire encore est quand vous avez des changements locaux non engagés: git stash, git checkout master, git merge dev, git checkout dev, git stash pop.
Mu Mind

2
Bonne question. Je le voulais aussi parce que je voulais me lancer dans une branche non actuelle. Je voulais éviter de changer de branche car j'ai un processus qui lance une compilation si des fichiers dans l'arbre de travail changent.
Kelvin

Réponses:


94

1. Ajoutez un alias distant pour votre référentiel local, par exemple:

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

(Ou sur windows git remote add self C:\path\to\your\repository)

2. Appuyez sur la télécommande automatique, ex:

git push self dev:master

2
Sous-modules! Non seulement cela résout le problème de la question posée, mais cela résout également le problème du changement de branche lorsque vous n'avez qu'un sous-module. Bon conseil!
eddiemoya

2
+1 Ceci est créatif et ne touche pas du tout à l'arbre de travail. Juste une précision: le /path/to/your/repositoryest le chemin vers votre arbre de travail, c'est-à-dire ne pas inclure le .gitrépertoire. De plus, cela devrait aller de soi: la télécommande devra être mise à jour si vous déplacez le dépôt.
Kelvin

Je n'ai pas de chance de faire fonctionner cela dans Windows ... Je viens de git remote add self file:///c/projectsrevenir avec les notes d'utilisation
Maslow

2
@ JosephK.Strauss Vous pouvez d'abord fusionner le maître dans la branche actuelle ( dev), puis pousser le commit de fusion en utilisant git push self dev:master.
Leonid Shvechikov

4
Pourquoi l'alias distant? .a bien fonctionné pour moi: git push . head:master.
geon

60

La réponse actuelle la plus votée de @zerome est bonne, mais elle est un peu inutilement verbeuse.

Dans la base de votre dépôt git, vous pouvez simplement faire ceci: git push . dev:master

Une solution plus généralisée qui fonctionnerait n'importe où dans l'arborescence serait:

git push $(git rev-parse --show-toplevel) dev:master

3
git push . dev:mastera beaucoup simplifié ma vie! Meilleure réponse de loin, merci
Jeremy Belolo

allez-vous pousser le maître fusionné vers un référentiel distant comme github? enregistrer une étape en faisantgit push origin dev:master
Alex R

1
Est-il possible de reproduire le merge --no-ffcomportement avec cela?
exhuma le

1
Je reçois le nom distant non valide « » dans Windows. Dois-je encore faire git remote add self file:///myRepo?
kiewic

1
Mais cela ne fait pas vraiment une fusion ... Cela fonctionnera si le développement est en avance sur master, mais que faire si ce n'est pas le cas?
Thomas Levesque

44

Votre meilleur pari serait d'utiliser simplement un alias, placé dans votre gitconfig ( ~/.gitconfig) global :

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

afin que vous puissiez l'invoquer depuis n'importe quel référentiel en tant que

git merge-to master dev

3
Que se passerait-il si la fusion n'est pas automatique, mais nécessite une résolution de fusion? (Dans ce cas, je suppose qu'aucun travail n'est effectué sur le master, donc cela n'arriverait pas, mais quand même) ...
Stein G. Strindhaug

@Stein: Depuis que j'ai utilisé &&, non ;, la fusion échouerait et n'essaierait pas de revenir en arrière. Espérons que l'utilisateur soit suffisamment intelligent pour voir le message «Échec de la fusion» et le traiter.
Cascabel

6
Je préfère cette merge-to = "!f() { export tmp_branch=branche git | grep '*' | tr -d « * » ; git checkout $1 && echo git merge $tmp_branch && echo git checkout $tmp_branch; unset $tmp_branch; }; f", il me laisse pas de taper dans la branche , je suis actuellement, donc si je veux fusionner devdans masteret je suis en devce moment , je viens de tapergit merge-to master
Steve

2
Meilleure version avec backticks corrects et sans écho: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
la commande unset n'est pas correcte. fixe est: 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

Une petite modification de l'alias Jefromi qui ne vous oblige pas à taper dans la branche actuelle.

Donc , vous l' utilisez comme: git merge-to dev.

Cela basculera vers la devbranche, la fusionnera avec CURRENT puis reviendra.

Par exemple, en supposant que vous soyez sur la masterbranche, cela fusionnera le maître dans dev et vous serez toujours sur le maître.

Cela va certainement à mes dotfiles :)

[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"

6

C'est vieux, mais ...

Combinaison des solutions de @ kevin-lyda et @ dmytrii-nagirniak ci-dessus. cet alias fusionne la branche actuelle dans la branche spécifiée. Il utilise la méthode des télécommandes avec et utilise les commandes git pour obtenir le contexte.

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

A utiliser comme:

git merge-to other-branch-name

4

Pour fusionner la branche actuelle dans une autre branche sans extraire l'autre branche:

Fusion rapide

C'est vraiment simple. Par définition, une fusion à avance rapide signifie simplement que le pointeur de branche est avancé dans l'arborescence de validation. Il vous suffit donc de simuler cela:

git branch -f master dev

Avertissements: cela suppose que cela masterpointe vers un commit qui est également dans une devbranche ou une autre branche. Sinon, vous risquez de perdre votre travail! Contrairement à git mergece qui créera un commit de fusion (ou se plaindra) lorsque l'avance rapide n'est pas possible, cette méthode force silencieusement le pointeur de branche à pointer vers un autre commit.

Cela suppose également que vous êtes le seul à travailler sur le repo et / ou que vous savez ce que vous faites.

Astuce: Si vous avez effectué un git fetchet que vous avez de nouveaux validations origin/master, vous pouvez déplacer la masterbranche sans extraire en utilisant:

git branch -f master origin/master

Fusionner via la validation de fusion

Ce n'est pas toujours possible. Pour créer une validation de fusion, vous devez effectuer une opération de fusion. Et pour effectuer une opération de fusion, vous devez avoir des commits dans l'autre branche qui ne sont pas dans la branche actuelle.

Si vous avez des commits dans la masterbranche qui ne sont pas dans la devbranche, vous pouvez:

Avertissement: Ceci est simplement une preuve de concept, juste pour montrer qu'il est parfois possible de faire une fusion avec l'autre branche sans vérification. Si vous souhaitez l'utiliser tous les jours, vous voudrez probablement lui créer un alias en utilisant la redirection shell ou créer un script shell pour cela. Là encore, vous pouvez également créer un script shell pour le processus plus court indiqué dans la question.

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

Explication:

  1. Découvrez une branche temporaire qui pointe vers le même commit que la branche actuelle.
  2. Fusionnez masterdans la branche temporaire et lancez l'éditeur de message de validation. Si vous voulez que le commit de fusion ressemble à ce que vous aviez fusionné la devbranche dansmaster , modifiez-la à partir de ceci:

    Merge branch 'master' into temp
    

    pour ça:

    Merge branch 'dev'
    

    Pointe: vous pouvez utiliser à la -m "Merge branch 'dev'"place de-e pour être plus rapide.

  3. Mettre à jour le master pointeur de branche pour qu'il pointe vers la validation de fusion.
  4. Vérifiez dev succursale.
  5. Forcer la suppression de la branche temporaire.

Cela touche toujours votre arbre de travail, mais de manière minimale. Il ne ramène pas l'arborescence à l'état d'origine masterjuste pour apporter à nouveau les changements de développement. Certains peuvent ne pas s'en soucier, mais pour d'autres, cela peut être important.


1

Souvent, vous venez de la branche dans laquelle vous souhaitez fusionner la branche actuelle. Dans ce cas, vous pouvez faire:

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

par exemple:

git checkout somebranch      // (while on master)

// add some commits

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

1

Ma solution est similaire aux autres réponses, avec les différences suivantes:

  • la fonction est divisée en plusieurs lignes pour plus de lisibilité
  • la fonction appelle set -exdonc chaque commande est imprimée et si la commande échoue, la fonction se termine immédiatement
  • alias passe ses arguments sauf le premier (branche cible) à git merge
  • la fonction inclut une commande nulle : git mergequi s'assure que la complétion par tabulation fonctionne avec certaines configurations de shell (par exemple gitfastdepuis 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"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.