Un modo per fare ciò è l'inverso: rimuovere tutto tranne il file che si desidera conservare.
Fondamentalmente, fare una copia del repository, quindi utilizzare git filter-branch
per rimuovere tutto tranne il file/le cartelle che si desidera conservare.
Per esempio, ho un progetto da cui vorrei estrarre il file tvnamer.py
ad un nuovo repository:
git filter-branch --tree-filter 'for f in *; do if [ $f != "tvnamer.py" ]; then rm -rf $f; fi; done' HEAD
che utilizza git filter-branch --tree-filter
a passare attraverso ogni commit, eseguire il comando e reimpegnarci il contenuto delle directory risultante . Questo è estremamente distruttivo (quindi dovresti farlo solo su una copia del tuo repository!), E può impiegare un po '(circa 1 minuto su un repository con 300 commit e circa 20 file)
Il comando precedente esegue solo il comando seguente shell script su ogni revisione, che si sarebbe necessario modificare naturalmente (per farla escludere vostro sub-directory invece di tvnamer.py
):
for f in *; do
if [ $f != "tvnamer.py" ]; then
rm -rf $f;
fi;
done
Il più grande problema evidente è che lascia tutti messaggi di commit, anche se non sono collegati al file rimanente. Lo script git-remove-empty-commits, risolve questo ..
git filter-branch --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "[email protected]"; else git commit-tree "[email protected]"; fi'
È necessario utilizzare la forza -f
argomento run filter-branch
di nuovo con qualcosa in refs/original/
(che fondamentalmente un backup)
Naturalmente questo non sarà mai perfetta, ad esempio, se i tuoi messaggi di commit menzionano altri file, ma è più vicino possibile a una corrente di git (per quanto ne sappia comunque).
Ancora, eseguirlo sempre su una copia del repository! - ma in sintesi, per rimuovere tutti i file, ma "thisismyfilename.txt":
git filter-branch --tree-filter 'for f in *; do if [ $f != "thisismyfilename.txt" ]; then rm -rf $f; fi; done' HEAD
git filter-branch -f --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "[email protected]"; else git commit-tree "[email protected]"; fi'
Anche una buona risposta: http://stackoverflow.com/questions/359424/detach-subdirectory-into-separate-git-repository –