Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the common ancestor of two branches before a merge commit in git?

Tags:

git

Background

I'm trying to write a script that will simplify my backport process using git.

The general process for fixing a bug in the current version goes something like this:

  1. Branch from master to a bug fix branch, e.g. bugfix/abc
  2. Make all the commits to fix the bug on bugfix/abc
  3. Merge bugfix/abc to master (without fast-forward merges)

Now when I want to backport the fix to version 1 for example (branch v1) I do:

  1. Create a new branch from bugfix/abc, e.g. bugfix/def
  2. Then manually find the commit on master that was before the merge commit, e.g. f4d399238f
  3. Now I use rebase: $ git rebase --onto v1 f4d399238f bugfix/def

This works great (after working out that I had to use the commit before the merge for the upstream).

Question

How do I find the common ancestor of two branches before a merge commit? (for step 2 of the backport process).

Tried

  1. git merge-base bugfix/abc master
    • Since the merge has already been done this just returns the commit at the head of bugfix/abc
  2. Combining the result of #1 to get the child of this commit using git log
    • I tried following How do I find the next commit in git? using various combinations of --reverse, --ancestry-path and --children but I never got what I expected.

Update

The key difference between this question and Find common ancestor of two branches is that the two branches have already been merged. As I mentioned the best commit is returned as the head of the branch that was merged. I need the common ancestor before the merge commit.

Assume that the branches after the bug has been fixed and merged into master look like:

A---B v1
     \
      C---D---F---H master
           \     /
            E---G bugfix/abc

Running $ git merge-base master bugfix/abc will return G but I need to get D (or even F would do for the purpose of using rebase --onto).

Once I get D I would then run:

$ git branch bugfix/def bugfix/abc
$ git rebase --onto v1 D bugfix/def
$ git checkout v1
$ git merge bugfix/def

To end up with the desired result of:

      E'---G' bugfix/def
     /      \
A---B--------I v1
     \
      C---D---F---H master
           \     /
            E---G bugfix/abc
like image 563
steinybot Avatar asked Nov 18 '25 22:11

steinybot


1 Answers

How do I find the common ancestor of two branches before a merge commit? (for step 2 of the backport process).

There are several options to use:

git merge-base

git merge-base is the command you are looking for

git merge-base finds best common ancestor(s) between two commits to use in a three-way merge. One common ancestor is better than another common ancestor if the latter is an ancestor of the former. A common ancestor that does not have any better common ancestor is a best common ancestor, i.e. a merge base. Note that there can be more than one merge base for a pair of commits.

Manually find it from the log

git log --decorate --graph --oneline --all

This will display the fork points in the log so you can track the commit id of the branching.

like image 197
CodeWizard Avatar answered Nov 21 '25 10:11

CodeWizard