git log –first-parent

 · 3 min · torgeir

Git

You merge a branch into main, run git log, and suddenly loose track of where the actual merge happened, and what commits arrived because of it. The result is correct, of course, but seen from the merger/main~’s point of view its confusing.

Maybe you want to reset to before the merge, because there’s something you need to amend, or maybe you need look up where that rebase or squash needs to happen.

git log --first-parent to the rescue!

It will show only the first parent of each commit. A commit usually has the commit it was based on as its parent, and there’s usually just one parent. In the case of a merge, there are more parents. With --first-parent git log will only trace back through the first parent of each commit, hence focusing on the main branch’s history.

Here’s an example:

git init
Initialized empty Git repository in /Users/Torgeir/tmp/.git/

Add one file

echo one >> one && git add one && git commit -m one
[main (root-commit) 66e245f] one
 1 file changed, 2 insertions(+)
 create mode 100644 one

Add another

echo another >> another && git add another && git commit -m another
[main 68184f7] another
 1 file changed, 1 insertion(+)
 create mode 100644 another

Add a file on a branch

git checkout -b branch
echo on-a-branch >> on-a-branch && git add on-a-branch && git commit -m on-a-branch
[branch 8e2c492] on-a-branch
 1 file changed, 1 insertion(+)
 create mode 100644 on-a-branch

Move back and add the last file

git checkout main
echo the-last >> the-last && git add the-last && git commit -m the-last
[main ad2934c] the-last
 1 file changed, 1 insertion(+)
 create mode 100644 the-last

Merge the branch back into main

git merge branch
Merge made by the 'ort' strategy.
 on-a-branch | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 on-a-branch

Git log shows the history of commits through time, which might be confusing - the merge, the-last file and the file on-a-branch have been interleaved.

git log --pretty=format:'%h %ai - %s'
d69adf7 2023-05-06 08:52:54 +0200 - Merge branch 'branch'
ad2934c 2023-05-06 08:52:45 +0200 - the-last
8e2c492 2023-05-06 08:52:39 +0200 - on-a-branch
68184f7 2023-05-06 08:52:35 +0200 - another
66e245f 2023-05-06 08:52:31 +0200 - one

Using “first parent” it will show the history as seen from the merger/main’s point of view. Notice how what happened on the branch is no longer included.

git log --pretty=format:'%h %ai - %s' --first-parent
d69adf7 2023-05-06 08:52:54 +0200 - Merge branch 'branch'
ad2934c 2023-05-06 08:52:45 +0200 - the-last
68184f7 2023-05-06 08:52:35 +0200 - another
66e245f 2023-05-06 08:52:31 +0200 - one

This is also what GitHub shows in the PR overview when you merge a branch into it.