2010-02-19 4 views
9

Ich möchte Module, die mit einer größeren Anwendung verteilt sind, in separate Submodule aufteilen und die Fähigkeit beibehalten, von Upstream zu ziehen. Dies ist komplexer als Detach subdirectory into separate Git repository. Ich habe nicht nur den git-filter-branch einmal benutzt, sondern möchte auch die Möglichkeit behalten, Upstream-Änderungen zu ziehen, nachdem ich das getan habe (und upstream nicht).Wiederholte Verwendung von git-filter-branch zum Neuschreiben neuer Commits

Einfach nochmal gunn-filter-branch über den gesamten Verlauf von upstream laufen lassen, inklusive neuer Commits, die nicht in meiner neu geschriebenen History gefunden wurden, ist keine Option, da es Hunderte von Modulen gibt, für die ich dies tun muss fast 100.000 erreichen.

Ich vermute, dies beinhaltet die Begrenzung der Geschichte auf nur die neuen Commits, neu zu schreiben und dann nach den zuvor neu geschriebenen Commits, aber ich bin mir nicht sicher, wie dies zu tun - und vielleicht gibt es einen besseren Ansatz.

Es wäre schön, wenn Zweige und Tags auch beibehalten werden könnten, aber das ist nicht absolut notwendig und wenn es Dinge kompliziert, würde ich eigentlich lieber diese verlieren.

+0

ich auch darüber wissen möchten. Jedes Mal, wenn ich ein Abhängigkeits-Repo abrufe, muss ich den Filter-Zweig erneut ausführen, um die Aktualisierungen in mein Projekt einzufügen (ich möchte den gesamten Repo nicht zusammenführen). –

+0

Ich war überrascht, dass niemand auf eine Antwort kam, immerhin saum es wie eine interessante Herausforderung. Nun, ich habe selbst etwas zusammengehackt, aber vergessen es hier zu posten. Ihr Interesse hat mich daran erinnert - unten ist meine Lösung. – tarsius

+2

Haben Sie schon mal [* git subtree *] (http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt) angeschaut? Es kann einen Teilbaum in einen neuen Zweig aufteilen und mit der Option '--rejoin' inkrementell machen. –

Antwort

8

Zum ersten rebase dies zu tun:

git checkout -b rebased master 
git filter-branch --some-filter 
git tag rebased-done master 

Und zu "verschmelzen" später verpflichtet:

# Create a tempory branch and rebase it's tail use 'rebase-done~' 
# and not 'rebase-done' because some filters (like --index-filter) 
# require this, others might not. 
git checkout -b rebased-tail master 
git filter-branch -f --some-filter -- rebased-done~..HEAD 

# Get the commit in branch 'rebased' corresponding to tag 'rebase-done' 
# (which tags a commit in 'master' not 'rebased'). Depending on your 
# situation you might have to determine this commit differently (in my 
# use case I am absolutely sure that there is never a commit with the 
# same author date - if that doesn't work you might want to compare 
# commit messages). 
start_time=$(git show --quiet --pretty=%at rebased-done) 
start_hash=$(
git log --reverse --pretty="%H %at" rebased_tail | 
while read hash time 
do 
    [ "$time" = "$start_time" ] && echo $hash && break 
done 
) 

# Finally apply the rebased commits. 
git checkout rebased 
git format-patch -k --stdout $start_hash..rebased-tail | git am -k 
git branch -D rebased-tail 
git tag -f rebased-done master 
Verwandte Themen