I have (or am aiming to have!) a repo like so:
Master *-----*--*----------C---
\ \
Project1 \-*-------A----B----M2---A'--B'---
\ \ \
Project2 \----------*---M1------------M2---
I would like to do the merge M2 but I would like A and B to be completely ignored. I will then manually (e.g. cherry-pick) recreate A’ and B’ as/if necessary atop the new changes from the master.
Project2 is based on the Master, but merges in changes from Project1.
Desired outcome:
-
I want point M2 to be an identical copy of C in terms of files.
-
I need Project1 to have its own linear history so that Project2 can merge from it.
Context: Master is Drupal’s main codebase. Project1 is a branch I use to maintain specific patches that I wish to share with several projects. Project2 (and many others) merge from Project1.
I have considered:
-
git merge -s recursive -X theirs masterproblem with this is that AFAIK it will only prefertheirsif something conflicts. So if a change in A does not conflict, it will be present at M2 which will mean that A’ will be incomplete. -
git revert B..A ; git merge CThis will work but will leave me with a messy and long history. -
There is
git merge -s oursbut there does not seem to be agit merge -s theirs. -
I do not want to
git reset --hard Cbecause this will (I think) break the possibility of merging Project1 into Project2. Another approach would be to rebase Project1 onto C, but again, this would mean I could not merge into Project2.
This can be done with the “plumbing” commands:
The
git diff HEAD..masterwill tell me how to get from where I’m at (B) and where I want to be (C) in one big patch, and patch will, of course, apply it.git add -A .will add all the changes in the working tree into the index.We then create a merge commit for this with the next line: the
git-write-treecreates a new tree object from the index, and outputs its SHA1 as an argument togit commit-tree, which creates a commit for it having two parents, the current heads of Project1 (B) and master (C), and give it a suitable message.Git will create the commit object, but it won’t update any branches to use this commit. The final line tells git that we want our current branch, Project2, to be advanced (fast forwarded) to the commit SHA1 it generated.
From there you can recreate (e.g. might try with cherry-pick) the patches A’ and B’, if necessary.