2013-04-11 9 views
5

Ich habe zwei Git Repos, die Gabeln voneinander sind und ich muss gelegentlich Commits von einem zum anderen importieren.Wie kann ich git Patches nur für Commits generieren/anwenden, die bestimmte Dateien ändern

Zum Beispiel:

git-repo1 hat diese Verzeichnisstruktur:

repo1/project1/src

repo1/project2/src

während git-repo2 hat die folgende Verzeichnisstruktur:

repo2/src/

Ich möchte eine Reihe von Commits machen und Patches nur für Commits generieren, die Dateien innerhalb eines bestimmten Unterverzeichnisses ändern (zB) und alle Commits ignorieren, die nur irgendwo anders Dateien ändern.

Oder alternativ Patches für alle Commits generieren, aber nur das Patch anwenden, wenn es Dateien in einem bestimmten Verzeichnis ändert.

Ich muss die Metadaten über die Commits beibehalten, so dass das Spielen mit git diff nicht als eine praktikable Option scheint.

Die Verzeichnisstruktur zwischen den gegabelten Git-Repos ist unterschiedlich.

Gibt es einen einfachen Weg, dies zu tun?

UPDATE1

Ich sehe diese Frage (How to apply a git patch from one repository to another?) in Bezug auf den Umgang mit Strukturen Verzeichnis unterscheiden.

Aber was, wenn der Patch davon spricht, Dateien zu modifizieren, die einfach nicht existieren? Ich würde solche Änderungen gerne ignorieren.

Antwort

9

git rev-list --reverseseries-- repo1/project1/src/ \
| xargs [email protected] git format-patch --stdout @^! >mystuff.patch

werden die Commits in Serie spucken, die beeinflussen, dass Unterverzeichnis in mystuff.patch

Dann

cat >mystuff.sed <<\EOD 
/^(From [0-9a-f]{40}|diff --git)/!{H;$!d} 
x 
/^From /b 
${h;s,.*--,--,;x} 
\,^diff[^\n]* [ab]/repo1/project1/src/,!{$!d;x;b} 
${p;x} 
EOD 

und

sed -Ef mystuff.sed mystuff.patch >justmystuff.patch 

entfernt alle Hunks außerhalb dieses Verzeichnisses. Sie können mit

git am justmystuff.patch 

mit -pn und --directory=new/path/to wie gewünscht anwenden.

(edit: EOD -> \ EOD so über die Katze versucht nicht zu ersetzen)

+0

Bei Verwendung des Befehls "sed -rf mystuff.sed mystuff.patch> justmystuff.patch" Ich bekomme den Fehler "sed: illegale Option - r" Haben Sie eine Idee, was es sein könnte? –

+0

Verwenden '- E 'statt, '-r' ist jetzt eine historische Schreibweise. In der Antwort behoben, danke. – jthill

+1

Es wäre nett, wenn Sie eine Erklärung auf Ihrem sed Skript geben können! – Neil

1

Wenn die beiden Repositorys einen gemeinsamen Verlauf haben (sie sind beide aus demselben Repository gespalten, haben sich aber anders entwickelt), könnten Sie cherry-picking verwenden, um selektiv Commits von einem Zweig in einen anderen zu importieren.

erstellen ein lokales Repository mit zwei Fernbedienungen (Ihre zwei divergierende Repositories)

Commits in repositoryA finden, die bestimmte Dateien

$ git checkout repoA/master 
$ git log sub/dir/ectory 
a34256f ... 

herauspicken diese Festschreibungen in den Zweig der repositoryB

berühren
git checkout repoB/master 
git cherry-pick a34256f 
+0

Nein, leider nicht eine Geschichte, die sie teilen. :( – EMiller