Feature Request: sort files by git status
heafnerj opened this issue · 2 comments
Would it be possible to add a feature to sort files in a repo by their git status?
Oh that could be super useful!
I propose --sort git
as the option flag.
Design Thoughts
Matching the order of git status
output is probably the most intuitive.
git status
prints file names with staged changes first, then file names with unstaged changes, and then finally untracked names (and within those groups, the sort is alphabetical/lexical).
exa
has to adapt that a bit because it only has one entry per path (a file with both staged and unstanged changes only gets one entry, whereas in git status
it gets listed twice) and because it might also be listing files that are in .gitignore
. But I think the closer we get to an intuitive match between the two the better.
So I propose to sort by like this:
- paths with staged changes go before paths without staged changes,
- within that, paths with unstaged changes get sorted before paths without unstaged changes, and
- within that, new status
N
gets sorted beforeM
(this last thing deviates fromgit status
but I think it would make a big difference in certain situations, because then you reduce the frequency and unpredictability of where you need to noticeN
vsM
distinctions in the listing... also in practice for it has been true for years that I occasionally find myself wishing thatgit status
grouped by renamed/added/deleted/modified within staged/unstaged/untracked before the lexical sort).
Sorting staged-changes before no-staged-changes also matches a decision already made in --git
output: staged status is the left character, unstaged status is the right character. So when you scan visually, it would work out really nicely - for example (modified from Exa --git
documentation):
$ exa --long --git
Permissions Size User Date Modified Git Name
.rw-r--r-- 155 ben 25 Nov 17:23 NM unselectable.scss
.rw-r--r-- 612 ben 24 Nov 16:04 M- media.scss
.rw-r--r-- 260 ben 25 Nov 17:23 -M icon.scss
.rw-r--r-- 59 ben 25 Nov 17:23 -N plain-link.scss
.rw-r--r-- 96 ben 21 Nov 14:20 -- hoverable.scss
Which corresponds to:
$ git status
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: media.scss
new file: unselectable.scss
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: icon.scss
modified: unselectable.scss
Untracked files:
(use "git add <file>..." to include in what will be committed)
plain-link.scss
P.S. a third reason for making has-staged-changes versus does-not-have-staged-changes as the primary sort is that right before a commit, the most important/salient difference is what's staged - and any deliberate use of the staging area (staging smaller pieces for individual commits instead of basically ignoring the staged/unstaged difference and committing all outstanging changes at once), it's really helpful to have a fast-and-easy-to-visually-parse cue of staged-vs-unstaged.
Sounds excellent to me.