git: can I subtree merge just a subpath of a repository? git: can I subtree merge just a subpath of a repository? git git

git: can I subtree merge just a subpath of a repository?


I've successfully done this using the following commands (rewritten for your scenario).

$ git remote add Bar /path/to/bar$ git merge -s ours --no-commit Bar/master$ git read-tree --prefix=public/bar -u Bar/master:www/tools/

HUGE WARNING! I'm still in the process of figuring out how to do fetch/merge from Bar. This will bring in everything just once.

My current way of merging changes is like so:

$ get fetch Bar$ git pull -X subtree=public/bar Bar master

This will leave you with conflicts saying that a ton of files have been removed, you can just git rm them and then git commit.

I'm certainly open to suggestions on a better way to pull changes.

Since this is an old thread, I should add that I'm running Git 1.7.9.


Try using git subtree for this. It allows you to extract a subtree of a project into another project, which you can then merge into yours.


Edit: It occurs to me that you could do this just with git merge --no-commit. This will attempt the merge, and even if it does not conflict, it will stop just before committing. At this point you can remove all the junk you don't need (including restoring conflicted files if necessary) and create a merge commit only containing the desired subtree.

Original answer:

You can indeed use filter-branch for this. An outline:

Clone your source repo:

git clone --bare /path/to/bar /path/to/bar_clone

Using a bare clone will save you the time and space of creating a working directory.

Next, use filter-branch on the clone:

git filter-branch --index-filter 'git rm -rf <unwanted files/directories>' -- --all

The --all lets it know that you want to use all refs, not just the current HEAD. You will now have a repository containing only the desired subdirectory, and all of the history associated with it.

Note: Sorry, I don't know a really straightforward way to remove all but what you want. You have to be careful with wildcards because you don't want to clobber any git directories. Here's something that'll work, though it's slower, especially if you've got a lot of files:

git filter-branch --index-filter 'git rm -f `git ls-files | grep -v ^www/tools`' -- --all

Anyway, however you manage the listing of files to remove, you can go ahead with your subtree merge, pulling from bar_clone into foo.