Search code examples
gitgit-log

How to view a linear `git log` (exclude feature commits), showing only commits to `main` or merges to `main`


Quick summary of my question

I have this git lg output (get this alias in my "Details" section below):

*   3333333 - merge of feature branch into `main`
|\  
| * ccccccc - feature branch commit 3
| * bbbbbbb - feature branch commit 2
| * aaaaaaa - feature branch commit 1
|/  
* 2222222 - some other commit
* 1111111 - initial commit

I want this git lg output:

* 3333333 - merge of feature branch into `main` 
* 2222222 - some other commit
* 1111111 - initial commit

How can I do that? You might re-title this question: "how to view a git log as if it was linear".

Details

I have this git lg alias. It's great! Get it by running this:

# add `git lg` alias from Coderwall
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

Its output looks like this:

*   3333333 - merge of feature branch into `main`
|\  
| * ccccccc - feature branch commit 3
| * bbbbbbb - feature branch commit 2
| * aaaaaaa - feature branch commit 1
|/  
* 2222222 - some other commit
* 1111111 - initial commit

Here, I have labeled the two branches main and feature. Commits 1111111, 2222222, and 3333333 are either direct commits to main, or merge commits to main. Commits aaaaaaa, bbbbbbb, and ccccccc are commits on feature branch:

v-branch `main`
  v-branch `feature`


*   3333333 - merge of feature branch into `main`
|\  
| * ccccccc - feature branch commit 3
| * bbbbbbb - feature branch commit 2
| * aaaaaaa - feature branch commit 1
|/  
* 2222222 - some other commit
* 1111111 - initial commit

I'd like a "bigger picture" sort of view. I don't care about the individual commits in each feature branch. I just want to see these "main" commits, whether I run git log or git lg:

* 3333333 - merge of feature branch into `main` 
* 2222222 - some other commit
* 1111111 - initial commit

How can I do that? git lg --merges or git log --merges is closer, but not right. It shows this:

* 3333333 - merge of feature branch into `main` 

But, what I really want is the whole linear history, with all commits directly to main, or merged to main. That would be as if I had a squashed linear git log history by enforcing git rebase+squash+fast-forward merges instead of git merge merges.

Anyway, so how can I filter and just get this git lg output?

* 3333333 - merge of feature branch into `main` 
* 2222222 - some other commit
* 1111111 - initial commit

Solution

  • I think you're looking for the --first-parent option to git log. It describes exactly what you're looking for. From the git-log man page:

    --first-parent

    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.

    Using a local repository as an example, if I run:

    git log --graph --format='%h' HEAD~5..
    

    I get:

    * 6abb395
    *   cb88d06
    |\  
    | * aa53a16
    |/  
    *   0abcc50
    |\  
    | * 1e7bcc6
    |/  
    *   4e0ab62
    |\  
    | * fd16fb0
    |/  
    * 5d7f675
    * 6941b71
    

    But if I add the --first-parent option ("When finding commits to include, follow only the first parent commit upon seeing a merge commit"):

    git log --graph --format='%h' --first-parent HEAD~5..
    

    I get:

    * 6abb395
    * cb88d06
    * 0abcc50
    * 4e0ab62
    * 5d7f675
    

    And I think that's the behavior you were looking for.