tags:

views:

200

answers:

3

I am currently working on a project using svn (server is version 1.4 which means no modern merge tools available).

I want to merge a branch with quite a few weeks of work in it. The problem is that back when the branch was created, it was made as a copy only of a subfolder.

Svn structure of project:

/trunk/folder1
              /file1
              /file2
       folder2
       folder3
       ...

Now I'm struggling to merge a branch back into trunk.

Now the problem is that the guy that created the branch only copied /trunk/folder1 and not the entire trunk. This creates a problem for git-svn, as it thinks that I created a bunch of files in the folder.

 git co master
 git merge branch1
 ...
 create mode 100644 trunk/file1
 create mode 100644 trunk/file2

(assuming that the files were originally in /trunk/folder1/file1)

The original reason i'm not using svn for this, is because of too many conflickts. (svn merge requires server 1.5+ and we're only on 1.4, svnmerge.py can only merge small chunks at a time and requires a LOT of mental overload ... i have used a half day to get only half way through)

Using git merge seems promising, but at first I need to tell git to use a subfolder of my master branch as merge target. How is that done?

A: 

For a one-off solution, I'd take that annoying "subfolder branch" in my local git repo's working copy, branch off a temporary working branch ("tmp-subdir") for safety, and then use git filter-branch on that working branch to move all its files into the proper place.

As that is probably lacking the rest of "trunk"'s files, I'd then branch off trunk ("tmp-trunk"), and replay/cherry-pick all the changesets from "tmp-subdir" onto "tmp-trunk".

Then it should be possible to merge that with "trunk".

This should work, but probably someone will come up with a one-liner to achieve the same thing. :-)

ndim
Interesting strategy. But a key issue is how to use `git filter-branch` to move all files into a subdirectory
Jesper Rønn-Jensen
With the `--tree-filter` option and some shell script magic. But you'll certainly be better off using [Jörg's `git merge -s subtree` one-liner](http://stackoverflow.com/questions/1783876/how-to-git-merge-a-branch-that-only-contains-a-subfolder-of-trunk/1785690#1785690).
ndim
+4  A: 

The subtree merge strategy was created specifically for this use case. It looks for files in the remote branch that match files in a subdirectory in the local branch, and if it does find them, it rewrites all the paths to make the two directory structures match up, before invoking the "normal" recursive merge strategy.

So, try

git merge -s subtree branch1
Jörg W Mittag
Thanks, but trying this command directly on master branch just creates files (as I described in my question). How do I tell git which directory to use?
Jesper Rønn-Jensen
This seems to work (when applied from master's /folder1). I'm still missing to dcommit back to svn, but the git merge runs really, really fast
Jesper Rønn-Jensen
+1  A: 

It looks like you need to use subtree merge strategy.

For first merge, take a look at the following references:

Or use git-subtree tool by Avery Pennarun, mentioned on InterfacesFrontendsAndTools page on Git wiki.

For subsequent merges it should be enough to specify subtree merge strategy:

$ git pull -s subtree <remote>

or

$ git merge -s subtree <branch>
Jakub Narębski