Git Pull führt zu irrelevanten "Merge Branch" -Nachrichten im Commit-Protokoll

110

Ich arbeite mit einem anderen Entwickler an einem Projekt und wir verwenden Github als Remote-Repo. Ich bin auf einem Mac mit Git 1.7.7.3, er ist auf Windows mit Git 1.7.6.

Das ist was passiert

  1. Einer von uns (nennen wir ihn Entwickler A, aber es spielt keine Rolle, welcher) sendet eine Reihe von Commits an GitHub.
  2. Der andere (Entwickler B) macht einige lokale Commits.
  3. B macht a git pull.
  4. B macht a git push.
  5. Wenn ich mir das Commit-Verlaufsprotokoll ansehe, sehe ich den Merge-Zweig 'master' von github.com:foo/bar

Das Festschreibungsprotokoll wird im Laufe der Zeit mit "Zweig zusammenführen" -Nachrichten übersät und zeigt Entwickler B als Festschreibungsänderungen an, die Entwickler A vorgenommen hat. Die einzige Möglichkeit, dieses Problem zu verhindern, bestand darin, eine git pull --rebasein Schritt 3 durchzuführen, aber ich weiß nicht, welche Nebenwirkungen eine Neufasierung mit sich bringen wird. Ich arbeite zum ersten Mal an einem Git-Repo für mehrere Entwickler. Ist das also nur normal? Irgendwelche Gedanken zur Lösung dieses Problems?

mshafrir
quelle
2
Sie können das Protokoll ohne Zusammenführung mitgit log --no-merges
wjandrea

Antworten:

88

Das Commit, das Sie sehen, ist vollkommen in Ordnung. A wird pulleffektiv ausgeführt, git fetchund dann git mergefindet normalerweise eine Zusammenführung statt, wenn Sie ausgeführt werden git pull.

Die Alternative, Rebasing anstelle von Zusammenführen zu verwenden, ist möglich, aber normalerweise sollten Sie dies vermeiden. Durch das erneute Basieren können Sie einen linearen Verlauf beibehalten, aber auch alle Informationen über die ursprünglich erfolgte Verzweigung entfernen. Dadurch wird auch der Verlauf des aktuellen Zweigs neu geschrieben, wodurch alle Commits neu erstellt werden, die nicht im Zielzweig enthalten sind (in Ihrem Fall die Fernbedienung). Da es sich bei den neu erstellten Commits um unterschiedliche Commits handelt, kann dies bei der Entwicklung zusammen mit anderen zu großer Verwirrung führen, insbesondere wenn Personen Teile dieser Commits bereits ausgecheckt haben, bevor sie neu geschrieben werden (z. B. mit Feature-Zweigen). Als Faustregel gilt, dass Sie niemals ein Commit umschreiben sollten , das bereits gepusht wurde.

Die angezeigten Commits dienen dazu, zwei (oder mehr) Zweige zu kombinieren. Es ist vollkommen in Ordnung, ein Commit zu haben, das nichts anderes tut, als mehrere Zweige zusammenzuführen. Tatsächlich wird sehr deutlich, wann Sie ein Zusammenführungs-Commit haben, das Zweige kombiniert, wenn Sie den Verlauf betrachten. Im Vergleich zur Neugründung können Sie durch das Zusammenführen auch den ursprünglichen Verlauf, wie er entwickelt wurde, einschließlich der tatsächlich existierenden Zweige effektiv anzeigen .

Also, lange Rede, kurzer Sinn: Ja, Merge-Commits sind vollkommen in Ordnung, und Sie sollten sich darüber keine Sorgen machen.

Sack
quelle
2
Sehr gute Antwort. Ich selbst habe den Rebase-Stil ausprobiert, da er in einigen Beitragsrichtlinien für Open-Source-Projekte empfohlen wurde und mir Probleme bereitete. Ein neues Mitglied im Team hatte das gleiche auch. Ich denke, die Rebase-Option ist nicht für Teams gedacht, die den ganzen Tag zusammenarbeiten, sondern für Projekte mit Hauptmitarbeitern und anderen Mitwirkenden, die nur Patches einreichen. Diese sollten in Ordnung sein, das Haupt-Repo abzurufen und ihre Änderungen kurz vor der Ausgabe einer Pull-Anfrage neu zu begründen.
Meligy
2
@sTodorov Wenn es keine neuen Änderungen gibt, führt der Abrufteil des Pulls nichts aus, aber die Zusammenführung wird noch ausgeführt. Wenn Ihre aktuelle lokale Niederlassung nicht auf dem neuesten Stand ist, werden die neuen Änderungen in Ihrer Niederlassung zusammengeführt. Und wenn es keine Schnellvorlauf-Zusammenführung durchführen kann (wenn Sie unterschiedliche Commits haben), wird ein Zusammenführungs-Commit erstellt.
Poke
28
Diese Antwort lässt den Eindruck entstehen, dass die Verwendung von Rebase, wie vom OP beschrieben, gefährlich ist, aber nicht. Das Wiederherstellen in Schritt 3 schreibt nicht den gesamten Verlauf neu. Nur die lokalen Commits, die nicht übertragen wurden, werden neu geschrieben, indem sie erneut auf den neuen HEAD angewendet werden (das letzte Commit, das an diesen Zweig gesendet wurde). Dies verhindert das Festschreiben von Fremdzusammenführungen und hat keine weiteren Nebenwirkungen.
Bob Esponja
1
@bobesponja Alle Commits, die sich nicht im gezogenen Remote-Zweig befinden, werden neu geschrieben. Dies kann veröffentlichte Commits aus anderen Zweigen umfassen, z. B. mit Feature-Zweigen, auf die andere möglicherweise bereits zuvor zugegriffen haben. Als solches ist es etwas gefährlich, neu zu gründen, ohne darüber nachzudenken, was Sie neu gründen.
Poke
1
@bobesponja Ja, wenn Sie Ihren Feature-Zweig frühzeitig veröffentlichen (weil andere daran arbeiten oder einfach als Backup), sollten Sie ihn nicht neu starten, da andere ihn möglicherweise bereits abgerufen haben. Ein erneutes Basieren - wie Sie selbst sagen - widerspricht den Richtlinien, die ich in meiner Antwort angegeben habe. Wenn Sie Ihre Commits jedoch nicht veröffentlichen, ist eine Neubasierung in Ordnung, wenn Sie möchten und den linearen Verlauf nicht stören. Aber es hängt davon ab, wie Sie arbeiten. Die allgemeine Antwort lautet, dies zu vermeiden, es sei denn, es ist wirklich sicher. Übrigens. Ich habe meine Antwort überarbeitet. Wenn das Problem behoben ist, würde ich mich freuen, wenn Sie Ihre Ablehnung entfernen würden.
stupsen
48

Diese Antwort wurde überarbeitet, da mein Verständnis, meine Diagramme und Schlussfolgerungen falsch waren.


git pullVerursacht Zusammenführungs-Commits, da Git zusammengeführt wird. Dies kann geändert werden, indem Sie Ihre Zweige so einstellen, dass Rebase anstelle von Merge verwendet wird. Die Verwendung von Rebase anstelle von Merge bei einem Pull bietet einen lineareren Verlauf für das gemeinsam genutzte Repository. Auf der anderen Seite zeigen Merge Commits die parallelen Entwicklungsbemühungen in der Branche.

Beispielsweise arbeiten zwei Personen in derselben Branche. Der Zweig beginnt als:

...->C1

Die erste Person beendet ihre Arbeit und drängt in die Filiale:

...->C1->C2

Die zweite Person beendet ihre Arbeit und möchte pushen, kann dies aber nicht, da sie aktualisiert werden muss. Das lokale Repository für die zweite Person sieht folgendermaßen aus:

...->C1->C3

Wenn der Pull auf Zusammenführen eingestellt ist, sieht das Repository für zweite Personen so aus.

...->C1->C3->M1
      \      /
       ->C2->

Wobei M1 ein Merge-Commit ist. Diese neue Filialhistorie wird in das Repo verschoben. Wenn stattdessen der Pull so eingestellt ist, dass das lokale Repo neu gestartet wird, sieht dies folgendermaßen aus:

...->C1->C2->C3

Es gibt kein Zusammenführungs-Commit. Die Geschichte wurde linearer gestaltet.

Beide Auswahlmöglichkeiten spiegeln die Geschichte der Branche wider. Mit git können Sie auswählen, welchen Verlauf Sie bevorzugen.

Es gibt in der Tat Orte, an denen eine erneute Basis ein Problem mit Remote-Zweigen verursachen kann. Dies ist nicht einer dieser Fälle. Wir bevorzugen die Verwendung von rebase, da dies einen bereits komplizierten Zweigverlauf vereinfacht und eine Version des Verlaufs relativ zum gemeinsam genutzten Repository anzeigt.

Sie können branch.autosetuprebase = festlegen, damit git Ihre Remote-Zweige immer automatisch als Rebase anstelle von Master einrichtet.

git config --global branch.autosetuprebase always

Diese Einstellung bewirkt, dass git automatisch eine Konfigurationseinstellung für jeden Remote-Zweig erstellt:

branch.<branchname>.rebase=true

Sie können dies selbst für Ihre Remote-Zweige festlegen, die bereits eingerichtet sind.

git config branch.<branchname>.rebase true

Ich möchte @LaurensHolst dafür danken, dass er meine vorherigen Aussagen hinterfragt und weiterverfolgt hat. Ich habe sicherlich mehr darüber gelernt, wie Git mit Pull- und Merge-Commits funktioniert.

Weitere Informationen zu Zusammenführungs-Commits finden Sie unter Beitrag zu einem Projekt in ProGit-Book . Im Abschnitt " Privates kleines Team " werden Zusammenführungs-Commits angezeigt.

Bill Door
quelle
7
„Die Verwendung von Rebase anstelle von Merge bei einem Pull liefert den korrekten Verlauf für das gemeinsam genutzte Repository. Die Verwendung von Merge liefert einen falschen Verlauf. “ - Was ist der Grund für diese ziemlich kühne Aussage? Eine Geschichte mit Zusammenführungen ist auf keinen Fall "falsche Geschichte". Es ist eine genaue Darstellung der Reihenfolge, in der die Dinge passiert sind. Was Sie durch Umbasieren tun, ist, die Geschichte tatsächlich zu ändern , um eine etwas linearere Version davon zu erstellen. Sie opfern Genauigkeit für Ästhetik. Vielleicht etwas, das Sie lieber tun, aber keineswegs wahrer.
Laurens Holst
2
Die Verwendung von Rebase anstelle von Merge beeinträchtigt nicht die Genauigkeit für die Ästhetik. Wir verwenden --no-ff für Zusammenführungen, daher ist Ästhetik keine Voraussetzung. Genauigkeit ist ein Wunsch. Rebase bietet diese Genauigkeit.
Bill Door
2
Wie ist die neu basierte Geschichte genauer? Sie klären das nicht und ich sehe nicht, wie es sein würde.
Laurens Holst
1
Die Geschichte spiegelt die Zeit wider, zu der Commits im Shared Repo stattfanden. Eines Tages 1 sah das Shared Repo Commit C2. Am zweiten Tag sieht das Shared Repo Commit C3. Wenn C3 vor C2 kommen würde, wäre die Reflexion der Zeit nicht korrekt. C3 kam nicht vor C2. Alles, was neu erstellt wird, ist, die Commits im lokalen Repository neu zu organisieren, um den vom freigegebenen Repository angezeigten Verlauf korrekt wiederzugeben .
Bill Door
6
Ihre Fragen veranlassten mich, mein Verständnis von Merge Commits zu überprüfen. Mein Diagramm ist falsch. Ich überarbeite die Diskussion. Meine Schlussfolgerungen sind auch falsch. Der Verlauf für Rebase und Merge ist gleichermaßen korrekt. Sie können Ihre eigene Wahl treffen.
Bill Door
11

Du kannst tun:

git pull --rebase

Dadurch werden Ihre Änderungen jedoch immer über die Ihrer Mitarbeiter gestellt. Sie erhalten jedoch keine verschmutzende Zusammenführungsnachricht.

gaborous
quelle
9

Darauf gibt es tatsächlich eine viel einfachere Antwort. Lassen Sie Entwickler B einfach ziehen, bevor Sie sich verpflichten. Dadurch werden diese Zusammenführungs-Commits verhindert, da sie durch den Verlauf verursacht werden, den Sie in Ihrem lokalen Repo aus Ihrem lokalen Commit erstellt haben und der versucht, mit dem Verlauf der Commits auf dem Remote-Repo zusammenzuführen. Wenn Sie beim Ziehen eine Meldung erhalten, die besagt, dass Änderungen überschrieben werden, bedeutet dies nur, dass Sie beide dieselbe Datei berührt haben. Gehen Sie also wie folgt vor:

git stash
git pull
git stash pop

Anschließend können Sie etwaige Zusammenführungskonflikte lösen.

Luke
quelle
Am nervigsten und ängstlichsten sind genau Zusammenführungskonflikte. Ich vermeide es lieber
Green
1
@Green Wenn du dir Sorgen über Zusammenführungskonflikte machst, ist auch Git Pull nicht anders.
Zoso
Außer das eine Mal, wenn du es stashvor dir vergisst pull. Ugh git erfordert, dass ich die ganze Zeit an der Spitze meines Spiels bin.
LinuxNoob
Need to git pull --rebaseremote Änderungen vor den auf lokaler Ebene zu integrieren, und zwar unabhängig.
vonbrand
7

Wenn Sie einen Git-Pull ausführen, werden die Nachrichten "Zweig zusammenführen" eingefügt. Genau das ist der Fall. Durch Ausführen eines Git-Pulls haben Sie den Remote-Zweig mit Ihrem lokalen Zweig zusammengeführt.

Wenn Sie einen Git-Pull ausführen und Konflikte auftreten, werden im Git-Protokoll die Aktualisierungen der Konfliktdateien als von dem Benutzer stammend angezeigt, der die Konflikte gelöst hat. Ich gehe davon aus, dass die Person, die den Konflikt behebt, die Datei erneut festschreibt.

Soweit ich weiß, funktioniert Git genau so, und daran führt kein Weg vorbei.

Durch das erneute Basieren wird der Git-Verlauf weggeblasen, sodass Sie nicht sehen können, wann Zusammenführungen stattgefunden haben.

kclair
quelle