I've a git repo, say repoA, with many subdirs. How can I detach one of the sub-directories, say dir1, and add it to another repo as a separate branch (with history)?
Secondly, how can I remove the history of the detached subdir from the repoA?
I've a git repo, say repoA, with many subdirs. How can I detach one of the sub-directories, say dir1, and add it to another repo as a separate branch (with history)?
Secondly, how can I remove the history of the detached subdir from the repoA?
How can I detach one of the sub-directories, say dir1, and add it to another repo as a separate branch (with history)?
git checkout -b tempBranch
git filter-branch --subdirectory-filter dir1 --prune-empty
In a second repository:
git remote add filtered_dir1 ../original_repo
git fetch filtered_dir1
git merge filtered_dir1/tempBranch
Secondly, how can I remove the history of the detached subdir from the repoA?
$ git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch dir1" --prune-empty
This might fail with a warning about being unable to make a backup; I'm not sure what this is about, but adding -f
will force git-filter-branch
to run anyway.
This will run in the current branch only. If you want to run it on all branches, append -- --all
. Note the -- --all
.
Some notes:
When running git filter-branch
, you will filter the branch you're on. (Rather obviously, if you think about it). If you're trying to extract some history to push into a second repository, you probably want to git filter-branch
on a new branch, so that the original repository doesn't lose anything.
This question has some useful information in it.
git filter-branch --subdirectory-filter
will make subdirectory
the new root directory of the branch - it will move files from subdirectory
to /
. To fix this, there's an example at the bottom of the EXAMPLES
section from man git-filter-branch
:
To move the whole tree into a subdirectory, or remove it from there:
git filter-branch --index-filter \
'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD