I need to merge two git repositories by rebasing the root of the second repository onto the head of the first one.
While doing so, it should keep:
- the commit history
- all author dates + names
- all tags
- unmerged (feature) branches
- merged branches
- the two repositories have common files (same file name) and the content was changed in both repos
How can I achieve this?
This only needs to be done once and I don't need to keep the second repository after the merge.
Note: You can use the linked repositories to test your solution.
Here's an example:
merge-test-first:
My first (examplary) repository looks like this (https://github.com/Pro/merge-test-first):
* fcc6649 (HEAD -> master) J1
| * ba0ecb9 (branch_I1) K1
|/
* 91bf6a4 I1
* acacd68 (tag: tag_H1) H1
|\
| * 40bf845 (branch_B1) F1
| * 3ea2925 D1
* | 3780004 G1
| | * f7a61eb (branch_D1) E1
| |/
| * aae948d C1
|/
* 739d400 B1
* 6717e64 A1
(Output of git log --oneline --abbrev-commit --all --graph --decorate --color
)
It contains a branch (branch_B1
) with base B1
and then merged into master as H1
and two branches branch_D1
, branch_I1
merge-test-second:
The second repository, which should be merged and then rebased onto merge-test-first/master/HEAD
has some similar structure (https://github.com/Pro/merge-test-second):
* 28e726a (HEAD -> master) I2
|\
| * 46f9d71 (branch_D2) G2
* | 2ae8b4d H2
| | * 606a346 (branch_E2, tag: tag_F2) F2
| |/
| * bed8db1 E2
|/
* e94c6d7 (tag: tag_D2) D2
| * 8a98058 (branch_B2) C2
|/
* 82cb3ee B2
* 1b12fdf A2
Final result should be:
A2
from the second repo should be rebased onto J1
from the first repo, including all the commits, author dates and branches and merges:
* (HEAD -> master) I2
|\
| * (branch_D2) G2
* | H2
| | * (branch_E2, tag: tag_F2) F2
| |/
| * E2
|/
* (tag: tag_D2) D2
| * (branch_B2) C2
|/
* B2
* A2
|
* J1
| * (branch_I1) K1
|/
* I1
* (tag: tag_H1) H1
|\
| * (branch_B1) F1
| * D1
* | G1
| | * (branch_D1) E1
| |/
| * C1
|/
* B1
* A1
So I need to add the red edge somehow (note: the tags are not visible in this graph, but should also be rebased):
What I tried so far:
- Simple rebase:
git rebase test-first/master test-second/master
This doesn't preserve the merges and author dates, nor other branches from the second repo - Solution for keeping author dates and merges:
http://axiac.ro/blog/2014/11/merging-git-repositories/
Summary: it uses--preserve-merges
and then some git magic (git filter-branch ...
) to rewrite the author dates.
This solution also doesn't copy over all the unmerged branches of the second repo. - How do you merge two Git repositories?
Only merges a single branch - Setting git parent pointer to a different parent
Git grafs only change the parent, but don't take into account the differences if two files have been changed in both repos and should be merged.