Skip to content

Branching - #2890

Open
philocalyst wants to merge 70 commits into
gitui-org:masterfrom
philocalyst:branching
Open

philocalyst wants to merge 70 commits into
gitui-org:masterfrom
philocalyst:branching

Conversation

@philocalyst

@philocalyst philocalyst commented Mar 24, 2026 •

Copy link
Copy Markdown

This Pull Request fixes/closes #81.

It changes the following:

  • Implements a complete view of commit lineage
  • Borrows the logic/implementation from the well-tested guitar
  • Conforms to the streaming model that was used in the previous version of the displays, meaning its performance impact is negligible.
  • Has a new keybind to hide the graph, as a toggle.
  • Expands and contracts dynamically based on what is currently on-screen
  • Makes good use of space by compressing whitespace when possible (Through re-using lanes)
  • Remains consistent against the rest of the UI.
Screenshot 2026-03-23 at 22 14 25 Screenshot 2026-03-23 at 22 15 36

I followed the checklist:

  • I added unittests
  • I ran make check without errors
  • I tested the overall application
  • I added an appropriate item to the changelog

@philocalyst

philocalyst commented Mar 24, 2026 •

Copy link
Copy Markdown
Author

@extrawurst Would love your feedback on this :) Quite large.

OH! And I just noticed that I removed the missing docs lint, I'll add that back if we agree on this general direction.

@gogongxt

Copy link
Copy Markdown

LGTM

@extrawurst
extrawurst requested a review from cruessler March 29, 2026 17:29
Comment thread CHANGELOG.md Outdated
* fix extremely slow status loading in large repositories by replacing time-based cache invalidation with generation counter [[@DannyStoll1](https://github.com/DannyStoll1)] ([#2823](https://github.com/gitui-org/gitui/issues/2823))
* fix panic when renaming or updating remote URL with no remotes configured [[@xvchris](https://github.com/xvchris)] ([#2868](https://github.com/gitui-org/gitui/issues/2868))
### Added
* Now with a graph view!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please match the ususal format

@extrawurst

Copy link
Copy Markdown
Collaborator

I think we need to improve the visualization still, this is the same point in time of the history in three different tools: gitui, tig and fork:

Screenshot 2026-03-29 at 19 50 36 Screenshot 2026-03-29 at 19 50 27 Screenshot 2026-03-29 at 19 51 51

@philocalyst

philocalyst commented Mar 29, 2026 via email

Copy link
Copy Markdown
Author

@VojtaStanek

Copy link
Copy Markdown

I am looking forward to this change!

By a quick look the source it seems like it works only with merge commits with 2 parents, but commit can have an arbitrary number of parents (see e.g. here).

@philocalyst

Copy link
Copy Markdown
Author

@VojtaStanek Yes! Octopus merges! That's not covered here.

I couldn't find an implementation that handles them in a way that maps well to streaming. They don't crash anything, and happen incredibly rarely. If someone is able to extend what I have here, they're welcome to; but it shouldn't block merging.

@cruessler

Copy link
Copy Markdown
Collaborator

Thanks a lot for getting this started, that’s much appreciated! I just started reviewing the changes, but then I had a few more general questions.

In its current form, I find it hard to see merge commits and how they connect to their respective parents. The image below shows a comparison between this branch and tig in the gitoxide repository that has quite a few merge commits. Is there anything I need to set up to make merge commits more prominent? Does my terminal font need to have certain glyphs?

Also, in tig, vertical lines don’t get cut by horizontal ones, as opposed to guitar. I think I like tig’s approach better. What do you think?

Screenshot_20260407_212543

@philocalyst

philocalyst commented Apr 7, 2026 via email

Copy link
Copy Markdown
Author

@extrawurst

Copy link
Copy Markdown
Collaborator

I also wonder if people like the pressed texts to the facets of the branch lines? I could implement that as well.

Not for now.

The glyphs could expose be exposed as configuration.

Also not relevant for now. Lets find a visual style thats a good default and add customization in a later PR. THis one is big enough as is.

In its current form, I find it hard to see merge commits and how they connect to their respective parents

I agree with this. we either find better symbols or go for the letter M.

Furthermore I think we should use different colored lines for parallel branches like tig does for more clear separation.

@philocalyst

Copy link
Copy Markdown
Author
Screenshot 2026-04-17 at 08 37 30 Screenshot 2026-04-17 at 08 39 29 Screenshot 2026-04-17 at 08 42 16

With the updates, the PR is now looking like the above. Is this a better direction? @extrawurst

I plan to submit a follow-up PR with selection-based highlighting which I think will clear up the remaining vie
wing complexities (As ascii characters can only show so much, realistically). This would look like cutting over the "background" lines when a particular lineage is focused.

@balintbarna

Copy link
Copy Markdown

Hi all, if you need a reference for what looks good and works well in TUI then lazygit (go) and git-igitt (rust) are both very good at visualizing the graph. I think the table layout of lazygit makes more sense:

short hash | timestamp | name | graph | (tags, branches) message

it can also switch between --all mode and current branch
and the colors and highlighting are great
I think it would be a good source of inspiration for the desired look
it also has multi-commit selection by holding down shift and a lot of useful shortcuts on this view, such as squash, fixup, drop, edit, amend, checkout, reset, cherry-pick, which is probably a separate issue from visualizing it, but mentioned it for completeness sake.

https://github.com/jesseduffield/lazygit#commit-graph
https://github.com/git-bahn/git-igitt

image

@philocalyst

Copy link
Copy Markdown
Author

When I looked at the algo's of git-gitt there was some issues around their design as a second-pass over a complete input, which is counter to the streaming design of gitui. Definitely still some issues I realize I miss when I review, I think there's still some issues with connecting pipes, but the tradeoffs of the algorithm feel solid to me.

@balintbarna

balintbarna commented Apr 22, 2026 •

Copy link
Copy Markdown

@philocalyst thanks for your reply. I don't have any insight on the code of the above mentioned projects, my comment is purely from a user perspective.

I'm a software professional and my main way of interacting with git is lazygit, before that I used the integration in vs code with the very popular git graph extension and before that I used source tree. I also briefly tried gitkraken and more recently gitui. I use the CLI when I need to or when it's simpler.

While lazygit has some serious bugs and I disagree with some of their decisions which make me miss git graph from vs code, it is my favourite tool so far, and a big part of that is their graph view, and even if the first version in gitui isn't equivalent, I would like to suggest it as inspiration for what it could become, in addition to the also fantastic git graph extension in vs code and the visually appealing git-igitt.

@philocalyst

philocalyst commented Apr 22, 2026 via email

Copy link
Copy Markdown
Author

@cruessler

Copy link
Copy Markdown
Collaborator

@philocalyst Thanks for the changes! I’ve now started the proper first review which should be ready by today or tomorrow if all goes according to plan! 😀

@philocalyst

philocalyst commented Apr 27, 2026 via email

Copy link
Copy Markdown
Author

@peso

peso commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Hi there. I'm still working on getting git-graph, now gleisbau, into gitui. The speed requirement from gitui can be solved by splitting the global branch trace algorithm off to a background thread, and then start at head. This will feel as if it starts instantly, but it will traverse the entire repo in due time. The split also addresses the memory issue seen in the gitui+gitgraph prototype from about a year go.

This is a major refactoring, so it will take some time. git-igitt is part of the git-bahn family and uses git-graph/gleisbau under the hood.

I think it is a good idea to get a graph feature into gitui as soon as possible. Everybody wants it. Maybe gleisbau can produce a visual improvement, but the major step is simply getting a graph. Congratulations to @philocalyst for reaching that goal.

@cruessler cruessler left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m sorry it’s taking so long! In order to not make you wait longer, I’m now sending you my first batch of comments, hoping they are already useful. As soon as I’m done with the next batch, you’ll get the next round of comments. I hope that works for you!

Comment thread asyncgit/src/graph/oids.rs Outdated
Comment thread asyncgit/src/graph/oids.rs Outdated
Comment thread asyncgit/src/graph/oids.rs Outdated
Comment thread asyncgit/src/graph/mod.rs Outdated
Comment thread asyncgit/src/graph/oids.rs Outdated
@philocalyst

Copy link
Copy Markdown
Author

Balls back in your court! @cruessler

@cruessler

Copy link
Copy Markdown
Collaborator

@philocalyst wrote:
Balls back in your court! @cruessler

Really sorry it’s taking so long, I should be able to devote some time to this PR this week as I don’t have too many other obligations.

@philocalyst

Copy link
Copy Markdown
Author

@cruessler Appreciated! Have another PR I've been sitting on for LFS, but didn't want to overwhelm the team -- so I'll be monitoring my github notifications closely to make sure this week isn't wasted!!

@cruessler cruessler left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m slowly getting myself familiar with the PR, in order to make sure I actually understand myself what is going on. 😀 I’ve got a couple of questions and remarks, some more fundamental than others. I’m also going to push minor refactorings that don’t warrant a comment to your branch as well, in order to make some areas more idiomatic. I hope that’s ok, if not, please let me know!

Comment thread asyncgit/src/lib.rs
Comment thread asyncgit/src/revlog.rs Outdated
Comment thread asyncgit/src/graph/walker.rs Outdated
Comment thread asyncgit/src/graph/mod.rs
Comment thread asyncgit/src/graph/mod.rs
Comment thread asyncgit/src/graph/mod.rs Outdated
Comment thread asyncgit/src/graph/mod.rs Outdated
Comment thread asyncgit/src/graph/chunk.rs Outdated
Comment thread src/components/commitlist.rs
Comment thread asyncgit/src/graph/buffer.rs
Comment thread asyncgit/src/graph/buffer.rs Outdated
@philocalyst

Copy link
Copy Markdown
Author

okay @cruessler you inspired me to do a pretty big refactor so sorry for the delay here! put a ton of effort into reducing the amount of redundant work as far as both clones and passing through the same commits/lanes twice or more. should be totally lazy as far as the graph goes, which i'm very happy to report! there's also a set of tests that should test the basics... (disclosure that i used $llm for the test writing, let me know if this goes against a policy and i will rewrite!)

Also I kind of overpromised with stashes, although I will do in a follow-up if all goes well :)

@andras-tim

andras-tim commented Sep 10, 2026 •

Copy link
Copy Markdown

sorry for the offtopic, but I can't wait this feature for months... 😓
Could you please to merge it if there's no serious issues? This is an awesome feature that would make the gitui tui complete! (I'm going to finally switch from git-gui & gitk to gitui 😍)

@philocalyst

philocalyst commented Sep 10, 2026 •

Copy link
Copy Markdown
Author

Will fortune and fate it should be complete, just waiting on final review, btw @cruessler that force push is with lease, it was just a cargo.toml change! Please don't fret.

@cruessler

Copy link
Copy Markdown
Collaborator

This PR is on top of my TODO list for the coming week! I have drafted a benchmark to make sure there’s no performance regressions, but I have not yet gotten to committing and pushing that code.

@cruessler

Copy link
Copy Markdown
Collaborator

@philocalyst The benchmark is available in this commit: cruessler@d372bfa. This commit can be applied on top of your PR. The benchmark exercises a history walk with and without creating the history graph. Would you mind double-checking that it actually measures your changes? (I had it drafted by an LLM and want to make sure I didn’t miss anything in my review.)

Also, could you run the part without graph creation on your machine and compare against master? (This requires some modifications to the benchmark, but should not be too complicated.)

Example result on my machine:

❯ GITUI_BENCH_REPO=~/github/extrawurst/gitui/ cargo bench -p asyncgit --bench full_history
    Finished `bench` profile [optimized] target(s) in 0.13s
     Running benches/full_history.rs (target/release/deps/full_history-1e929556af4de21d)
full_history/without_graph
                        time:   [17.477 ms 17.660 ms 17.786 ms]
                        thrpt:  [146.18 Kelem/s 147.23 Kelem/s 148.77 Kelem/s]
                 change:
                        time:   [+0.4870% +1.6229% +2.7906%] (p = 0.02 < 0.05)
                        thrpt:  [−2.7148% −1.5970% −0.4847%]
                        Change within noise threshold.
full_history/with_graph time:   [35.523 ms 35.901 ms 36.392 ms]
                        thrpt:  [71.444 Kelem/s 72.421 Kelem/s 73.193 Kelem/s]
                 change:
                        time:   [−0.2869% +1.1908% +2.8456%] (p = 0.17 > 0.05)
                        thrpt:  [−2.7669% −1.1768% +0.2878%]
                        No change in performance detected.
Found 1 outliers among 10 measurements (10.00%)
  1 (10.00%) high mild

So it looks like creating the graph requires about the same amount of time as walking the history in this example. Running the full_history/without_graph part on master requires about the same amount of time as on this branch, so it looks like your changes don’t affect the “graph is disabled”-case in this synthetic benchmark.

❯ GITUI_BENCH_REPO=~/github/extrawurst/gitui/ cargo bench -p asyncgit --bench full_history
    Finished `bench` profile [optimized] target(s) in 0.10s
     Running benches/full_history.rs (target/release/deps/full_history-164177db5604f630)
full_history/without_graph
                        time:   [17.510 ms 17.691 ms 17.808 ms]
                        thrpt:  [146.01 Kelem/s 146.97 Kelem/s 148.49 Kelem/s]
                 change:
                        time:   [+0.3010% +1.5661% +2.7256%] (p = 0.03 < 0.05)
                        thrpt:  [−2.6532% −1.5420% −0.3001%]
                        Change within noise threshold.
Found 1 outliers among 10 measurements (10.00%)
  1 (10.00%) low mild

@philocalyst

Copy link
Copy Markdown
Author

Verifying now 🫡

@philocalyst

Copy link
Copy Markdown
Author

Alrighty! Okay as-was it was roughly a doubling in latency on scroll. Got some pretty simple fixes on accidental double-passes, and it's looking +15% which I think is fair. Going deeper would take deeper refactors and uh, I think we all just want this to be merged :)

@philocalyst

Copy link
Copy Markdown
Author

OH and I added a small dependency for hashing as that was a hangup just because of the sheer amount of things that need to get hashed. gix has a hash impl but it's panick-y and annoying to work with.... could vendor/handroll if we really want to, but both are kind of ugly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show the branching structure in the log.

8 participants