149

In following example tree:

A-B-C-D-E (master branch)
    \
     F-G-H (xxx branch)

I'm looking for F - the first commit in xxx branch. I think that it is possible with:

git log xxx --not master

and the last listed commit should be F. Is it correct solution or maybe there are some disadvantages of it?

I know that there were similar questions on stackoverflow, but nobody proposed such solution, and I'm not sure if I do it right.

Nevik Rehnel
  • 49,633
  • 6
  • 60
  • 50
user2699113
  • 4,262
  • 3
  • 25
  • 43
  • Possible duplicate of http://stackoverflow.com/questions/6058308/in-git-how-can-i-find-the-revision-at-which-a-branch-was-created – nyzm Aug 23 '13 at 16:33

8 Answers8

171
git log master..branch --oneline | tail -1

Where "branch" is your specific branch name. The dot-dot gives you all of the commits that the branch has that master doesn't have. tail -1 returns the last line from the previous output.

Community
  • 1
  • 1
konyak
  • 10,818
  • 4
  • 59
  • 65
  • 4
    this only works if `branch``exists. How would you do it if branch is deleted? – oz123 Feb 08 '16 at 20:29
  • 2
    @Oz123 branch can be replaced by any ref, like HEAD or a sha1 or a tag. But obviously you need some kind of reference. – Zitrax Apr 21 '16 at 11:36
  • 6
    Doesn't give me what I was expecting. My branch (old one) was already merged back to master, which means all commits in xxx are already in master. Still - I need to know which commit WAS the first one on that branch - or actually - I need to examine the history of commits of that branch alone - I don't care if they're on master or not. – Motti Shneor Apr 04 '17 at 12:15
  • 2
    @MottiShneor depending on how you merged, that could be tricky. If you did a fast-forward, it's as if the branch never existed. Otherwise, you may be interested in [this answer](https://stackoverflow.com/a/4991675/1463788), which lists a number of ways to find the branch point. Once you have your branch point, the SHA can replace `master`, and as long as your branch hasn't been deleted, `git log ..branch --oneline | tail -1` should still give you the results you're looking for. – ND Geek Jun 05 '17 at 15:35
  • 1
    You can use `--reverse` to read the logs backwards with colors, etc. – Dominik Aug 14 '19 at 16:26
24
git cherry master -v | head -n 1

cherry - Shows the commits on your current branch that aren't present on a branch upstream (docs). An upstream (master in this case) is a point your current branch derives from.

-v - Shows commit names (instead of just SHA's) - verbose.

head - Unix command which prints n number of lines from a text

Nelu
  • 16,644
  • 10
  • 80
  • 88
14

You should use the merge-base functionality which is designed to solve exactly this:

git merge-base remotes/origin/<branch> develop 
jwg
  • 5,547
  • 3
  • 43
  • 57
Fabrizio Stellato
  • 1,727
  • 21
  • 52
  • 2
    I don't think this will work if you desire to go back to the original fork point. If you merge develop into the merge-base will be newer than the original fork point. – Alexander Mills Sep 02 '18 at 02:28
  • 9
    Also, this would *not* point to F, but to a commit in master branch (although difficult to see in OP's drawing, seems to be B or C). – Romain Valeri Mar 16 '19 at 11:40
2

If your branch (old one) once again merged back to master doesn't give expected result.I have using python script to find initial branch commit Id.

git rev-list --first-parent changeset

--first-parent follow only the first parent commit upon seeing a merge commit.

Iterate changeset's from above command until parent branch found.

def status_check(exec_command, exec_dir=None, background=False):
    if exec_dir:
        os.chdir(exec_dir)
    res = subprocess.Popen(exec_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if not background:
        result = res.communicate()
    return result



def findNewBranchCommits(changeset=None):
    cmd = "git rev-list --first-parent "+ changeset
    rev_list = status_check(cmd,self.module_dir)
    rev_list = str(rev_list[0]).split('\n')
    rev_list = list(filter(None, rev_list))
    for x in rev_list:                      # Iterate until branch base point
        rev_cmd = "git branch --contains " + x
        rev_cmd = status_check(rev_cmd,self.module_dir)
        rev_cmd = str(rev_cmd[0]).split('\n')
        if(len(rev_cmd) > 2): 
            print "First Commit in xxx branch",x
            break

findNewBranchCommits(changeset)
Nayagam
  • 1,767
  • 18
  • 12
1
git cherry master -v | tail -1   

however this will only give you the first commit on branch xxx that is not in master, not the first commit on branch xxx ever. the latter would be difficult if branch xxx has been deleted and/or re-created one or more times. it that case you could try the following:

git reflog | grep checkout | grep xxx | tail -1   
Doc Unid
  • 11
  • 4
  • 4
    Did you mean to write `head -n 1` instead of `tail -1`? `tail -1` returns the most recent commit instead of the first. – Nelu Mar 15 '19 at 23:27
  • The first suggestion above doesn't work for me. After changing `master` to `main` which is the default branch on my current repo (`master` gives a fatal error from git). It gives the most recent commit instead of the oldest. The 2nd suggestion works fine. – arielf Feb 13 '21 at 04:59
0

git rev-list --ancestry-path $(git merge-base master xxx)..xxx | tail -1

wedens
  • 1,782
  • 14
  • 18
  • In my repo this shows the 1st commit since the last merge from master into branch xxx, not the 1st commit of branch xxx. – jk7 Mar 02 '16 at 19:57
  • For me this worked the best of all the answers listed here. I think it answers the question the best way (assuming the branch isn't merged back to master) – Eyal Gerber Jul 01 '21 at 08:30
0

Its very simple: You can use this to directly get the hash of the first commit in the feature branch:

git log <source_branch>..<feature_branch> --pretty=format:%h
user
  • 867
  • 9
  • 21
-2

I tried this command and it worked:

git log <source_branch> <feature_branch> --oneline | tail -1
Abderrahmen
  • 440
  • 3
  • 6
  • 2
    Please do not add me-too answers that relate to already existing answer material on the same post: https://stackoverflow.com/a/32870852/367456 – hakre Jan 23 '22 at 15:35