Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better visualization of branch heads in non-expanded commits view #2735

Closed
stefanhaller opened this issue Jun 21, 2023 · 2 comments
Closed
Labels
enhancement New feature or request

Comments

@stefanhaller
Copy link
Collaborator

stefanhaller commented Jun 21, 2023

See #2568.

Current situation: we have an implementation of visualizing branch heads as a magenta (*) in front of the subject. It is disabled by default because users find it confusing; it can be enabled with the gui.experimentalShowBranchHeads config.

The main reason why it's confusing is that it is shown for all cases where there's any branch head pointing to a commit; this includes the current head (no matter whether that's a branch or a detached head), and remote branches. If we find a way to filter these out, and show the visualization only for local branches that are not the current head, then I'd hope we can turn it on again unconditionally.

(Another question is whether we can find a better way of conveying the information than marking the commit with (*). I'm open to suggestions here, but I'm personally happy with it.)

Now the question is how to implement this. Currently, we're passing %d in a --pretty=format option to git log, which gives us the decorations such as (HEAD -> mybranch) or (origin/master, origin/HEAD, master) that we show in the expanded commits view. We store these in the ExtraInfo field of the Commit struct. We could theoretically filter them down by passing the --decorate-refs-exclude option to git log; however, that's not really an option, since we are using the same log command for both the expanded and the compact view, and we do want to see all heads in the expanded view.

So the only way that I can see to achieve what we want is to parse the ExtraInfo field and apply heuristics to it to filter out unwanted stuff. Here's one way to do that:

  1. Use %D instead of %d in the --pretty=format option; this removes the enclosing ( ), making the data slightly easier to parse. We simply add the ( ) ourselves at display time.
  2. Split the field at ,
  3. Remove any element that contains ->
  4. Remove any element that starts with tag:
  5. Remove any element that is HEAD
  6. Remove any element that is the name of the current branch (not sure this can happen after step 3, but doesn't hurt)
  7. Remove any element that is equal to any of the configured main branches
  8. During an interactive rebase, remove any element that is the same as what's in .git/rebase-merge/head-name (minus the refs/heads/
  9. Loop over all remotes and remove any element that starts with <remote-name>/. Since we have the remotes in the model, this should be reasonably efficient.

Point 9. is the ugly part; for a name like foo/bar it can't distinguish whether that's refs/remotes/foo/bar (which should be filtered out) or refs/heads/foo/bar (which shouldn't). Hopefully that's rare enough in practice that it doesn't matter too much. If in doubt we'll filter out more rather than less, which is good.

Any thoughts or better ideas?

@stefanhaller
Copy link
Collaborator Author

Here's a PR that implements this approach: #2737. I've been running with this locally for while now and am very happy with it.

@stefanhaller
Copy link
Collaborator Author

Addressed by #2775.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant