46

I've done a bit of searching and found:

git log myBranchName

as a possible solution. But what happens when my branch is the master branch? when I run:

git log master

It seems to return everything commited to any branch. Based on what I've read, it lists all of the commits related to the master branch. Knowing that, how I can call up the commit history of the master branch only?

Kris Anderson
  • 1,007
  • 2
  • 9
  • 15

2 Answers2

82

I think this is what you want

git log --first-parent master

To quote the manual

Follow only the first parent commit upon seeing a merge commit. This option can give a better overview when viewing the evolution of a particular topic branch, because merges into a topic branch tend to be only about adjusting to updated upstream from time to time, and this option allows you to ignore the individual commits brought in to your history by such a merge.

ydaetskcoR
  • 53,225
  • 8
  • 158
  • 177
parkydr
  • 7,596
  • 3
  • 32
  • 42
  • 5
    `--first-parent master` was very useful for an issue I was dealing with: determine which merges (--merges) went into master, vs merges on a topic branch. – Matt Dressel Sep 20 '13 at 20:31
  • Thanks. I think should me market as a solution to this problem. – Konrad Szałwiński Nov 19 '14 at 18:07
  • 1
    Just a heads-up, it's not perfect. If the previous commit to `master` happens to be listed as a commit's _second_ parent, this will give you the wrong one. That won't usually happen if you're following GitHub's pull request / merge process, though. – PJSCopeland Aug 17 '17 at 21:36
  • Unfortunately it doesn't work in the quite common case of fast forward merges, see the other answer. – ThreeStarProgrammer57 Jun 23 '23 at 23:42
  • It depend on your branching strategy. If you use have a main branch make changes on side branches then merge back to the main branch (e.g. Gitflow) this works well – parkydr Jun 25 '23 at 06:30
20

Due to Git’s branching model, commits do not belong to a single or multiple branches. Branches are pointers to single commit objects within the whole commit graph. So when you say a commit is “on a branch X” in X, you usually mean that it is reachable when starting at the commit the branch X points to.

For git log, the default behaviour is equal to git log HEAD where HEAD refers to the commit the current branch currently points at. So if you are on the master branch, it is equal to git log master, showing all commits that are reachable when starting at the most recent commit.

Unfortunately what you are referring to as a commit made to a certain branch is not clearly defined in Git. If I make a commit on master, and then create a new branch that points to the same commit (e.g. using git branch newbranch), then that branch is literally identical to the master branch except for the name. So every property “made on branch master” would now also imply “made on branch newbranch”. As such you cannot have this property in Git.

Even parkydr’s solution, which shows all commits which were made only on a single side of merges is not a failproof solution. Ideally it would hide all those commits which were made on a separate non-master branch and which were then merged back into master. As such you would only get commits that are either made to the master-line directly or which are merge commits merging in some other commits. However there are two things that will prevent this from working:

  1. Fast-forward merges: When you branch off from master and create some commits, while creating no new ones on master directly, then a git merge somebranch on master will fast-forward the commits, resulting in the master branch pointing to the same commit as somebranch. As such you “lose” the information that those commits were originally created on a separate branch. You can force Git to always create merge commits though, using git merge --no-ff but this won’t help you afterwards.
  2. The merge order is not guaranteed: When you are on master and merge a branch in, then the previous master commit will always be the first parent. So you would get your desired behaviour. However it is perfectly possible to be on said branch, and merge master in instead, resulting in the master commit being the second parent. Then master could be fast-forwarded (or reset) to the new commit resulting in a “reversed” view.

So, the bottom line is that you cannot safely get such a history. You’re better off getting used to how Git’s flexible branching model works.

poke
  • 369,085
  • 72
  • 557
  • 602
  • "flexible branching model"? Hmmm, it looks more like a design flaw to me. Mercurial doesn't suffer from this one, and it's very helpful when you need to revisit history to find a commit when you remember on which projet-branch it was made. You filter-in the commits from that branch and you already have a much lower number of commits to visit, instead of looking at a huge and wide graph (like a project with ~50 parallel branches). I guess "getting used to Git's flexible branching model" means giving up on this most of the time. – ThreeStarProgrammer57 Jun 23 '23 at 23:40