So führen Sie den aktuellen Zweig in einem anderen Zweig zusammen

182

Ich habe zwei Zweige, Master und Dev. Ich arbeite immer an Entwicklern und checke Code erst dann in der Hauptniederlassung ein, wenn er für die Verwendung in der Produktion genehmigt wurde. Wenn ich das mache, muss ich Folgendes tun:

git checkout master
git merge dev
git checkout dev

Das ist furchtbar ausführlich, und da ich es häufig mache, möchte ich es minimieren. Gibt es einen git-Befehl, mit dem ich von meinem aktuellen Zweigentwickler zum anderen Zweigmaster zusammenführen kann, ohne zuerst den Hauptzweig auschecken zu müssen? So etwas wie:

git merge dev to master

das wäre großartig. Ich habe die Git-Dokumentation durchgesehen und nichts gesehen.

Chris
quelle
1
Haben Sie versucht, Git Push dafür zu verwenden?
Jay Sullivan
11
Was ist mit den Vorschlägen von Push? Dies dient zum Aktualisieren von Fernbedienungen und nicht zum Zusammenführen innerhalb des eigenen Repositorys.
Cascabel
4
Jefromi hat recht, Push ist hier nicht sinnvoll. Ich spreche von einer anderen lokalen Niederlassung, nicht von einer entfernten Niederlassung.
Chris
2
Noch schlimmer ist , wenn Sie nicht gebundene lokale Änderungen haben: git stash, git checkout master, git merge dev, git checkout dev, git stash pop.
Mu Mind
2
Gute Frage. Ich wollte das auch, weil ich in eine langfristige Filiale ziehen wollte. Ich wollte vermeiden, Zweige zu wechseln, weil ich einen Prozess habe, der einen Build startet, wenn sich Dateien im Arbeitsbaum ändern.
Kelvin

Antworten:

94

1. Fügen Sie einen Remote-Alias ​​für Ihr lokales Repository hinzu, z.

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

(Oder unter Windows git remote add self C:\path\to\your\repository)

2. Drücken Sie auf die Selbstfernbedienung, z.

git push self dev:master
Null
quelle
2
Submodule! Dies löst nicht nur das Problem der gestellten Frage, sondern löst auch das Problem des Verzweigens von Zweigen, wenn nur ein Submodul vorhanden ist. Toller Tipp!
Eddiemoya
2
+1 Dies ist kreativ und berührt den Arbeitsbaum überhaupt nicht. Nur eine Klarstellung: Dies /path/to/your/repositoryist der Pfad zu Ihrem Arbeitsbaum, dh enthalten Sie nicht das .gitVerzeichnis. Dies sollte auch selbstverständlich sein: Die Fernbedienung muss aktualisiert werden, wenn Sie das Repo verschieben.
Kelvin
Ich habe kein Glück, dass dies in Windows funktioniert ... git remote add self file:///c/projectskommt gerade mit den Verwendungshinweisen zurück
Maslow
2
@ JosephK.Strauss Sie können den Master zuerst in den aktuellen Zweig ( dev) zusammenführen und dann das Zusammenführungs-Commit mit verwenden git push self dev:master.
Leonid Shvechikov
4
Warum der Remote-Alias? .hat bei mir gut funktioniert : git push . head:master.
Geon
60

Die derzeit am höchsten bewertete Antwort von @zerome ist gut, aber etwas unnötig ausführlich.

In der Basis Ihres Git Repo können Sie dies einfach tun: git push . dev:master

Eine allgemeinere Lösung, die überall im Baum funktionieren würde, wäre:

git push $(git rev-parse --show-toplevel) dev:master
Kevin Lyda
quelle
3
git push . dev:masterhat mein Leben sehr vereinfacht! Beste Antwort bei weitem, danke
Jeremy Belolo
Wirst du den zusammengeführten Master in ein Remote-Repository wie Github verschieben? Speichern Sie einen Schritt, indem Sie tungit push origin dev:master
Alex R
1
Ist es möglich, das merge --no-ffVerhalten damit zu replizieren ?
Exhuma
1
Ich erhalte einen ungültigen Remote-Namen "." in Windows. Brauche ich noch zu tun git remote add self file:///myRepo?
Kiewic
1
Aber das führt nicht wirklich zu einer Zusammenführung ... Es wird funktionieren, wenn der Entwickler dem Meister voraus ist, aber was ist, wenn es nicht so ist?
Thomas Levesque
44

Am besten verwenden Sie einfach einen Alias ​​in Ihrer globalen gitconfig ( ~/.gitconfig):

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

damit Sie es aus jedem Repository als aufrufen können

git merge-to master dev
Cascabel
quelle
3
Was würde passieren, wenn die Zusammenführung nicht automatisch erfolgt, sondern eine Auflösung der Zusammenführung erfordert? (In diesem Fall
gehe
@Stein: Da ich &&nicht verwendet habe ;, würde die Zusammenführung fehlschlagen und nicht versuchen, zurückzuschalten. Hoffentlich ist der Benutzer klug genug, um die Meldung "Zusammenführung fehlgeschlagen" zu sehen und damit umzugehen.
Cascabel
6
Ich bevorzuge diesen merge-to = "!f() { export tmp_branch=Git-Zweig grep '*' | tr -d ‚*‘ ; git checkout $1 && echo git merge $tmp_branch && echo git checkout $tmp_branch; unset $tmp_branch; }; f", es ist lassen Sie mich haben nicht zur Zeit bin ich auf in der Branche zu geben, also wenn ich fusionieren wollen devin masterund ich bin auf devjetzt Ich tippe einfachgit merge-to master
Steve
2
Bessere Version mit korrekten Backticks und ohne Echo: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
Der nicht gesetzte Befehl ist nicht korrekt. behoben ist: 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

Eine kleine Änderung des Jefromi-Alias, bei der Sie den aktuellen Zweig nicht eingeben müssen.

Sie verwenden es also wie folgt : git merge-to dev.

Dadurch wird auf den devZweig umgeschaltet, mit CURRENT zusammengeführt und dann zurückgeschaltet.

Angenommen, Sie befinden sich in einem masterZweig, wird der Master mit dev zusammengeführt, und Sie befinden sich weiterhin auf dem Master.

Es geht definitiv zu meinen 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"
Dmytrii Nagirniak
quelle
6

Das ist alt, aber ...

Kombinieren Sie die Lösungen von @ kevin-lyda und @ dmytrii-nagirniak oben. Dieser Alias ​​führt den aktuellen Zweig mit dem angegebenen Zweig zusammen. Es verwendet die Remotes-Methode mit und verwendet Git-Befehle, um den Kontext abzurufen.

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

Zu verwenden wie:

git merge-to other-branch-name
tFeld
quelle
4

So führen Sie den aktuellen Zweig in einem anderen Zweig zusammen, ohne den anderen Zweig auszuchecken:

Schnellvorlauf-Zusammenführung

Das ist wirklich einfach. Per Definition bedeutet eine Schnellvorlauf-Zusammenführung einfach, dass der Verzweigungszeiger im Festschreibungsbaum nach vorne verschoben wird. Sie müssen also nur Folgendes simulieren :

git branch -f master dev

Vorsichtsmaßnahmen: Dies setzt voraus, dass masterauf ein Commit verwiesen wird , das sich ebenfalls in einem devZweig oder einem anderen Zweig befindet. Wenn nicht, riskieren Sie, Arbeit zu verlieren! Im Gegensatz git mergedazu, bei dem ein Zusammenführungs-Commit (oder eine Beschwerde) erstellt wird, wenn ein schneller Vorlauf nicht möglich ist, zwingt diese Methode den Verzweigungszeiger stillschweigend , auf ein anderes Commit zu zeigen.

Dies setzt auch voraus, dass Sie der einzige sind, der am Repo arbeitet, und / oder Sie wissen, was Sie tun.

Tipp: Wenn Sie a ausgeführt haben git fetchund neue Commits eingegeben haben origin/master, können Sie den masterZweig verschieben, ohne ihn auschecken zu müssen.

git branch -f master origin/master

Zusammenführen über Merge Commit

Dies ist nicht immer möglich. Um ein Zusammenführungs-Commit zu erstellen, müssen Sie einen Zusammenführungsvorgang ausführen. Um einen Zusammenführungsvorgang durchzuführen, sollten Sie Commits in der anderen Verzweigung haben, die sich nicht in der aktuellen Verzweigung befinden.

Wenn Sie Commits in der masterFiliale haben, die sich nicht in der devFiliale befinden, können Sie:

Haftungsausschluss: Dies ist lediglich ein Proof-of-Concept, um zu zeigen, dass es manchmal möglich ist, eine Zusammenführung mit dem anderen Zweig durchzuführen, ohne ihn auszuchecken. Wenn Sie es jeden Tag verwenden möchten, möchten Sie wahrscheinlich mithilfe der Shell-Umleitung einen Alias ​​dafür erstellen oder ein Shell-Skript dafür erstellen. Andererseits können Sie auch ein Shell-Skript für den in der Frage gezeigten kürzeren Prozess erstellen.

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

Erläuterung:

  1. Überprüfen Sie einen temporären Zweig, der auf dasselbe Commit wie der aktuelle Zweig verweist.
  2. masterIn den temporären Zweig einbinden und Commit-Nachrichteneditor starten. Wenn das Zusammenführungs-Commit so aussehen soll, als hätten Sie den devZweig zusammengeführt master, bearbeiten Sie es folgendermaßen:

    Merge branch 'master' into temp
    

    dazu:

    Merge branch 'dev'
    

    Tipp: Sie können verwenden, -m "Merge branch 'dev'"anstatt -eschneller zu sein.

  3. Aktualisieren Sie den masterVerzweigungszeiger so, dass er auf das Zusammenführungs-Commit verweist.
  4. Schauen Sie sich die devFiliale an.
  5. Erzwingen Sie das Löschen des temporären Zweigs.

Dies berührt immer noch Ihren Arbeitsbaum, aber nur minimal. Der Baum wird nicht bis zum ursprünglichen Zustand zurückgesetzt, masternur um die Entwicklungsänderungen erneut einzuführen. Einige mögen sich nicht darum kümmern, aber für andere mag es wichtig sein.

ADTC
quelle
1

Oft kommen Sie aus dem Zweig, in den Sie den aktuellen Zweig einbinden möchten. In diesem Fall könnten Sie Folgendes tun:

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

beispielsweise:

git checkout somebranch      // (while on master)

// add some commits

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

Meine Lösung ähnelt den anderen Antworten mit den folgenden Unterschieden:

  • Die Funktion ist zur besseren Lesbarkeit in mehrere Zeilen unterteilt
  • Die Funktion wird aufgerufen, set -exsodass jeder Befehl gedruckt wird. Wenn der Befehl fehlschlägt, wird die Funktion sofort beendet
  • Der Alias ​​übergibt seine Argumente mit Ausnahme des ersten (Zielzweigs) an git merge
  • Die Funktion enthält einen Null-Befehl, : git mergeder sicherstellt, dass die Tab-Vervollständigung bei einigen Shell-Setups funktioniert (z. B. gitfastvon 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
quelle