2010-10-28 10 views
50

Ho un progetto sotto git. Un giorno ho spostato tutti i file di progetto dalla directory corrente a foo/bar/ nell'ambito del progetto. L'ho fatto usando git mv. Poi ho aggiunto altri file e ho apportato alcune modifiche ai file già esistenti.Come posso riscrivere la cronologia in modo che tutti i file, ad eccezione di quelli che ho già spostato, si trovino in una sottodirectory?

Come risultato, ora quando guardo la cronologia di foo/bar/file.c, posso vedere solo le modifiche che ho fatto dopo aver spostato il file.

Ho provato a risolvere questo problema in vari modi (filter-branch con filtro sottodirectory, ecc.), Ma nulla ha aiutato, quindi sono abbastanza impilati qui. Apprezzerò qualsiasi aiuto tu possa darmi. Grazie!

risposta

85

Per riscrivere la storia con i file spostati:

Se si desidera la storia del progetto a guardare come se tutti i file sono sempre stati nella directory foo/bar, allora avete bisogno di fare un po 'di un intervento chirurgico. Utilizzare git filter-branch con il "filtro ad albero" per riscrivere i commit in modo tale che nessuna parte foo/bar non esiste, viene creato e tutti i file vengono spostati ad esso:

git filter-branch --prune-empty --tree-filter ' 
if [ ! -e foo/bar ]; then 
    mkdir -p foo/bar 
    git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files foo/bar 
fi' 

Ora la storia verrà registrato come se tutti i file sono stati sempre situato in foo/bar.

di vedere la storia di un file spostato:

Se si desidera solo per vedere la storia di un file che è stato spostato o rinominato ad un certo punto nel passato, quindi è sufficiente utilizzare l'opzione --follow a git log:

git log --follow foo/bar/file.c 
+1

@Alexander: Si consiglia di provare a inserire l'one-liner (tutto nelle virgolette singole) in uno script effettivo, con una riga di shebang bash. Penso che 'filter-branch' stia probabilmente cercando di eseguirlo in' sh', non 'bash'. – Cascabel

+0

Ho fatto dei progressi. Sembra che le parentesi doppie in istruzione if stessero causando questo errore. Le singole parentesi funzionano meglio, ma non funziona comunque. Il problema è che prima di spostare tutto su foo/bar/avevo una directory chiamata foo con qualche contenuto nel progetto. Così ora si lamenta "non è possibile spostare' foo 'in una sottodirectory di se stesso, 'foo/bar/foo'". –

+0

@Alexander: dovrai solo adattare lo script di conseguenza. Qualcosa come: 'if [[! -e foo/bar]]; quindi mkdir -p foo/bar; git ls-tree --name-only $ GIT_COMMIT | grep -v^pippo $ | xargs -I file mv file foo/bar; fi' Questo usa grep per filtrare 'foo' dall'elenco di file da spostare. Nota che suppongo anche che la sottodirectory 'bar' non sia mai esistita finché non hai spostato tutto sotto di essa. Se questo non è il caso, dovrai anche tenerne conto nello script. –

6

Per avvolgere le cose ecco un breve riassunto di quello che ho fatto. Il comando che ha funzionato per me è stato:

if [ ! -e foo/bar ]; then mkdir -p foo/bar; git ls-tree --name-only $GIT_COMMIT | grep -v ^foo$ | xargs -I files mv files foo/bar || echo ""; fi 

Il comando echo che ho aggiunto alla fine assicurato che anche quando fallisce mv intero comando continuerà a funzionare. Non ha spostato il contenuto di foo/bar/foo, ma posso conviverci.

Grazie mille a Dan Moulding (!!!) e Jefromi per l'aiuto.

Problemi correlati