7

I have been toying with rebase a bit, trying to split and combine history as described here: https://git-scm.com/book/en/v2/Git-Tools-Replace

Here is my test repository with split history: https://github.com/defufna/split-history

Note that "initial commit" and "Added description" commits both point to the same tree. What I'm trying to do is merge these two histories (while maintaining merges). I used this:

git rebase --rebase-merges --onto history 94da9b0f

This works, but I'm getting a conflict at 084dae5. This is a merge that resolves modify/delete conflict, and it requires me to manually resolve this conflict.

I am doing this in preparation for much larger repo merge, where I will have to do something similar but with 50k commits, so I would like to avoid manual conflict resolution. I am aware that git replace could solve my problem, but I'm curious if it is possible to do it without replacement. I would also like to keep sha values of commits in history branch.

Edit:

So I've managed to do what I want, but I'm not sure how good this idea is. I've added -i to rebase, and when I got todo file, I've changed every

merge -C 9751be2 Merge # Merge

line into:

exec git checkout `git commit-tree '9751be2^{tree}' -p HEAD -p refs/rewritten/Merge -m Merge`

I'm basically telling git whenever it encounters a merge to reuse tree from original merge.

It works as expected (for now), but it's a lot slower. Is there a better way to do this?

Ivan
  • 1,735
  • 1
  • 17
  • 26
  • 1
    You might need `--allow-unrelated-histories` https://stackoverflow.com/questions/37937984/git-refusing-to-merge-unrelated-histories-on-rebase – evolutionxbox Feb 11 '20 at 14:31
  • Apperently rebase does not support that parameter. Also git does not complain about unrelated histories, rebase completes correctly and as expected after I resolve conflict. I'm just trying to find a way that wont produce a conflict. – Ivan Feb 11 '20 at 14:56
  • Why do you need to rebase? Could you use a merge instead? – evolutionxbox Feb 11 '20 at 15:07
  • 1
    Note that any "merge preserving" rebase (including the fancy new `--rebase-merges` that replaces the old sort-of-defective `-p` / `--preserve-merges`) actually works by *re-performing* the merge. Any conflicts you had to solve then, you may well have to solve again. While `git rerere` will help with low level conflicts, it will do nothing for high level (whole-file) conflicts such as modify/delete conflicts. – torek Feb 11 '20 at 17:41
  • @evolutionxbox: `--allow-unrelated-histories` is only needed with `git merge` when there is no merge base. It tells the merge strategy to use the empty tree (https://stackoverflow.com/q/9765453/1256452) as the merge base commit. Since this is a rebase, not a merge, that particular trick doesn't apply here. – torek Feb 11 '20 at 17:43
  • @torek according to the image they have no merge base. – evolutionxbox Feb 11 '20 at 17:48
  • @evolutionxbox Right, but *this is a rebase!* (Perhaps the appropriate emphasis on *merge* is missing in my phrase "only needed with ... merge".) – torek Feb 11 '20 at 17:50
  • @torek ah right. Then there may not be a way round the OP's issue of many conflicts. – evolutionxbox Feb 11 '20 at 17:52
  • Do you need the files on your future master be exactly the same as they are now? – max630 Feb 11 '20 at 18:22
  • Yes, It wouldn't be ok for them to differ. – Ivan Feb 12 '20 at 09:43

1 Answers1

4

Note that "initial commit"[94da] and "Added description"[c00e] commits both point to the same tree

Is there a better way to do this?

Much.

git replace --graft 94da c00e^
git filter-branch master

and you're done.

git rebase exists to re-apply changes onto different base content, producing snapshots with new content. You already have all the snapshots you want, you only need to rewire the ancestry. git replace --graft does it locally, allowing you to experiment casually. git filter-branch exists to bake in rewired ancestry while applying any super-easy content changes -- but you don't even have any of those. You just want to rewire the master history.

jthill
  • 55,082
  • 5
  • 77
  • 137