2014: as j6t comments, gitk
already provide a solution (requested and documented by jt6):
gitk --exclude=inactive-\* --branches
Before Git 1.9 (Q4 2013), people often wished a way to tell "git log --branches
"(man) (and "git log --remotes --not --branches
"(man)) to exclude some local branches from the expansion of "--branches
" (similarly for "--tags
", "--all
" and "--glob=<pattern>
").
Now they have one.
See commit 9dc01bf, commit ff32d34, commit 751a2ac (01 Nov 2013), and commit e7b432c (30 Aug 2013) by Junio C Hamano (gitster
).
See commit 574d370 (02 Sep 2013) by Johannes Sixt (j6t
).
(Merged by Junio C Hamano -- gitster
-- in commit 10167eb, 05 Dec 2013)
rev-parse
: introduce --exclude= to tame wildcards
Teach "rev-parse
" the same "I'm going to glob, but omit the ones that match these patterns" feature as "rev-list".
git rev-parse
now includes in its man page:
--exclude=<glob-pattern>
Do not include refs matching '' that the next --all
,
--branches
, --tags
, --remotes
, or --glob
would otherwise
consider. Repetitions of this option accumulate exclusion patterns
up to the next --all
, --branches
, --tags
, --remotes
, or
--glob
option (other options or arguments do not clear
accumlated patterns).
The patterns given should not begin with refs/heads
, refs/tags
, or
refs/remotes
when applied to --branches
, --tags
, or --remotes
,
respectively, and they must begin with refs/
when applied to --glob
or --all
. If a trailing '/{asterisk}' is intended, it must be given
explicitly.
But, if you have to use git for-each-ref
, to echo torek's 2017 answer:
2023 (6+ years later): Yes, there is now a convenient way to do this
With Git 2.42 (Q3 2023), enumerating refs in the packed-refs file, while excluding refs that match certain patterns, has been optimized.
And that means you can use git for-each-ref
with the new --exclude
option:
git for-each-ref --format="%(refname:short)" --exclude="inactive-" refs/heads
(The pattern follows fnmatch
though, it is not a true regex)
So:
gitk $(git for-each-ref --format="%(refname:short)" --exclude="inactive-" refs/heads)
See commit 284c55d, commit b571fb9, commit 311bfe1, commit b9f7daa, commit bf1377a (10 Jul 2023) by Jeff King (peff
).
See commit 98456ef, commit 18b6b1b, commit cc2a1f9, commit 15af64d, commit e6bf24d, commit c45841f, commit c489f47, commit 59c35fa, commit d22d941, commit b269ac5, commit 8255dd8 (10 Jul 2023) by Taylor Blau (ttaylorr
).
(Merged by Junio C Hamano -- gitster
-- in commit 39fe402, 21 Jul 2023)
Co-authored-by: Jeff King
Signed-off-by: Jeff King
Signed-off-by: Taylor Blau
When using for-each-ref
, it is sometimes convenient for the caller to be able to exclude certain parts of the references.
For example, if there are many refs/__hidden__/*
references, the caller may want to emit all references except the hidden ones.
Currently, the only way to do this is to post-process the output, like:
$ git for-each-ref --format='%(refname)' | grep -v '^refs/hidden/'
Which is do-able, but requires processing a potentially large quantity of references.
Teach git for-each-ref
(man) a new --exclude=<pattern>
option, which excludes references from the results if they match one or more excluded patterns.
This patch provides a naive implementation where the ref_filter
still sees all references (including ones that it will discard) and is left to check whether each reference matches any excluded pattern(s) before emitting them.
By culling out references we know the caller doesn't care about, we can avoid allocating memory for their storage, as well as spending time sorting the output (among other things).
Even the naive implementation provides a significant speed-up on a modified copy of linux.git (that has a hidden ref pointing at each commit):
$ hyperfine \
'git.compile for-each-ref --format="%(objectname) %(refname)" | grep -vE "[0-9a-f]{40} refs/pull/"' \
'git.compile for-each-ref --format="%(objectname) %(refname)" --exclude refs/pull/'
Benchmark 1: git.compile for-each-ref --format="%(objectname) %(refname)" | grep -vE "[0-9a-f]{40} refs/pull/"
Time (mean ± σ): 820.1 ms ± 2.0 ms [User: 703.7 ms, System: 152.0 ms]
Range (min … max): 817.7 ms … 823.3 ms 10 runs
Benchmark 2: git.compile for-each-ref --format="%(objectname) %(refname)" --exclude refs/pull/
Time (mean ± σ): 106.6 ms ± 1.1 ms [User: 99.4 ms, System: 7.1 ms]
Range (min … max): 104.7 ms … 109.1 ms 27 runs
Summary
'git.compile for-each-ref --format="%(objectname) %(refname)" --exclude refs/pull/' ran
7.69 ± 0.08 times faster than 'git.compile for-each-ref --format="%(objectname) %(refname)" | grep -vE "[0-9a-f]{40} refs/pull/"'
Subsequent patches will improve on this by avoiding visiting excluded sections of the packed-refs
file in certain cases.
git for-each-ref
now includes in its man page:
--exclude=<pattern>
If one or more patterns are given, only refs which do not match
any excluded pattern(s) are shown. Matching is done using the
same rules as <pattern>
above.