79

I have a folder in my Git repository that I'd like to move out in to its own repository. Is it possible to move the history of that folder along with the folder?

I've previously been doing just a git rm -r --cached subfolder/ and then git init on the subfolder. However, the history is not imported in to the new repository.

matpie
  • 17,033
  • 9
  • 61
  • 82
  • 2
    Similar to, or duplicate of: http://stackoverflow.com/questions/811251/how-can-i-move-a-single-directory-from-a-git-repository-to-a-new-repository-whil – Adam Monsen Nov 01 '11 at 23:21
  • Possible duplicate of [How can I move a single directory from a git repository to a new repository whilst maintaining the history?](http://stackoverflow.com/questions/811251/how-can-i-move-a-single-directory-from-a-git-repository-to-a-new-repository-whil) – Evandro Coan May 04 '17 at 19:00

2 Answers2

107

Quoting an example from git-filter-branch(1)

To rewrite the repository to look as if foodir/ has been its project root, and discard all other history:

git filter-branch --subdirectory-filter foodir -- --all

Thus you can, e.g., turn a library subdirectory into a repository of its own. Note the -- that separates filter-branch options from revision options, and the --all to rewrite all branches and tags.

Joel Purra
  • 24,294
  • 8
  • 60
  • 60
jamessan
  • 41,569
  • 8
  • 85
  • 85
  • 51
    Just make sure to run this on a clone of the original repository, as it wipes the rest of the repo. – bobDevil Nov 02 '09 at 18:30
  • Amazing! I couldn't understand that option without a working example. Thanks! – matpie Nov 02 '09 at 19:19
  • Also, thanks to @bobDevil for the heads up. I pushed all my changes to my remote /before/ trying this, so I'd be safe if it wiped my repo; but it would certainly be unexpected. – matpie Nov 02 '09 at 19:21
  • 7
    You'd expect the resulting clone to be smaller when you only keep one directory's history, but more work is necessary. The easiest way to shrink it after doing filter-branch is to clone again. See the git-filter-branch(1) manpage for details ("CHECKLIST FOR SHRINKING A REPOSITORY"). – Adam Monsen Nov 01 '11 at 22:42
  • 4
    @AdamMonsen: you can do `git gc` instead of cloning the repo. – David Jan 14 '16 at 03:17
  • To clone the local directory `git clone original_repo foodir` – Chris Aug 02 '18 at 18:28
  • See below for an updated answer, as core git team strongly disagrees with this method – 128KB Feb 15 '23 at 21:37
23

For anyone else arriving here in 2021 (or later), git filter-branch is not strongly recommended by the core git team.

WARNING git filter-branch has a plethora of pitfalls that can produce non-obvious manglings of the intended history rewrite (and can leave you with little time to investigate such problems since it has such abysmal performance). These safety and performance issues cannot be backward compatibly fixed and as such, its use is not recommended. Please use an alternative history filtering tool such as git filter-repo. If you still need to use git filter-branch, please carefully read SAFETY (and PERFORMANCE) to learn about the land mines of filter-branch, and then vigilantly avoid as many of the hazards listed there as reasonably possible.

Instead the recommended tool is git-filter-repo which makes easy work of this problem

git filter-repo --path subfolder/   # Filter the repo to just the sub-dir
git mv subfolder/* .                # Move the contents of the sub-dir to the root
git commit -m "Filtered from main repo"
Jamie Cook
  • 4,375
  • 3
  • 42
  • 53
  • You can even merge it into a single step: `git filter-repo --path subfolder/ --path-rename 'subfolder/':''` – Gabriel Nov 12 '21 at 09:29
  • 1
    Using `--path-rename 'subfolder':''` didn't work for me. Instead I used this command to filter and rename in one step: `git filter-repo --subdirectory-filter subfolder/` – Corey Jun 03 '22 at 11:53