So richten Sie Branches mit unterschiedlichen Pull/Push-Upstreams ein

Lesezeit: 7 Minuten

Ich habe ein lokales Git-Repo mit zwei Fernbedienungen: upstreamdas ursprüngliche Hauptrepo und originmein GitHub-Fork davon.

Ich möchte neue Zweige basierend auf erstellen upstream/masterschieben Sie sie an origin für PRs, und ziehen regelmäßig neue Änderungen ein upstream/master.

Gibt es eine Möglichkeit, meine Branches so einzurichten, dass dies standardmäßig geschieht? Dh:

$ git checkout -b my-new-branch --some-other-flags
$ git maybe some other command
# branch 'my-new-branch' points to 'upstream/master' and is checked out
# make changes, git commit
$ git push  # pushes to origin/my-new-branch
$ git pull  # pulls from upstream/master

So richten Sie Branches mit unterschiedlichen PullPush Upstreams ein
alecbz

Folgendes scheint zu funktionieren:

git config push.default current && git config remote.pushdefault origin

Erstellen Sie dann Zweige mit git checkout -b new-branch upstream/master.

git push drängt zu origin/my-branch, git pull zieht ab upstream/master.


Bei Zweigen, die auf anderen lokalen Zweigen statt auf Upstream/Master basieren, scheinen die Dinge etwas kniffliger zu sein. Ich könnte git config branch.autoSetupMerge alwaysaber Zweige würden dann von dem lokalen Zweig ziehen, von dem sie gestartet sind, nicht upstream/master. Oder ich könnte den Upstream auf setzen upstream/master ausdrücklich mit -u beim Erstellen der Verzweigung. Ich bin mir aber nicht sicher, was angemessener wäre.

Ein weiteres Ärgernis ist, dass Git mir manchmal sagt, wenn ich einen Zweig mit Änderungen auschecke:

Ihr Zweig ist 7 Commits vor ‘Upstream/Master’. (benutze “git push”, um deine lokalen Commits zu veröffentlichen)

Aber A) es ist in Ordnung, dass ich meinem Upstream voraus bin, ich warte darauf, diese Änderungen in einer PR zusammenzuführen, und B) was noch wichtiger ist, git push wird zu drängen new-branch bei Ursprungnicht master bei stromaufwärts.

Dies passiert jedoch nicht immer, also denke ich, dass ich hier eine andere Variable vermisse.

  • Da Sie das Problem gelöst haben, können Sie Ihre eigene Antwort markieren. Davon profitieren andere, die ähnliche Fragen haben.

    – Marina Liu

    17. August 2017 um 6:27 Uhr

  • Ich bin mit meiner Lösung noch nicht ganz zufrieden. Es scheint manchmal zu funktionieren, hat aber einige Kanten, die ich ausarbeiten muss.

    – Alecbz

    17. August 2017 um 14:17 Uhr

Gibt es eine Möglichkeit, meine einzurichten Geäst damit das standardmäßig passiert?

Nein: du bekommst nur einen “upstream” bzw @{u} Einstellung pro Zweig (Sie können einen Zweig mit haben Nein Upstream-Set, wenn Sie möchten, aber Ihre andere Option ist ein stromaufwärts). git fetch holt von der Fernbedienung in diesem Upstream und git merge verschmilzt mit dem in diesem Upstream genannten Zweig (und wie üblich, git pull entspricht im Wesentlichen Abrufen + Zusammenführen); git push schiebt … nun ja, jetzt wird es kompliziert.

Gibt es eine Möglichkeit, meine einzurichten Repository damit das standardmäßig passiert?

Ja, aber mit einem Fehler. Wie groß dieser Fehler ist, hängt von Ihrer Nutzung und Ihren Bedürfnissen ab. Die Verwendung (und Konfiguration) dieses Fehlers ist besonders kompliziert. Lassen Sie uns die Elemente durchgehen.

Jeder lokale Zweig kann nur einen Upstream haben, aber:

  • Der Upstream benennt zwei Teile. Einer ist ein Fernbedienung wie origin oder upstream; der andere ist ein verschmelzen wie refs/heads/master.

Diese werden kombiniert, um zu machen origin/master, zum Beispiel. Wir haben also bereits kein Glück damit, dass der Standard-Upstream beides ist origin/master und anything/my-new-branchob die anything ist origin.

Aber:

  • Sie können Git für einen “dreieckigen Workflow” konfigurieren, bei dem Sie von einer URL abrufen, aber per Push zu einer anderen, indem Sie die Einstellung vornehmen zwei URLs für eine bestimmte Fernbedienung.

Das bedeutet, dass Sie etwas Remote machen können, nennen wir es tri Holen Sie für dreieckig von der URL, die Sie für haben origin und drücken Sie auf die, für die Sie haben upstream. Wenn Zweig B hat tri als Fernbedienung und tri ruft von derselben URL ab wie origin schiebt aber auf die gleiche URL wie upstreamdann werden Sie tatsächlich von abrufen origin und zudrücken upstream.

Ihr Git wird jedoch ein wenig verwirrt sein, was refs/remotes/tri/master bedeutet. Wenn ein Push des Formulars:

git push tri somebranch:master

gelingt, das denkt jetzt dein Git refs/remotes/tri/master hat denselben Hash, den Sie gerade gepusht haben. Ihr Git denkt: Ja sicher! Der Typ, unter dem ich angerufen habe tri sagt, er hat es genommen! Sobald Sie laufen git fetch tri Sie erhalten einen anderen Hash und Ihr Git wird dies beheben, um sich daran zu erinnern, was sich auf derselben URL wie befindet origin aufs Neue. Ihr Git denkt: Das ist lustig, der Typ, unter dem ich angerufen habe tri sagt, er hat seine zurückgesetzt master. Na ja, das ist der andere Git für dich, der seinen zurücksetzt master die ganze Zeit…

Außerdem beim Laufen git push tri oder git push mit tri impliziert, aber nein Referenzspez Argumente auf der Kommandozeile … nun, das kommt von der git push Dokumentation:

Wenn git push [<repository>] ohne irgendetwas <refspec> Das Argument ist so eingestellt, dass einige Referenzen am Ziel mit aktualisiert werden <src> mit
remote.<repository>.push Konfigurationsvariable, :<dst> part kann weggelassen werden – ein solcher Push aktualisiert eine Referenz, die <src> normalerweise Updates ohne <refspec> auf der Kommandozeile. Ansonsten fehlt
:<dst> bedeutet, dieselbe Referenz wie die zu aktualisieren <src>.

Das heißt, Sie können ein Special einstellen remote.tri.push Konfiguration, damit git push tri ohne eine Quelle zu nennen, bzw git push tri somebranch ohne Namen :<dst>du kannst das schaffen somebranch Karte zu somebranch hier, auch wenn die one-upstream-einstellung dir erlaubt ist zum somebranch sagt master.

Setzen Sie diese alle zusammen

  • Du bekommst nur einen @{u}.
  • Aber das @{u} hat zwei Teile, a Fernbedienung und ein verschmelzen.
  • Dein @{u} kann eine spezielle Fernbedienung benennen, die zwei URLs hat: eine zum Abrufen und eine zweite zum Pushen.
  • Diese Fernbedienung kann auch eine haben remote.remote.pushdefault das erzwingt den Stoß :dst Teil zu einem anderen Namen als dem des Abrufs gehen verschmelzen Einstellung. (Nennen wir das pushtarget zum letzten Punkt.)
  • Der Nebeneffekt ist, dass die Remote-Tracking-Verzweigung specialremote/pushtarget wird falsch, bis Sie laufen git fetch specialremote. Dies wird die Dinge verwirrend machen, als ob sie aufgrund all des oben Genannten nicht bereits verwirrend wären.

Wenn Sie mich fragen, ob das oben genannte zu tun ist a gute IdeeIch werde sagen: definitiv nicht.

  • Nur um zu unterstreichen, dass dies ein Missbrauch von git ist: „Beachten Sie, dass die Push-URL und die Abruf-URL, auch wenn sie unterschiedlich gesetzt werden können, immer noch auf denselben Ort verweisen müssen. Was Sie an die Push-URL gepusht haben, sollte das sein, was Sie tun würden Sehen Sie, ob Sie sofort von der Abruf-URL abgerufen haben. Wenn Sie versuchen, von einem Ort (z. B. Ihrem Upstream) abzurufen und zu einem anderen (z. B. Ihrem Veröffentlichungs-Repository) zu pushen, verwenden Sie zwei separate Remotes.“ git-scm.com/docs/git-remote#git-remote-emset-urlem

    – Alecbz

    11. August 2017 um 17:34 Uhr


Sobald Sie den Zweig erstellt haben, müssen Sie ihn nach oben schieben und so einstellen, dass er Ihr ist local kann den Überblick behalten remote.

Sie können dies wie folgt tun (vorausgesetzt, Sie befinden sich bereits im Master-Zweig):

// Create and checkout the new branch
git checkout -b <your_branch_nane>

// Push new branch upstream and set it to track remote branch
git push -u origin <your_branch_name>

Dadurch wird Ihr neuer Zweig stromaufwärts verschoben. der -u -Argument legt es fest, um den Remote-Zweig zu verfolgen. Die -u Argument ist nur eine Abkürzung für die --set-upstream Streit.

Sie können mehr darüber lesen Arbeiten mit Remote-Zweigstellen.

Es gibt ein paar Möglichkeiten, dies anzugehen. Ich denke, Sie möchten wahrscheinlich einen Workflow übernehmen, der so aussieht:

  1. Beginnen Sie mit der Arbeit an einem neuen Branch basierend auf dem Upstream-Master:

    git checkout -b my-new-branch upstream/master
    
  2. Nehmen Sie Ihre Änderungen vor und konfigurieren Sie den Zweig so, dass er in Ihr Remote-Repository gepusht wird:

    git push -u origin my-new-branch
    

    (Anschließend können Sie einfach laufen git push von selbst und Änderungen werden an gesendet dein Repository)

  3. Wenn Sie neue Änderungen von Upstream einbringen möchten:

    git remote update
    git rebase upstream/master
    

Auf diese Weise können Sie regelmäßig neue Änderungen von Upstream einbringen und gleichzeitig einen linearen Verlauf beibehalten (anstatt einen mit Merge-Commits übersäten), was die Dinge vereinfacht, falls Sie Änderungen an Upstream zurücksenden möchten.

998360cookie-checkSo richten Sie Branches mit unterschiedlichen Pull/Push-Upstreams ein

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy