jesseduffield / lazygit

simple terminal UI for git commands
MIT License
53.78k stars 1.88k forks source link

feat: Custom sort orders & support for multiple sort tags. #3552

Open XavierChanth opened 7 months ago

XavierChanth commented 7 months ago

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

Working with bare repositories + worktrees makes the local branches tab quite useless. With a bare repo, git branch lists all of the remote branches as local.

Describe the solution you'd like I would like to use the following sorts:

--sort=-worktreepath --sort=-HEAD, this will list the current worktree first, then all other worktrees, then all other branches which are not checked out in a worktree.

Describe alternatives you've considered Tried looking for config options, this will not work in gitconfig since branch.sort is only used by git if --sort is not specified (but lazygit always passes --sort)

Additional context

The other thing that contributes to this problem is that with recency (the default sort) as the default sort, recent branches are not recent in the context of multiple worktrees. Since if I checkout branchA and then branchB in separate worktrees, branchA will not be considered recent from branchB since branchA wasn't checked out recently from branchB's worktree. So it pretty much sorts HEAD then everything else alphabetically, assuming a one-branch-one-worktree workflow.

Example of the sort:

git branch --sort=-worktreepath --sort=-HEAD:

* trunk
+ c_daemon
  1000-add-feedback-to-no-ports-desktop
  712-empty-session-and-tunnel-username-prevents-a-successful-ssh-in-the-desktop-app
  713-the-desktop-app-is-stuck-on-a-loading-screen-when-a-hung-session-occurs
  714-fix-settings-screen-shows-a-grey-box
  731-buggy-nav-bar-see-video-below
  733-organize-config-screen-fields-into-a-2-column-layout
  754-make-sure-the-dashboard-page-reloads-to-show-the-profiles-after-initial-sync
  775-profile-boolean-fields-resorts-to-the-default-value-when-the-submit-button-is-pressed-sometimes
... etc.

Where trunk is the current worktree, and c_daemon is the only other worktree.

Happy to work on a PR for this over the weekend.

XavierChanth commented 7 months ago

Alright, so this has lead me down a git rabbit hole which may be worth sharing...

Since I don't actually want to copy all of the remote refs to my local anyways (this is a result of using bare repos, not anything to do with lazygit), the better way for me to checkout the repo is:

git clone <url> -n -c core.bare=true

This way, it should behave like a bare repo, but 2 things are different:

I have yet to determine if there are any other side effects in doing this, but I guess I will find out the hard way if there are. Hope this helps anyone else with similar issues.

Update:

From the context of the root of the repo, both $GIT_DIR and $GIT_COMMON_DIR will be .git instead of "." which could cause some tooling to put things inside of .git/ instead of the root.

I suppose there are ways of fixing the refs, but this fits my usecase of lazygit + worktrees well enough.