2010-02-19 11 views
9

Vorrei suddividere i moduli distribuiti con un'applicazione più grande in sottomoduli separati e mantenere la possibilità di eseguire il pull up da monte.Uso ripetuto di git-filter-branch per riscrivere nuovi commit

Quindi questo è più complesso di Detach subdirectory into separate Git repository. Non ho solo usato git-filter-branch una volta ma voglio mantenere la possibilità di effettuare modifiche upstream dopo averlo fatto (e l'upstream non lo ha fatto).

È sufficiente rieseguire il ramo git-filter nella cronologia completa da ora in upstream, inclusi i nuovi commit non trovati nella cronologia riscritta, non è un'opzione in quanto vi sono centinaia di moduli per i quali devo eseguire questa operazione e il numero di commit è avvicinarsi a 100.000.

Immagino che ciò implichi limitare la cronologia solo ai nuovi commit, riscrivendoli e quindi aggiungendoli dopo i commit precedentemente riscritti, ma non sono sicuro di come farlo - e forse c'è un approccio migliore.

Sarebbe bello poter conservare anche i rami e le etichette, ma questo non è assolutamente necessario e se complica le cose in realtà preferirei perdere quelle.

+0

mi piacerebbe anche sapere di questo. Ogni volta che richiamo un repository di dipendenze, devo eseguire di nuovo il filtro-ramo per unire gli aggiornamenti nel mio progetto (non voglio unire l'intero repo in). –

+0

Sono rimasto sorpreso dal fatto che nessuno abbia avuto una risposta, dopo tutto sembra una sfida interessante. Bene, ho fatto qualcosa insieme ma ho dimenticato di postarlo qui. Il tuo interesse mi ha ricordato: qui sotto è la mia soluzione. – tarsius

+2

Hai mai guardato [* git subtree *] (http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt)? Può suddividere una sottostruttura in un nuovo ramo e, con l'opzione '--rejoin', farlo in modo incrementale. –

risposta

8

Per la prima rebase fare questo:

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

E per "fondere" più avanti commette:

# 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 
Problemi correlati