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:


But I would like:


See the original thread for details.

  1. Backup XYZ. I use rsync, just to spread my risk around, but you can git clone if you prefer.

     rsync -ahz --progress XYZ/ XYZ.git.bak/
  2. Create the repository you want to be ABC-only by cloning it from XYZ.

     git clone --no-hardlinks XYZ ABC
  3. In ABC, remove all history outside the ABC hierarchy.

     git filter-branch --subdirectory-filter ABC HEAD -- --all
  4. Clean up references…

     git remote rm origin
     git update-ref -d refs/original/refs/heads/master
  5. …and then objects.

     git reset --hard
     git reflog expire --expire=now --all
     git gc --aggressive
     git prune
     git repack -ad
  6. In XYZ, remove all history belonging to the ABC 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 up XYZ, just delete the ABC hierarchy and commit.

     git rm -rf ABC
     git commit
  7. Clean up: repeat Step 5 in XYZ.