git subtree - Detach (move) subdirectory into separate Git repository -


i have git repository contains number of subdirectories. have found 1 of subdirectories unrelated other , should detached separate repository.

how can while keeping history of files within subdirectory?

i guess make clone , remove unwanted parts of each clone, suppose give me complete tree when checking out older revision etc. might acceptable, prefer able pretend 2 repositories doesn't have shared history.

just make clear, have following structure:

xyz/     .git/     xy1/     abc/     xy2/ 

but instead:

xyz/     .git/     xy1/     xy2/ abc/     .git/     abc/ 

update: process common, git team made simpler new tool, git subtree. see here: detach (move) subdirectory separate git repository


you want clone repository , use git filter-branch mark subdirectory want in new repo garbage-collected.

  1. to clone local repository:

    git clone /xyz /abc 

    (note: repository cloned using hard-links, not problem since hard-linked files not modified in - new ones created.)

  2. now, let preserve interesting branches want rewrite well, , remove origin avoid pushing there , make sure old commits not referenced origin:

    cd /abc in branch1 br2 br3; git branch -t $i origin/$i; done git remote rm origin 

    or remote branches:

    cd /abc in $(git branch -r | sed "s/.*origin\///"); git branch -t $i origin/$i; done git remote rm origin 
  3. now might want remove tags have no relation subproject; can later, might need prune repo again. did not , got warning: ref 'refs/tags/v0.1' unchanged tags (since unrelated subproject); additionally, after removing such tags more space reclaimed. apparently git filter-branch should able rewrite other tags, not verify this. if want remove tags, use git tag -l | xargs git tag -d.

  4. then use filter-branch , reset exclude other files, can pruned. let's add --tag-name-filter cat --prune-empty remove empty commits , rewrite tags (note have strip signature):

    git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter abc -- --all 

    or alternatively, rewrite head branch , ignore tags , other branches:

    git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter abc head 
  5. then delete backup reflogs space can reclaimed (although operation destructive)

    git reset --hard git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d git reflog expire --expire=now --all git gc --aggressive --prune=now 

    and have local git repository of abc sub-directory history preserved.

note: uses, git filter-branch should indeed have added parameter -- --all. yes that's dash dash space dash dash all. needs last parameters command. matli discovered, keeps project branches , tags included in new repo.

edit: various suggestions comments below incorporated make sure, instance, repository shrunk (which not case before).


Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -