Wie gehen Sie mit einem bereits umbasierten öffentlichen Repository um?

Lesezeit: 5 Minuten

Diese Frage wurde wahrscheinlich schon einmal gestellt, aber ich habe eine verdammt lange Zeit, danach zu suchen.

Sehr häufig, erfahren git Benutzer werden sagen “nicht rebase Repositories, die bereits öffentlich enthüllt wurden!” und das zu Recht. Aber ich sehe keine Informationen, die sich mit dem Fallout befassen. Ich weiß, dass wir uns nicht in eine Situation bringen sollten, aber was tun wir, wenn es passiert? passieren?

Original: A--B--C--D--E--F
My Repo:  A--B--C--D
                    
                     X--Y--Z
Rebased:  A--B
              
               L--M--N--O

Also ich fetch, das sollte ziemlich einfach sein, oder? Und… was passiert dann? Wenn ich es tue `pull --rebase, es sollte irgendwann scheitern, weil C--D wird vermisst. Welche Fehler treten tatsächlich auf und wie behebe ich sie?

  • Git 2.0 wird den Prozess vereinfachen, den ich in meiner Antwort unten beschreibe.

    – VonC

    6. Dezember ’13 um 12:30 Uhr

Wie gehen Sie mit einem bereits umbasierten offentlichen Repository um
Cascabel

Es gibt einen Abschnitt in der git-rebase Manpage namens “RECOVERING FROM UPSTREAM REBASE”, die dies recht gut beschreibt.

Abrufen

Lassen Sie uns für Ihren speziellen Fall durchgehen, was passiert. Wenn Sie einfach abrufen, müssen Sie lediglich Ihren Remote-Tracking-Zweig aktualisieren. Das funktioniert immer noch gut – es wird dich warnen, obwohl:

From <url>:
 + abc123...def456 master    -> origin/master  (forced update)

Ziehen

Ein Pull, egal ob normal (Merging) oder Rebasing, ruft intern fetch auf. So Wenn Sie noch nicht abgerufen haben, wird die Warnung “erzwungenes Update” angezeigt. Wenn Sie bereits abgerufen haben, wurde die Warnung vor erzwungenem Update zuvor ausgegeben, und es gibt jetzt kein erzwungenes Update, vor dem Sie warnen müssen. Sie könnten auch die Warnung zum erzwungenen Update verpassen, wenn im Rahmen der Zusammenführung danach ein großer Diff-Bericht vorliegt. Nach dem Abrufen ruft git-pull dann wie gewünscht merge oder rebase auf. Hier kommt es an Ja wirklich unheimlich. Was Git jetzt angeht, verpflichtet sich C und D sind jetzt nur lokale Commits. Es spielt keine Rolle, dass sie irgendwann veröffentlicht wurden. Git wird also wie gewohnt zusammenführen/rebasen.

Die Verschmelzung:

- A - B - L - M - N - O (origin/master)
                      
    C - D - X - Y - Z - Q (master)

Die Neuauflage:

 - A - B - L - M - N - O (origin/master) - C' - D' - X' - Y' - Z' (master)

Nun könnten beide sehr wohl in Konflikte geraten, wenn das Entfernen der Commits C und D die späteren Commits unterschiedlich macht. Zusammenführungskonflikte sind die einzigen anderen Fehler, die Sie bemerken würden. Aber wenn es vereinzelte Änderungen waren, dann geht alles “in Ordnung”. Wenn der Benutzer es nicht bemerkt, kann er diese Historie nachträglich pushen und so die entfernten Commits wieder einführen! Dies kann manchmal relativ harmlos sein. Vielleicht ist L tatsächlich C mit einem Tippfehler in der Commit-Nachricht, und MNO sind identisch mit DEF, nur mit anderen Eltern. Die Wiedereinführung von C und D würde also nichts weiter tun, als die Geschichte durcheinander zu bringen. Aber vielleicht ist es schrecklich gefährlich: Vielleicht hat das Entfernen von C einen schrecklichen Fehler behoben, und es wurde gerade wieder eingeführt.

Das Problem vermeiden

Und deshalb ist es a Ja wirklich schlechte Idee, die veröffentlichte Geschichte neu zu schreiben. Der beste Fall ist, dass am Ende einige duplizierte Commits auftreten, und der schlimmste Fall ist, dass ein Benutzer unwissentlich alles bricht. Wenn es also passiert, müssen Sie es als erstes sagen alle und weisen Sie sie an, wie sie sich erholen können. Als nächstes sollten Sie alles, was später veröffentlicht wird, wachsam überwachen, um sicherzustellen, dass die alten Commits nicht wieder eingeführt werden. Wenn Sie auf der anderen Seite sind und von einem öffentlichen Repository holen, vertrauen Sie den Betreuern hoffentlich genug, um den Stable-Zweig niemals neu zu basen oder Ihnen mitzuteilen, ob sie es tun. Wenn Sie ihnen nicht vertrauen, ist es eine gute Praxis, anstatt zu ziehen, zu holen und dann zusammenzuführen/zu rebasieren, damit Sie die Meldung “erzwungene Aktualisierung” bemerken und sehr vorsichtig vorgehen.

Lokal wiederherstellen

Die Details zur Wiederherstellung variieren; Ich empfehle die oben genannte Manpage. Es ist schwer zu sagen, was Sie genau tun müssen – es hängt davon ab, ob C in L (und vielleicht D in M) umgeschrieben wurde oder ob es sich um völlig neue Commits handelt und ob Sie ein Rebase oder Merge durchführen möchten. Wenn Sie nur ein Rebase durchführen möchten, reicht es aus, XYZ auf O umzubasieren. Wenn Sie zusammenführen möchten, würden Sie XYZ entweder auf B oder M umbasieren und dann O zusammenführen.

  • in Bezug auf das von Ihnen gepostete Zusammenführungsergebnisdiagramm: Sollte die Zusammenführungsbasis nicht sein? A-B statt nur A ?

    – Klick mich

    27. Februar ’17 um 17:09

1641934084 943 Wie gehen Sie mit einem bereits umbasierten offentlichen Repository um
VonC

Sie sollten tun (wie in “Wie kann ich wiederherstellen/resynchronisieren, nachdem jemand eine Rebase oder einen Reset auf einen veröffentlichten Branch verschoben hat?”):

git checkout yourBranch
git branch old-upstreamBranch D # BEFORE fetching!

           E--F (origin/upstreamBranch)
          /
A--B--C--D (old-upstreamBranch)
          
           X--Y--Z (yourBranch)


git fetch


     L--M--N--O (origin/upstreamBranch)
    /
A--B--C--D (old-upstreamBranch)
          
           X--Y--Z (yourBranch)

An diesem Punkt können Sie Ihren Zweig nicht einfach auf den neu geschriebenen stützen upstreamBranch: das würde C und D einführen, die explizit beiseite gelassen wurden, wenn upstreamBranch wurde umgeschrieben.

Du musst umbauen einfach yourBranch, und nicht die Commits davor.
Deshalb stellst du ein old-upstreamBranch Tag vor dem Abrufen:

git rebase --onto origin/upstreamBranch old-upstreamBranch yourBranch

                X--Y--Z (yourBranch)
               /
     L--M--N--O (origin/upstreamBranch)
    /
A--B--C--D (old-upstreamBranch)



git branch -D old-upstreamBranch 

                X--Y--Z (yourBranch)
               /
     L--M--N--O (origin/upstreamBranch)
    /
A--B

Aber: Mit Git 2.0 musst du nur noch:

fork_point=$(git merge-base --fork-point origin/upstreamBranch yourBranch)
# return D
git rebase --onto origin/upstreamBranch $fork_point yourBranch

Kein “Zweig machen” mehr Vor holen!

Wenn Sie das Problem erkennen nach git fetch, können Sie Ihren Zweig immer noch gut auf den neu geschriebenen Upstream-Zweig umbasieren.


Seit Commit ad8261d von John halten (johnkeeping), git rebase kann das gleiche neu gebrauchen --fork-point Möglichkeit.

.

387560cookie-checkWie gehen Sie mit einem bereits umbasierten öffentlichen Repository um?

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

Privacy policy