jesseduffield / jesseduffield/lazygit

Branch-sensitive commits traversal

Open
#3,575 1 comment 11 reactions 0 assignees View on GitHub
enhancement
Dominant language
Go
Stars
82.4k
Forks
3k
Avg merge
2d 18h
Merged PRs (30d)
19

Description

**Is your feature request related to a problem? Please describe.**

When viewing repository with a lot of merges to the main branch (e.g. when all feature PRs are merged without fast-forwarding), it is annoying to have to try to visually find previous/next merge commit (or next normal commit) in this particular branch, especially if there are long running feature branches with many commits being merged.
Iterating with ``/`` keybindings does not help much, because there is no control over which commit will go next -- it will jump from one sub-branch to the other, when I might want to go through commits of one particular branch *without checking it out*.

**Describe the solution you'd like**

Ideally, there would be keybindings like ``/`` (``/``) to traverse graph view in `commits` window, which will select previous/next commit in given branch and "skipping" merge commits by following only the first parent (like `git log --first-parent`) when going back in history. When going forward in history the behavior should be similar -- as if we were going upwards in `git log --first-parent`.

These keybindings are supported in Sublime Merge, and you can use them starting from any commit on any branch, although I am not sure how they resolve going forwards in history -- which commit to choose if there are many choices.
But if we traversed backwards in history, the traversal upwards from that point seems to follow the same path as it took to get there.

So in the following example, starting from commit `h` we should be able to traverse `h -> g -> e -> c -> a` using `` and the other way starting from `a` -- `a -> c -> e -> g -> h` using ``.

```mermaid
%%{init: { 'theme': 'base', 'gitGraph': {'rotateCommitLabel': false}} }%%
gitGraph
commit id: "a"
branch bar
checkout bar
commit id: "b"
checkout main
commit id: "c"
branch foo
checkout foo
commit id: "d"
checkout main
merge bar id: "e"
checkout foo
commit id: "f"
checkout main
commit id: "g"
merge foo id: "h"
```

Note that in Sublime Merge if we start from commit `f` and go backwards, the path will be `f -> d -> c -> a`, and if the we go forwards, it will do the same path in reverse -- `a -> c -> d -> f`. However, if starting from `f` we go forward to merge commit `h`, from there going backwards will follow `main` branch according to `--first-parent` rule -- `h -> g -> e -> ...`.

**Describe alternatives you've considered**

1. Filtering the whole displayed graph with `--first-parent`:
```
git log --graph --first-parent
```
However, I would still prefer to see all the intermediate commits in branches that I am skipping this way.
Also it does not work with `--all`, so I won't be able to see other unrelated branches in the same view while filtering my branch with `--first-parent`.
2. Supporting collapsing/expanding of merge commits, like in https://github.com/jesseduffield/lazygit/issues/2843#issuecomment-1837629329
This will mostly suffice when viewing single branch history, but with `--all` it still will be possible to traverse other branches' commits by going backwards/forwards in history.
However, these to suggestions are not mutually exclusive, since Sublime Merge supports both better history traversal and collapsible merge commits.

**Additional context**

If some mechanism of such branch-sensitive traversal is implemented, it might be a good idea to support also "selection history" traversal (again like it is implemented in Sublime Merge), where ``/`` traverse through previously selected commits -- something like undo history for commit selection.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.