547 Stimmen

Was ist die genaue Bedeutung von "unser" und "ihr" in Git?

Dies klingt vielleicht wie eine zu grundlegende Frage, aber ich habe nach Antworten gesucht und bin jetzt mehr verwirrt als zuvor.

Was bedeuten "ours" und "theirs" in git, wenn ich meinen Branch in meinen anderen Branch integriere? Beide Branches sind "ours".

Bei einem Mergekonflikt ist "ours" immer die obere der beiden angezeigten Versionen?

Bezieht sich "ours" immer auf den Branch, auf den HEAD zeigte, als der Merge begonnen wurde? Wenn ja, warum nicht eine klare possessive Bezugnahme wie "current branch's" verwenden, anstatt ein besitzanzeigendes Pronomen wie "ours" zu verwenden, das referentiell mehrdeutig ist (da beide Branches technisch gesehen uns gehören)?

Oder verwenden Sie einfach den Branch-Namen (statt "ours" zu sagen, sagen Sie einfach "local master's" oder ähnliches)?

Der verwirrendste Teil für mich ist, wenn ich in einer bestimmten Branches .gitattributes-Datei spezifiziere. Angenommen, in test branch habe ich folgende .gitattributes-Datei:

config.xml merge=ours

Jetzt wechsle ich den Branch und zeige HEAD auf master an, dann führe ich test zusammen. Da master 'ours' ist und die .gitattributes von test nicht ausgecheckt ist, wird es überhaupt eine Auswirkung haben? Wenn ja, da master jetzt "uns gehört", was wird passieren?

562voto

torek Punkte 381305

Ich vermute, dass du hier verwirrt bist, weil es grundsätzlich verwirrend ist. Um die Dinge noch schlimmer zu machen, wird das ganze "unser/ihre" Zeug vertauscht (wird umgekehrt), wenn du ein Rebase durchführst.

Letztendlich, während eines git merge, bezieht sich der "unser" Branch auf den Branch, den du zusammenführst in:

git checkout merge-into-ours

und der "ihr" Branch bezieht sich auf den (einzigen) Branch, den du zusammenführst:

git merge from-theirs

und hier ergibt "unser" und "ihr" schon Sinn, denn obwohl "ihr" höchstwahrscheinlich sowieso deiner ist, ist "ihr" nicht der, auf dem du warst, als du git merge ausgeführt hast.

Obwohl die Verwendung des tatsächlichen Branch-Namens ziemlich cool sein könnte, funktioniert es in komplexeren Fällen nicht. Beispielsweise könntest du anstelle des obigen folgendes tun:

git checkout ours
git merge 1234567

wo du durch eine rohe Commit-ID zusammenführst. Schlimmer noch, du könntest sogar das hier tun:

git checkout 7777777    # HEAD abkoppeln
git merge 1234567       # einen Test-Merge durchführen

in diesem Fall sind keine Branch-Namen involviert!

Ich glaube, das hilft wenig hier, aber tatsächlich kannst du mit der gitrevisions-Syntax in einem Konflikt-Merge auf einen individuellen Pfad im Index durch Nummer verweisen

git show :1:README
git show :2:README
git show :3:README

Phase #1 ist der gemeinsame Vorgänger der Dateien, Phase #2 ist die Ziel-Branch-Version und Phase #3 ist die Version, von der du zusammenführst.


Der Grund, warum die "unser" und "ihr" Bezeichnungen während eines rebase vertauscht werden, ist, dass Rebase durch eine Serie von Cherry-Picks funktioniert, in einem anonymen Branch (entkoppelter HEAD-Modus). Der Ziel-Branch ist der anonyme Branch und der Merge-From-Branch ist dein originaler (vor dem Rebase) Branch: also bedeutet "--ours" der anonyme, den Rebase erstellt, während "--theirs" "unser Branch, der rebased wird" bedeutet.


Was den Eintrag in den gitattributes betrifft: Er könnte eine Auswirkung haben: "unser" bedeutet intern wirklich "Phase #2 verwenden". Aber wie du bemerkt hast, ist er zu diesem Zeitpunkt nicht tatsächlich vorhanden, also sollte er hier keine Auswirkung haben... es sei denn, du kopierst ihn vor dem Start in das Arbeitsverzeichnis.

Außerdem, übrigens, das gilt für alle Verwendungen von unser und ihr, einige sind auf Dateiebene (-s unser für eine Merge-Strategie; git checkout --ours während eines Merge-Konflikts) und manche sind auf Stück-für-Stück-Basis (-X unser oder -X ihr während eines -s rekursiven Merges). Das trägt wahrscheinlich nicht zur Aufklärung bei.

Ich habe nie einen besseren Namen für diese gefunden. Und: siehe VonCs Antwort auf eine andere Frage, wo git mergetool noch mehr Namen für diese einführt und sie "lokal" und "remote" nennt!

178voto

Nitay Punkte 3693

Ich weiß, dass dies bereits beantwortet wurde, aber dieses Problem hat mich so oft verwirrt, dass ich eine kleine Referenzwebsite erstellt habe, um mir zu helfen, mich zu erinnern: https://nitaym.github.io/ourstheirs/

Hier sind die Grundlagen:

Zusammenführungen:

$ git checkout master 
$ git merge feature

Wenn Sie die Version in master auswählen möchten:

$ git checkout --ours codefile.js

Wenn Sie die Version in feature auswählen möchten:

$ git checkout --theirs codefile.js

Neu-Basis:

$ git checkout feature 
$ git rebase master 

Wenn Sie die Version in master auswählen möchten:

$ git checkout --ours codefile.js

Wenn Sie die Version in feature auswählen möchten:

$ git checkout --theirs codefile.js

(Dies gilt natürlich für vollständige Dateien)

83voto

kenorb Punkte 134883

Das 'ours' in Git bezieht sich auf den Original-Arbeitszweig, der den maßgeblichen/kannonischen Teil der Git-Historie hat.

Das 'theirs' bezieht sich auf die Version, die die Arbeit hält, um neu zu basieren (Änderungen zur Wiedergabe auf dem aktuellen Zweig).

Dies kann für Personen, die nicht wissen, dass das Durchführen von Rebase (z.B. git rebase) tatsächlich bedeutet, dass Ihre Arbeit aufgehalten wird (was theirs ist), um auf die kanonische/Haupt-Historie gespielt zu werden, die ours ist, verwirrend erscheinen, weil wir unsere Änderungen als Arbeit von Drittanbietern neu basieren.

Die Dokumentation für git-checkout wurde in Git >=2.5.1 gemäß dem f303016 Commit weiter verfeinert:

--ours --theirs

Beim Überprüfen von Pfaden aus dem Index wird Stufe #2 ('ours') oder #3 ('theirs') für nicht zusammengeführte Pfade überprüft.

Beachten Sie, dass während git rebase und git pull --rebase 'ours' und 'theirs' vertauscht erscheinen können; --ours gibt die Version aus dem Zweig an, auf den die Änderungen neu basiert werden, während --theirs die Version aus dem Zweig angibt, der Ihre Arbeit hält, die neu basiert wird.

Dies liegt daran, dass rebase in einem Workflow verwendet wird, der die Historie im Remote als die gemeinsame kanonische betrachtet und die Arbeit auf dem Zweig, den Sie neu basieren, als Arbeit von Drittanbietern zur Integration betrachtet, und dass Sie vorübergehend die Rolle des Hüters der kanonischen Historie während des Rebase einnehmen. Als Hüter der kanonischen Historie müssen Sie die Historie aus dem Remote als ours betrachten (d.h. "unsere gemeinsame kanonische Historie"), während das, was Sie auf Ihrem Seitenzweig getan haben, als theirs betrachtet wird (d.h. "die Arbeit eines Mitwirkenden darauf").

Für git-merge wird es folgendermaßen erklärt:

ours

Diese Option zwingt konfliktierende Stücke, sauber durch Bevorzugung unserer Version, auto-aufzulösen. Änderungen vom anderen Baum, die nicht mit unserer Seite in Konflikt stehen, werden im Zusammenführungsergebnis widergespiegelt. Für eine Binärdatei werden die gesamten Inhalte von unserer Seite übernommen.

Dies sollte nicht mit der ours-Merge-Strategie verwechselt werden, die überhaupt nicht darauf schaut, was der andere Baum enthält. Es verwirft alles, was der andere Baum getan hat, und erklärt, dass unsere Historie alles enthält, was darin passiert ist.

theirs

Dies ist das Gegenteil von ours.

Darüber hinaus wird hier erklärt, wie man sie verwendet:

Der Zusammenführungsmechanismus (git merge und git pull Befehle) erlaubt die Auswahl der Backend-Zusammenführungsstrategien mit der -s Option. Einige Strategien können auch ihre eigenen Optionen haben, die durch die Angabe von -X Argumenten an git merge und/oder git pull übergeben werden können.


Also kann es manchmal verwirrend sein, zum Beispiel:

  • git pull origin master wobei -Xours unser lokaler, -Xtheirs ihr (Remote-)Zweig ist
  • git pull origin master -r wobei -Xours ihr (Remote-), -Xtheirs unser Zweig ist

Das zweite Beispiel ist also das Gegenteil des ersten, da wir unseren Zweig auf dem Remote-Zweig neu basieren, also ist unser Ausgangspunkt der Remote-Zweig, und unsere Änderungen werden als extern behandelt.

Gleiches gilt für git merge Strategien (-X ours und -X theirs).

34voto

Kamafeather Punkte 6892

Ich weiß, das erklärt nicht die Bedeutung, aber ich habe mir selbst ein kleines Bild gemacht, als Referenz, um mich daran zu erinnern, welches verwendet werden soll:

Bildbeschreibung eingeben

Hoffe, es hilft!

PS - Schau dir auch den Link in Nitays Antwort an

25voto

Mecki Punkte 113876
  • Unsere: Dies ist der Zweig, auf dem Sie sich aktuell befinden.
  • Ihre: Dies ist der andere Zweig, der bei Ihrer Aktion verwendet wird.

Wenn Sie sich also auf dem Zweig release/2.5 befinden und den Zweig feature/new-buttons in diesen zusammenführen, bezieht sich der Inhalt, wie er in release/2.5 gefunden wird, auf unsere und der Inhalt, wie er in feature/new-buttons gefunden wird, auf Ihre>. Während einer Zusammenführungsaktion ist dies ziemlich einfach.

_

Das einzige Problem, dem die meisten Leute zum Opfer fallen, ist der Rebase-Fall. Wenn Sie einen Rebase anstelle einer normalen Zusammenführung durchführen, werden die Rollen vertauscht. Wie kommt das? Nun, das liegt ausschließlich an der Arbeitsweise des Rebasens. Denken Sie beim Arbeiten mit dem Rebasen daran:

  1. Alle Commits, die Sie seit Ihrem letzten Pull durchgeführt haben, werden in einen eigenen Zweig verschoben, nennen wir ihn ZweigX.
  2. Sie checken den Kopf Ihres aktuellen Zweigs aus, verwerfen alle lokalen Änderungen, die Sie hatten, und stellen so alle Änderungen wieder her, die von anderen für diesen Zweig gepusht wurden.
  3. Nun werden alle Commits auf ZweigX nacheinander von alt nach neu in Ihren aktuellen Zweig übernommen.
  4. ZweigX wird erneut gelöscht und taucht daher nie in einer Historie auf.

Natürlich ist das nicht wirklich das, was passiert, aber es ist ein gutes mentales Modell für mich. Und wenn Sie sich Punkte 2 und 3 ansehen, werden Sie verstehen, warum die Rollen jetzt vertauscht sind. Ab Punkt 2 ist Ihr aktueller Zweig nun der Zweig vom Server ohne jede Ihrer Änderungen, also ist dies unsere (der Zweig, auf dem Sie sich befinden). Die Änderungen, die Sie vorgenommen haben, befinden sich nun auf einem anderen Zweig, der nicht Ihr aktueller ist (ZweigX) und daher sind diese Änderungen (obwohl es die Änderungen sind, die Sie vorgenommen haben) Ihre (der andere für Ihre Aktion verwendete Zweig).

Das bedeutet, wenn Sie zusammenführen und Ihre Änderungen immer gewinnen sollen, sagen Sie Git immer "unsere" zu wählen, aber wenn Sie einen Rebase durchführen und Ihre Änderungen immer gewinnen sollen, sagen Sie Git immer "Ihre" zu wählen.

_

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X