2

I have a git repository containing a fork of project foo:

origin/master
+src/
|  +foo/
|     +A/
|     +B/
|     +C/
+stuff/

I also have a mirror of project foo:

upstream/master
+foo/
   +A/
   +B/
   +C/

I do not yet have in git a common ancestry. I would like to both establish a common ancestry to make future merges easier and merge in any changes from the upstream foo that have been made since I forked.

I attempted to rebase my changes to foo on top of the upstream:

C:\src>git rebase -s recursive -X subtree=foo/ --root upstream/master

But, that did not work the way I desired. I ended up with origin/master looking exactly like upstream/master with none of my changes included and completely missing stuff.

origin/master
+foo/
   +A/
   +B/
   +C/

What do I need to do to merge upstream foo with my src/foo?

Am I limited to doing something like this?

C:\src>git merge upstream/master -s recursive -X subtree=foo/
PaulH
  • 7,759
  • 8
  • 66
  • 143
  • Just to be clear, it looks like your fork has added a layer of nesting to the directory structure. Is this correct? – merlin2011 Feb 06 '15 at 18:38
  • Yes. The `foo` sub directory in `origin/master` is based on the root of `upstream/master`. – PaulH Feb 06 '15 at 19:36

1 Answers1

2

My suggestion would be to use a git filter-branch to rewrite upstream as if foo/ had been src/foo/ from the start. Based on https://stackoverflow.com/a/3212697/54249:

git filter-branch --commit-filter '
    TREE="$1";
    shift;
    SUBTREE=`echo -e 040000 tree $TREE"\tsrc" | git mktree`
    git commit-tree $SUBTREE "$@"' -- --all

That should give us:

upstream/master
+src/
   +foo/
      +A/
      +B/
      +C/

At this point you should be able to simply merge upstream/master into origin/master, giving a git log --oneline --graph --decorate that looks something like this:

*    (HEAD, master) Merge branch 'master' of upstream
|\
| *  (upstream/master) fourth upstream commit
| *  third upstream commit
* |  (origin/master) fourth origin commit
| *  second upstream commit
* |  third origin commit
| *  first upstream commit
*    second origin commit
*    first origin commit

Here's a proof of concept for a pair of local repositories - note the git pull reports "warning: no common commits": Proof of Concept

Community
  • 1
  • 1
dahlbyk
  • 75,175
  • 8
  • 100
  • 122