Merge disjoint branches with git
My current situation
I have 2 git repositories of the same software project, where one is the fork of the other:
fork: A1 - B1 - C1 - ... - HEAD_FORK : (Some changes done outside of git) : orig: A2 - B2 - C2 - D2 - E2 - ... - HEAD_ORIGINAL
These two histories are completely disjoint, they share no common commit. (as far as git is concerned)
- Git: Deciding between branches and multiple repositories
- “git reset --hard HEAD” in master branch deleted unstaged changes in local branch
- Version control setup for a tutorial
- Is it possible to see if a forced push was done on a git enabled tfs repository?
- Using Git and Dropbox together effectively?
- How can I configure git on a server with a development and production branch?
However based on the timestamps and the fact that I know that fork was forked from orig (not using a VCS, but the usual dirty “just copy the files and create a new repository” way) I can find a point of “minimal difference” between the two:
A1 is based on D2 minus some files.
Merge this mess. I want fork with all the useful changes from orig after the fork.
I don’t care about the history of orig. One large commit on fork would be fine. (I could split and refactor that anyway)
My current battle plan
I already have a git repository which contains both histories as branches. What I plan to do:
Create a branch orig-old where D2 is HEAD and a branch fork-old where A1 is HEAD.
fork-old: A1 <- HEAD_FORK-OLD : : orig-old: A2 - B2 - C2 - D2 <- HEAD_ORIG-OLD
Merge fork-old and orig-old creating common-old
fork-old: A1 <- HEAD_FORK-OLD : \ common-old: : A3 <- HEAD_COMMON-OLD : / orig-old: A2 - B2 - C2 - D2 <- HEAD_ORIG-OLD
Rebase fork on common-old
fork: B1 - C1 - D1 - .... - HEAD_FORK / common-old: A3 <- HEAD_COMMON-OLD / orig-old: A2 - B2 - C2 - D2 <- HEAD_ORIG-OLD
Rebase orig on fork
orig: E2 - F2 - ... - HEAD_ORIG / fork: B1 - C1 - D1 - .... - X1 <- HEAD_FORK / common-old: A3 <- HEAD_COMMON-OLD
Merge the rebased orig using merge –squash onto fork.
orig: E2 - F2 - ... - K2 <- HEAD_ORIG / \ fork: B1 - C1 - D1 - .... - X1 -------------- M1 <- HEAD_FORK
Create a diff between the new HEAD of fork M1 and the old head (the HEAD of the forked repository) and apply it to the forked repository.
Did anyone here try to do something similar and has some experience if that will work?
Since we are taking about quite a large undertaking here (multiple days at least), it would be nice to know if my plan is insanity before I start to merge all this.
I also considered just copying everything from orig and paste it over the files in fork
and then selectively add changes with “git add –patch” but I think for that there are just to much complex changes.
Thanks in advance!
One Solution collect form web for “Merge disjoint branches with git”
It sounds like git-graft may help. Basically it allows you to manually stitch history.
Here are couple of articles describing details procedure:
If you add a graft to make A1 a descendant of D2, git merge may do a passable job merging in the rest of the changes. If there’s substantial difference between A1 and D2, you may first do
git merge -s ours A1 to tell git that those differences should be considered merged so they would not get in the way when you do
git merge HEAD_FORK
git merge -s ours A1 you may not need any grafts at all as that fake merge will join the histories of two branches, though not at the exact point in history. Should not make much of a difference considering that there were no other merges across branches.