Wie kann man mit Git in mehrere Zweige gleichzeitig ziehen?

13

In einem Repo habe ich mehrere Zweige, darunter "Master" und "Entwickeln", die eingerichtet sind, um entfernte Zweige "Ursprung / Master" und "Ursprung / Entwickeln" zu verfolgen.

Kann festgelegt werden, dass sowohl Master als auch Entwicklung gleichzeitig zusammengeführt (schnell vorgespult) werden sollen?

Wenn ich das git pulljetzt mache, bekomme ich so etwas:

remote: Counting objects: 92, done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 70 (delta 29), reused 28 (delta 8)
Unpacking objects: 100% (70/70), done.
From scm.my-site.com:my-repo
   5386563..902fb45  develop    -> origin/develop
   d637d67..ba81fb2  master     -> origin/master
Updating 5386563..902fb45
Fast-forward

Alle Remote-Zweige werden abgerufen, aber nur der Zweig, in dem ich mich gerade befinde, wird mit dem entsprechenden Remote-Zweig zusammengeführt.

Also muss ich tun git checkout master...

Switched to branch 'master'
Your branch is behind 'origin/master' by 106 commits, and can be fast-forwarded.

... und dann noch git pulleinmal und dann zurück zum Entwickeln, um das gewünschte Ergebnis zu erzielen.

Ich weiß, dass ich Aliase / Skripte erstellen kann, die diese Schritte ausführen. Aber ich möchte das nach Möglichkeit vermeiden, da es fehleranfällig und nicht sehr effizient ist .
Edit: ok lass mich das umformulieren. Mein Ziel war es nicht, das Anpassen von Git durch Skripte / Alias ​​zu entmutigen oder die Stirn zu runzeln. Ich würde nur eine eingebaute Lösung bevorzugen, wenn es existiert :)

Superole
quelle
Ich habe es versucht, git pull origin refs/heads/develop:refs/remotes/origin/develop refs/heads/master:refs/remotes/origin/masteraber das hat dazu geführt, dass der Remote-Master in die Entwicklung integriert wurde.
Superole
1
Warum sollte es fehleranfällig oder ineffizient sein? Git soll so angepasst werden. Übrigens, um zu vermeiden, dass Sie jeden Zweig auschecken müssen, möchten Sie möglicherweise Ihren Zweig pullin einen fetchgefolgt von einem mergein jeden Zweig aufteilen .
JJlin
@jjlin gut, wenn ich es kann, ohne jeden Zweig zu überprüfen, der für die Effizienz helfen kann. Es ist fehleranfällig, da die Matrix der Dinge, die schief gehen können, und die Auswirkungen auf den Rest des Skripts etwas komplex sind. Ich sage nicht, dass es unmöglich ist, es sicher zu machen, aber es wäre ein Kompromiss. Also würde ich eine eingebaute Lösung bevorzugen, wenn es existiert :)
Superole

Antworten:

11

Sie können einen Alias ​​einrichten, der git fetchmit refspecs verwendet wird, um Ihre Zweige mit nur einem Befehl schnell zusammenzuführen. Richten Sie dies als Alias ​​in Ihrer Benutzerdatei ein .gitconfig:

[alias]
    sync = "!sh -c 'git checkout --quiet --detach HEAD && \
                    git fetch origin master:master develop:develop ; \
                    git checkout --quiet -'"

Verwendung : git sync.

Hier ist, warum es funktioniert:

  1. git checkout --quiet HEADÜberprüft direkt Ihr aktuelles Commit und versetzt Sie in den Status " Abgelöst" . Auf diese Weise, wenn Sie sind masteroder develop, Sie lösen Ihre Arbeitskopie von diesem Zweig Zeiger, so dass sie verschoben werden (Git wird nicht zulassen , dass Sie die Zweig Referenzen verschieben , während der Arbeitskopie hat sie ausgecheckt).

  2. git fetch origin master:master develop:developverwendet refspecs mit fetch, um die masterund -Zweige developin Ihrem lokalen Repo schnell vorzuspulen . Die Syntax sagt Git im Grunde: "Hier ist eine Referenz des Formulars <source>:<destination>. Nehmen Sie es <destination>und spulen Sie es bis zum selben Punkt vor wie <source>". Die Quellen im Alias ​​sind also die Zweige von origin, während die Ziele die lokalen Repo-Versionen dieser Zweige sind.

  3. Schließlich git checkout --quiet -checkt die Filiale waren Sie das letzte Mal, unabhängig davon , ob oder ob nicht ein Fehler in den vorherigen Befehlen war. Wenn Sie also masterbeim Ausführen eingeschaltet git syncwaren und alles erfolgreich ist, verlassen Sie den Status des getrennten Kopfes und überprüfen die neu aktualisierten Daten master.

Siehe auch meine Antwort auf git: einen lokalen Zweig aktualisieren, ohne ihn auszuchecken? .

40XUserNotFound
quelle
Ich verstehe die losgelöste Magie hier nicht ganz. Warum kann der Zeiger auf den Master nicht bewegt werden, wenn die Entwicklung ausgecheckt ist? ... trotzdem habe ich es versucht und es scheint zu funktionieren, außer jetzt bekomme ich "Ihr Zweig ist um 1 Commit vor 'origin / development'."
Superole
... was beim nächsten Ziehen gelöst ist
Superole
@ Superole Welcher Zweig ist voraus, origin/developwenn Sie den Alias ​​verwenden? Es wäre nicht sinnvoll, wenn es Ihre lokale developNiederlassung wäre. Außerdem kann der Zeiger für master verschoben werden, wenn er developausgecheckt ist. Wenn er masterausgecheckt ist, können Sie nicht schnell vorspulen, masterda dies Ihre Arbeitskopie beeinträchtigen würde. Deshalb trennen Sie die Arbeitskopie von ihm zuerst mit git checkout head. Ich habe eine andere Antwort gesehen, die es als "auf einem Felsen stehen" beschrieb. Man muss vom Felsen steigen, bevor man ihn bewegen kann.
40XUserNotFound
Es war in der Tat meine lokale Entwicklung. Und der Grund muss sein, dass dieser Abruf die Tracking-Zweige nicht aktualisiert. So wie ich es verstehe; Ein Pull holt sich den Ursprung / die Entwicklung und verschmilzt ihn dann mit der Entwicklung.
Superole
Es ist sehr wichtig , dass diese Antwort verursacht fatal: bad config line xx in file xxx. was durch das Semikolon verursacht wird. Sie müssen den gesamten Befehl in doppelte Anführungszeichen setzen, um dieses Problem zu vermeiden.
William Leung
1

Installiere git-up . Sie erhalten den Befehl, mit git-updem alle lokalen Zweige in Ihrem Repository abgerufen werden.

BillyTom
quelle
Süss! Ich werde das auf jeden Fall überprüfen.
Superole
2
heh: P Die Anweisungen, die Windows unterstützt, fehlen vorhersehbar. und es muss noch ein strenger Beweis formuliert werden, dass es definitiv nicht mit Ihrem Git-Setup zu tun hat, Daten löscht oder in Ihrem Namen einen verrückten Unsinn an Hacker News sendet. , kombiniert mit der Notwendigkeit von Ruby, trieb mich weg. Ich mag das Konzept.
Superole
Gut , dass es ein Verfahren überhaupt ... irgendwie sucky, obwohl , dass jede einzelne Methode erfordert einiges Drittanbieter - Tool. Wie dieses und diejenigen mit einem Shell-Befehl "Rezept" oder einem Alias, der eine bestimmte (plattformspezifische) Shell verwendet.
0xC0000022L
0

Es scheint, dass es keine eingebaute Option für Git gibt, um in mehrere Zweige zu ziehen. Zumindest nicht in Version 1.8.0. obwohl @ Cupcakes Antwort nah dran ist.

Durch den Kommentar von @ jjlin wurde mir jedoch klar, dass ich zumindest nicht zweimal ziehen muss.

Eine etwas effizientere Sequenz wäre also:

git pull
git checkout master
git merge origin/master
git checkout -

Unweigerlich habe ich einen Alias ​​erstellt, mich aber entschlossen, den Auszug wegzulassen, und mich darauf konzentriert, nur einen anderen Zweig schnell vorzuspulen.

[alias]
ffwd = "!_() { git checkout $1 && git merge --ff-only origin/$1 && git checkout -; }; _"

Ohne Tests setzt dieser Alias ​​natürlich voraus, dass ich einen gültigen Namen eines ff'able-Zweigs als erstes Argument gebe und ansonsten ein undefiniertes Verhalten habe. Es ist auch nicht optimal für Anwendungsfälle mit mehr als zwei Zweigen, aber es wird mir das bringen, was ich jetzt brauche.

git pull
git ffwd master
Superole
quelle