Search code examples
gitmergegit-merge

How can I override the merge-base in a git merge?


My repository has cherry-picks recorded as merges. It throws of git's selection of merge-base. Is it possible to specify the merge-base? If so, how?

Example: f is branched from master at A. C is cherry-picked to f, but misleadingly committed as a merge with K and C as parents.

A-B-C   master
\   \  
 K---C'-L   f

When merging f into master git will find C as best common ancestor and use it as Base. Since B is included at Base, but is missing at f it will be undone by the merge. Using A as base would give a correct merge.

Edit: This answer rules out plan B asked about below. So, hopefully someone can answer: How can I specify the merge-base in a git merge?


Edit, plan B: The repository has become like that by using tfs-git to fetch from two tfs-branches that have a cherry-pick-workflow. "Merge selected range" of one changeset shows up as a full merge in git. An alternative solution would be to somehow configure git-tfs to not create merge-commits. (To stop cherry-picking for all is not at an option.)


Solution

  • How can I specify the merge-base in a git merge?

    With grafts:

    echo $(git rev-parse tip1 mybase) >>.git/info/grafts
    echo $(git rev-parse tip2 mybase) >>.git/info/grafts
    
    git checkout tip1
    git merge tip2
    
    rm .git/info/grafts
    

    edit from comment: with annotated tags, specify ^{} at the end of your references, tip1^{} etc, to have rev-parse chase down and print the commit's id rather than being happy with the tag's.