Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tell gitk to ignore all branches that match pattern

Tags:

git

gitk

Suppose I have some branches with names beginning with inactive-. As their names suggest, these branches are inactive; I'm keeping around for archival purposes.

I want to tell gitk to ignore those branches, even if I also pass it the --all flag. Is there a way to do this?

Alternatively, is there some other convenient way to tell gitk to include all branches except those whose name matches inactive-*?


P.S. I did try

gitk --branches='!inactive-*'

...and variations thereof, but none worked.

like image 308
kjo Avatar asked Oct 22 '25 00:10

kjo


1 Answers

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)

builtin/for-each-ref.c: add --exclude option

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.

like image 140
VonC Avatar answered Oct 25 '25 05:10

VonC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!