Move subdirectory to new git repo (preserve history)

git_logo_compI was about to branch a subdirectory within one of my GitHub projects as a new project. I realized that I’ll lose all revision history which I wanted to avoid for obvious reasons. I found a discussion thread on Stack Overflow to achieve this. Here’s the simplified procedure with explanation for each step.

Let’s say the source repository has the structure:

     |_ dir1
     |_ dir2
     |_ targetdir
     |_ file1
     |_ file2

Our target repo:

     |_ targetdir

As you can understand, the goal is to bring targetdir (along with full revision history) under repository target from repository source.

Move subdir to new repo

  1. Clone the source repository under directory source
    $ git clone source_repo_URL source
  2. Move into source
    $ cd source
  3. Remove all content within source other than targetdir and bring targetdir contents directly within source
    $ git filter-branch --subdirectory-filter targetdir -- --all
  4. Create the directory targetdir
    $ mkdir targetdir
  5. Move files within source into targetdir (the command works because moving the directory into itself fails)
    $ mv * targetdir/
  6. Add the new structure to version control
    $ git add . --all
  7. Make sure that all the new files (within targetdir) are ready for commit (redundant)
    $ git status
  8. Commit the changes locally (NO git push…)
    $ git commit -a -s
  9. Move up, check out the target repo and move into it
    $ cd ..
    $ git clone target_repo_URL target
    $ cd target
  10. Add the local source directory as remote for target with branch name source_branch
    $ git remote add source_branch ../source/
  11. Merge changes from master branch of source into source_branch
    $ git pull source_branch master
  12. Unlink source as remote
    $ git remote rm source_branch
  13. Check your commit history (redundant)
    $ sudo apt-get install tig
    $ tig
  14. Push the changes to target repo’s origin
    $ git push origin master

Detach a fork from original repo

There might be situations where you’ld want to continue developing a fork as a separate project. You need a mirror repository with commit history preserved. Here are the steps:

  1. Clone the full git history of the source fork and move into it
    $ git clone --bare source_repo_URL
    $ cd source.git
  2. Create a new empty repo (say target) on the server (e.g. GitHub) and make it a mirror of the source repo
    $ git push --mirror target_repo_URL

Leave a Reply

Your email address will not be published. Required fields are marked *