2016-10-10 6 views
1

Vor einer Woche habe ich einen Zustand 'Ceph-ansible' Ordner in% current% Zweig mit Code aus entsprechenden Zweig zurückgesetzt (die eine stromaufwärts von Github verfolgt):'git merge -s Teilbaum' funktioniert nicht korrekt

# git read-tree --prefix=ceph-ansible/ -u ceph_ansible 

Dann habe ich begangen mehrere Änderungen, einschließlich:

  1. umbenannte Datei und commited:

    # git mv site.yml.sample site.yml 
    
  2. einige Änderungen vorgenommen und engagiert

  3. Pulled Updates von Original Zweig von:

    # git merge -s subtree --squash ceph_ansible 
    

Es wird gesagt:

Auto-Fusion Ceph-ansible/site.yml.sample

blablabla

Squash-Commit - keine Aktualisierung HEAD

Automatische Zusammenführung ging gut; gestoppt, bevor wie gewünscht zu begehen

Ich kann „my“ Ceph-ansible/site.yml (sowie einige neue Dateien von mir hinzugefügt) sehen, dass gelöscht wird, wird Ceph-ansible/site.yml.sample restauriert und enthält meine Änderungen nicht (es wird gerade in den Zustand vor meinen Änderungen wiederhergestellt).

git log ceph_ansible site.yml.sample zeigt 26. August 2016 (= letzte Änderungen ceph-ansible Zweig), meine Änderungen in% aktuelle% Zweig war in diesem Oktober, so sollte es auch keinen Konflikt sein.

Ich glaube, dass es eine offensichtliche Erklärung für dieses Verhalten gibt. Kannst du mir bitte helfen?

UPDATE: Ich habe bemerkt, dass mein Git ist ziemlich alt (1.8.3) und baute es aus Quell-Tarball (2.10.1). Jetzt ist die Ausgabe:

# ~/gitbuild/git-2.10.1/git merge -s subtree --squash ceph_ansible 
fatal: refusing to merge unrelated histories 

Eine schnelle googeln zeigte (Git refusing to merge unrelated histories), dass das Standardverhalten geändert wird. Das Hinzufügen von'allow-unrelated-histories 'löscht die Fehlermeldung, aber die Zusammenführung selbst ist immer noch falsch (meine Änderungen sind verloren).

Diese Fehlermeldung könnte erklären, warum git es nicht richtig zusammenführen kann (da diese Repos keine Relationen haben, richtig). Kann das bitte jemand bestätigen? "Merge -s subtree" führt Zweige nicht wirklich zusammen?

+1

Jemand (oder etwas anderes) machte die Löschungen und Änderungen. Stellen Sie sich das umgekehrt vor: Angenommen, Sie haben eine Reihe von Änderungen an einer Datei vorgenommen und dann eine PR erstellt. Nachdem Sie diese PR abgeschlossen haben, möchten Sie, dass das, was Sie getan haben, im Zielzweig widergespiegelt wird. Nun, in diesem Fall wurde jemandes Wunsch wahr, aber er gehörte nicht dir. –

+0

@TimBiegeleisen, danke für schnelle Antwort! Das kann es perfekt erklären, aber wie ich schrieb 'git log ceph_ansible site.yml.sample' zeigt mir nichts im Oktober. Wie kann ich deine Idee beweisen? –

+1

Während der Zusammenführung wurde ein Teil Ihrer Arbeit zugunsten der Version aus dem anderen Zweig verworfen. Zumindest würde ich dies so erklären (ich bin bereit, falsch zu liegen). –

Antwort

0

ich diese Frage zu Git Mailingliste gepostet haben und paar nette Personen gab mir eine ausgezeichnete Erklärung für dieses Verhalten:

Wenn Sie von ceph_ansible verschmelzen, gibt es keine gemeinsame Geschichte, und git verwendet die leerer Baum als gemeinsamer Vorfahre.

Ich denke, vielleicht sind Sie nicht vollständig verstehen, was die --squash Flagge tut ... das ist, was hier das Problem verursacht, nicht die -s Option.

Ein Squash merge nimmt die Commits, die vom Ursprung Zweig zusammengeführt werden würde und quetscht sie zu einem einzigen Fleck und wendet sie auf den Stromzweig als ein neuen begehen ... aber diese neuen begehen ist keine merge commit (das heißt, wenn man es mit "git show" etc. anschaut) hat das Commit nur einen Elternteil, nicht zwei - oder mehr - Eltern wie einen normalen Merge Commit.

Grundsätzlich ist es syntaktischer Zucker für eine diff plus Patch-Operation plus einige Git-Güte darum gewickelt, um es einfacher zu bedienen.

Aber schließlich, wenn Sie fertig sind, hat Git keine Ahnung, dass dieses neue Commit irgendeine Beziehung zum Ursprungszweig hat. So die nächste Zeit, die Sie zusammenführen, Git weiß nicht, dass es eine vorherige Zusammenführung und es wird versuchen, alles von Grund auf neu zu verschmelzen, anstatt bei der vorherigen gemeinsamen Zusammenführungspunkt zu beginnen.

Also entweder es einen normalen, nicht-Squash Druck verwenden muß, oder, wenn man nicht die ceph_ansible Geschichte in Ihrem Projekt tragen will, Sie brauchen die ursprüngliche Upstream begeht irgendwo aufzuzuzeichnen (wahrscheinlich in der Commit-Nachricht, wenn Sie das Lese-Baum-Ergebnis festschreiben), und dann fragen Git , dass als Merge-Basis während nachfolgender Zusammenführungen verwenden ( erfordern Verwendung von Sanitär-Codes, wie Git-Merge die Zusammenführung berechnen) Basis selbst).

Der git subtree Befehl (von contrib) erlaubt noch eine weitere Möglichkeit: es squashes Geschichte des fusionierten Teilprojekt (als ob mit interaktiven rebase 'Squash'), dann ist diese Squash verschmilzt begehen.