Verwenden von git zum Zusammenführen von zwei Verzeichnissen mit einem gemeinsamen übergeordneten Element (aber unterschiedlichem SHA1)

Lesezeit: 4 Minuten

Verwenden von git zum Zusammenfuhren von zwei Verzeichnissen mit einem
HNygard

In unserem Projekt hat jemand eine Kopie des Codes gemacht. Sie starteten ein neues Git-Repository in ihrem Verzeichnis und setzten dort ihre Arbeit fort. Inzwischen wurde auch an unserem Hauptprojekt-Repository weitergearbeitet. Wir haben jetzt zwei Git-Repositories ohne gemeinsames SHA1.

A --- B --- C --- D
      |
      | Copy of code to new directory
      |
      E --- F --- G

B und E sind exakt die gleichen Dateien, Ordner usw.

Unser Ziel ist es, mit Git die Änderungen F und G im Hauptzweig zusammenzuführen (derzeit bei D)

1641964219 4 Verwenden von git zum Zusammenfuhren von zwei Verzeichnissen mit einem
Dietrich Epp

Zuerst werde ich Ihr Diagramm neu zeichnen.

A --- B --- C --- D  master

         E --- F --- G  copy

Lassen Sie uns zuerst beide in das gleiche Repo legen. Dafür gibt es keine besonderen Schritte, du musst nur git fetch beide in das gleiche Repository.

Dann erstellen Sie ein Transplantat. Bearbeiten .git/info/grafts

<E-sha1> <B-sha1>

Dann renne git filter-branch um es dauerhaft zu machen.

git filter-branch --tag-name-filter cat -- --all

Dadurch wird eine neue Historie erstellt, die “richtige” Historie:

A --- B --- C --- D  master
        
         E --- F --- G  copy

Danach können Sie einfach zusammenführen.

Demo in Aktion

Ich habe zwei Repositorys erstellt, die dem Diagramm entsprachen, und von Commit B kopiert, um Commit E zu machen.

  • E hat SHA-1 3aa6b69127d20ac42746c39be3c273a9d80fb706
  • B hat SHA-1 95b0fc836dbea7eaa0d043390df841d184af7cd5
$ git init
$ git remote add master ../gittest
$ git remote add copy ../gittest2
$ git fetch master
remote: Counting objects: 12, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 12 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (12/12), done.
From ../gittest
 * [new branch]      master     -> master/master
$ git checkout -b master master/master
Branch master set up to track remote branch master from master.
Already on 'master'
$ git fetch copy
warning: no common commits
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 9 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
From ../gittest2
 * [new branch]      master     -> copy/master
$ git log --format=oneline copy/master | tail -n 1
3aa6b69127d20ac42746c39be3c273a9d80fb706 E
$ git log --format=oneline master/master
1532332fe705931babe9db04c8d84051867b52c9 D
90903c0ac8dc26649b875ee00ea39bfd7571b1fb C
95b0fc836dbea7eaa0d043390df841d184af7cd5 B
e9de90c82a32041cff3a19f8e40d4358bc4ec2ca Commit A
$ git log --format=oneline master/master
bec0e7af9374e4c57cb87f3fd5b2fb2b6a3f431b G
a61e01d096e81c36bcc450afd98ca94cff909622 F
3aa6b69127d20ac42746c39be3c273a9d80fb706 E

Was passiert, wenn Sie jetzt zusammenführen?

Ich habe Zusammenführungskonflikte, die ich lieber automatisch auflösen würde.

$ git merge copy/master
Auto-merging test.txt
CONFLICT (add/add): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.

Transplantate in Aktion

$ echo 3aa6b69127d20ac42746c39be3c273a9d80fb706 
    95b0fc836dbea7eaa0d043390df841d184af7cd5 > .git/info/grafts
$ git filter-branch --tag-name-filter cat -- --all
Rewrite bec0e7af9374e4c57cb87f3fd5b2fb2b6a3f431b (7/7)
WARNING: Ref 'refs/heads/master' is unchanged
Ref 'refs/remotes/copy/master' was rewritten
WARNING: Ref 'refs/remotes/master/master' is unchanged
$ git merge copy/master
Auto-merging test.txt
Merge made by the 'recursive' strategy.
 test.txt |    5 +++++
 1 file changed, 5 insertions(+)

Das Endergebnis

$ git log --graph --oneline | cat
*   4dadb0a Merge remote-tracking branch 'copy/master'
|  
| * bb2fc85 G
| * be88bc5 F
| * 0816baf E
* | 1532332 D
* | 90903c0 C
|/  
* 95b0fc8 B
* e9de90c Commit A

  • Großartig, das erzeugt ein schönes Protokoll. Und +1 für deine Lösung.

    – pktangyue

    10. Januar ’13 um 9:31


Angenommen, Sie befinden sich jetzt im Repo-Include A---B---C---D.

Sie müssen zuerst das andere Repository zu diesem Repository hinzufügen, indem Sie den Befehl verwenden.

$git remote add another_repo <git repo path>
$git fetch another_repo

Dann können Sie zusammenführen, verwenden

$git merge another_repo/master

  • Warte… wird das nicht zu vielen Zusammenführungskonflikten führen?

    – Dietrich Epp

    10. Januar ’13 um 8:59

  • Dadurch werden im Konfliktfall viele geänderte Dateien angezeigt, jedoch nicht mehr Konflikte als beim normalen Zusammenführen.

    – pktangyue

    10. Januar ’13 um 9:01


  • Aber es sollte Konflikte geben… weil sie keine gemeinsame Geschichte haben

    – Dietrich Epp

    10. Januar ’13 um 9:01

  • @DietrichEpp:Die meisten werden automatisch per Git zusammengeführt, da der Inhalt der meisten Dateien gleich ist.

    – pktangyue

    10. Januar ’13 um 9:02


  • Ich habe es als Experiment ausprobiert und habe in jeder berührten Datei in beiden Repos Zusammenführungskonflikte festgestellt.

    – Dietrich Epp

    10. Januar ’13 um 9:09


.

419520cookie-checkVerwenden von git zum Zusammenführen von zwei Verzeichnissen mit einem gemeinsamen übergeordneten Element (aber unterschiedlichem SHA1)

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

Privacy policy