Distilled from a question thread (which I found a little too confusing) on Stack Overflow. matli writes:
Just to make it clear, I have the following structure:
XYZ/ .git/ XY1/ ABC/ XY2
But I would like:
XYZ/ .git/ XY1/ XY2/ ABC/ .git/
See the original thread for details.
Backup
XYZ
. I use rsync, just to spread my risk around, but you cangit clone
if you prefer.rsync -ahz --progress XYZ/ XYZ.git.bak/
Create the repository you want to be
ABC
-only by cloning it fromXYZ
.git clone --no-hardlinks XYZ ABC
In
ABC
, remove all history outside theABC
hierarchy.git filter-branch --subdirectory-filter ABC HEAD -- --all
Clean up references…
git remote rm origin git update-ref -d refs/original/refs/heads/master
…and then objects.
git reset --hard git reflog expire --expire=now --all git gc --aggressive git prune git repack -ad
In
XYZ
, remove all history belonging to theABC
hierarchy.git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ABC" --prune-empty HEAD
Alternatively, if you’re not worried about
ABC
’s history cluttering upXYZ
, just delete theABC
hierarchy and commit.git rm -rf ABC git commit
Clean up: repeat Step 5 in
XYZ
.