Ich habe ein lokales Git-Repo mit zwei Fernbedienungen: upstream
das ursprüngliche Hauptrepo und origin
mein GitHub-Fork davon.
Ich möchte neue Zweige basierend auf erstellen upstream/master
schieben 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

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 always
aber 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.
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-branch
ob 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 upstream
dann 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.
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:
-
Beginnen Sie mit der Arbeit an einem neuen Branch basierend auf dem Upstream-Master:
git checkout -b my-new-branch upstream/master
-
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)
-
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.
9983600cookie-checkSo richten Sie Branches mit unterschiedlichen Pull/Push-Upstreams einyes