phihag
phihag

Reputation: 287815

Find first ancestor commit in another branch

I want to find the most recent commit that's included in another branch; given the history

A-B-C---E  <-master
  └-F---G  <-develop
    └-H-I  <-branch1

I want to find F. Note that I only know the starting point branch1, and not the names of the other branches.

I know that I can simply check for the lowest i≥0 so that

git branch --contains branch1~i

outputs more than one line, but that seems wasteful.

Upvotes: 2

Views: 197

Answers (2)

Brian Campbell
Brian Campbell

Reputation: 332776

To do this, take a look at the post-receive-email script that comes with your Git distribution (should be installed somewhere like /usr/share/doc/git-core/contrib/hooks/post-receive-email if you want a local copy). This has a long comment that describes how to find only commits that are new in a given branch, and haven't been seen in any others before:

    # Consider this:
    #   1 --- 2 --- O --- X --- 3 --- 4 --- N
    #
    # O is $oldrev for $refname
    # N is $newrev for $refname
    # X is a revision pointed to by some other ref, for which we may
    #   assume that an email has already been generated.
    # In this case we want to issue an email containing only revisions
    # 3, 4, and N.  Given (almost) by
    #
    #  git rev-list N ^O --not --all
    #
    # The reason for the "almost", is that the "--not --all" will take
    # precedence over the "N", and effectively will translate to
    #
    #  git rev-list N ^O ^X ^N
    #
    # So, we need to build up the list more carefully.  git rev-parse
    # will generate a list of revs that may be fed into git rev-list.
    # We can get it to make the "--not --all" part and then filter out
    # the "^N" with:
    #
    #  git rev-parse --not --all | grep -v N
    #
    # Then, using the --stdin switch to git rev-list we have effectively
    # manufactured
    #
    #  git rev-list N ^O ^X

There are more details to handle corner cases in the comment, and the rest of the script; but if the basic case is all you care about, this should give you the answer:

git rev-parse --not --all | grep -v I | git rev-list --stdin I

where you can calculate I as $(git rev-parse branch1). The last entry of the result will be the commit H, you can reach the most recent ancestor in another branch with H^ then.

Upvotes: 3

Peter van der Does
Peter van der Does

Reputation: 14468

If you know the name of the branch with H-I, for example branch1

git reflog show --all|grep branch1

The highest number in accolades is your first commit on that branch.

Upvotes: 0

Related Questions