2

There are several subtrees in my repo (e.g. ./sub1/, ./sub2/, ..) which I would like to extract into separate repos, keeping commit history and the same dir structure, i.e. a new repo for sub1 should have ./sub1/ subtree from the main repo. How can I do this?

1 Answer 1

5

You can use git's filter-branch with subtree filter.

Here are the steps:

  1. Clone a working copy. This operation will alter local repo, so we must have a working copy first. You can either do a git clone as below or just copy it.

    git clone --no-hardlinks <original repository> <working copy> 
  2. Use subtree fileter.

    cd <working copy> git filter-branch --subdirectory-filter <subdir path to be splited> --prune-empty --tag-name-filter cat -- --all # reset current working directory git reset --hard 
  3. We have accomplished our task, it is better to do some cleaning work, because lots of old objects became unreachable.

    1. Delete old remote

      git remote rm origin 
    2. Remove old reflog

      # clean unneeded reflog in order to free space refbak=$(git for-each-ref --format="%(refname)" refs/original/) if [ -n "$refbak" ];then echo -n $refbak | xargs -n 1 git update-ref -d fi git reflog expire --expire=now --all 
    3. Repack and compress the repo

      # prune loose objects git gc --aggressive --prune=now 

This will make the repos structure change from

repo/ |-- sub1/ |-- sub11 |-- sub12 |-- sub2 

to

repo/ |-- sub11 |-- sub12 

But, it seems you want it to became

repo/ |-- sub1/ |-- sub11 |-- sub12 

Then, there is one more step need to be done, rewrite the git commit history with index-filter.

# replace <subdir path> with the actual subdir path, for this case, it should be "sub1" git filter-branch --index-filter 'git ls-files -s | sed "s-\t-&<subdir path>/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.