X Tutup
Skip to content

branch: add prefixes to new branch names#2202

Open
valeriyoann wants to merge 3 commits intogit:masterfrom
valeriyoann:branch-with-prefix
Open

branch: add prefixes to new branch names#2202
valeriyoann wants to merge 3 commits intogit:masterfrom
valeriyoann:branch-with-prefix

Conversation

@valeriyoann
Copy link

@valeriyoann valeriyoann commented Feb 17, 2026

This PR adds a way to add prefixes to a new branch being created. The goal is mostly to ease the developer process of creating new branches by adding shortcuts that can be set either with a command-line option or with configuration parameter. This is useful especially when you have to do similar backports on multiple branches, removing a bit of the need for finding names or typing the names over and over again.

Changes since v1:

  • Added a '--no-prefix' option to git branch

Changes since v2:

  • Changed the PR structure, with 3 patches:
    • first patch adds the '--name-prefix' option
    • second adds the 'branch.namePrefix' configuration parameter
    • third adds the '--no-name-prefix' option
  • Those patches only target 'git branch' now

cc: Patrick Steinhardt ps@pks.im
cc: Junio C Hamano gitster@pobox.com
cc: Yoann Valeri yoann.valeri@cea.fr
cc: Eric Sunshine sunshine@sunshineco.com

@gitgitgadget-git
Copy link

Welcome to GitGitGadget

Hi @valeriyoann, and welcome to GitGitGadget, the GitHub App to send patch series to the Git mailing list from GitHub Pull Requests.

Please make sure that either:

  • Your Pull Request has a good description, if it consists of multiple commits, as it will be used as cover letter.
  • Your Pull Request description is empty, if it consists of a single commit, as the commit message should be descriptive enough by itself.

You can CC potential reviewers by adding a footer to the PR description with the following syntax:

CC: Revi Ewer <revi.ewer@example.com>, Ill Takalook <ill.takalook@example.net>

NOTE: DO NOT copy/paste your CC list from a previous GGG PR's description,
because it will result in a malformed CC list on the mailing list. See
example.

Also, it is a good idea to review the commit messages one last time, as the Git project expects them in a quite specific form:

  • the lines should not exceed 76 columns,
  • the first line should be like a header and typically start with a prefix like "tests:" or "revisions:" to state which subsystem the change is about, and
  • the commit messages' body should be describing the "why?" of the change.
  • Finally, the commit messages should end in a Signed-off-by: line matching the commits' author.

It is in general a good idea to await the automated test ("Checks") in this Pull Request before contributing the patches, e.g. to avoid trivial issues such as unportable code.

Contributing the patches

Before you can contribute the patches, your GitHub username needs to be added to the list of permitted users. Any already-permitted user can do that, by adding a comment to your PR of the form /allow. A good way to find other contributors is to locate recent pull requests where someone has been /allowed:

Both the person who commented /allow and the PR author are able to /allow you.

An alternative is the channel #git-devel on the Libera Chat IRC network:

<newcontributor> I've just created my first PR, could someone please /allow me? https://github.com/gitgitgadget/git/pull/12345
<veteran> newcontributor: it is done
<newcontributor> thanks!

Once on the list of permitted usernames, you can contribute the patches to the Git mailing list by adding a PR comment /submit.

If you want to see what email(s) would be sent for a /submit request, add a PR comment /preview to have the email(s) sent to you. You must have a public GitHub email address for this. Note that any reviewers CC'd via the list in the PR description will not actually be sent emails.

After you submit, GitGitGadget will respond with another comment that contains the link to the cover letter mail in the Git mailing list archive. Please make sure to monitor the discussion in that thread and to address comments and suggestions (while the comments and suggestions will be mirrored into the PR by GitGitGadget, you will still want to reply via mail).

If you do not want to subscribe to the Git mailing list just to be able to respond to a mail, you can download the mbox from the Git mailing list archive (click the (raw) link), then import it into your mail program. If you use GMail, you can do this via:

curl -g --user "<EMailAddress>:<Password>" \
    --url "imaps://imap.gmail.com/INBOX" -T /path/to/raw.txt

To iterate on your change, i.e. send a revised patch or patch series, you will first want to (force-)push to the same branch. You probably also want to modify your Pull Request description (or title). It is a good idea to summarize the revision by adding something like this to the cover letter (read: by editing the first comment on the PR, i.e. the PR description):

Changes since v1:
- Fixed a typo in the commit message (found by ...)
- Added a code comment to ... as suggested by ...
...

To send a new iteration, just add another PR comment with the contents: /submit.

Need help?

New contributors who want advice are encouraged to join git-mentoring@googlegroups.com, where volunteers who regularly contribute to Git are willing to answer newbie questions, give advice, or otherwise provide mentoring to interested contributors. You must join in order to post or view messages, but anyone can join.

You may also be able to find help in real time in the developer IRC channel, #git-devel on Libera Chat. Remember that IRC does not support offline messaging, so if you send someone a private message and log out, they cannot respond to you. The scrollback of #git-devel is archived, though.

@gitgitgadget-git
Copy link

There is an issue in commit d47d061:
branch: add 'branch.addCurrentBranchAsPrefix' config param

  • Commit not signed off

@valeriyoann valeriyoann force-pushed the branch-with-prefix branch 2 times, most recently from c2f18f8 to 0124424 Compare February 17, 2026 13:00
@dscho
Copy link
Member

dscho commented Feb 17, 2026

/allow

@gitgitgadget-git
Copy link

User valeriyoann is now allowed to use GitGitGadget.

WARNING: valeriyoann has no public email address set on GitHub; GitGitGadget needs an email address to Cc: you on your contribution, so that you receive any feedback on the Git mailing list. Go to https://github.com/settings/profile to make your preferred email public to let GitGitGadget know which email address to use.

@dscho
Copy link
Member

dscho commented Feb 17, 2026

@valeriyoann you asked on IRC for help with the failing tests that you could not replicate locally. The failing tests run in the *-leaks jobs, which enable the AddressSanitizer leak checking (which you can only replicate locally if you also set SANITIZE=leak before building, like the CI jobs).

It is admittedly convoluted, thanks to Git's CI configuration, to see the actual error messages, I guess that the authors of the *-leaks jobs were not actually interested in making the errors helpful :-(

Here is the actually interesting part of the log:

The leak error messages
[...]
=================================================================
==git==214936==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f29b863e8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55c1a796b783 in xrealloc wrapper.c:140
    #2 0x55c1a791e928 in strbuf_grow strbuf.c:114
    #3 0x55c1a791f538 in strbuf_add strbuf.c:313
    #4 0x55c1a774bf91 in strbuf_addstr strbuf.h:310
    #5 0x55c1a774cedf in add_branch_prefix branch.c:379
    #6 0x55c1a7605651 in cmd_branch builtin/branch.c:1007
    #7 0x55c1a75ebdee in run_builtin git.c:506
    #8 0x55c1a75ec309 in handle_builtin git.c:780
    #9 0x55c1a75ec62d in run_argv git.c:863
    #10 0x55c1a75ecaf0 in cmd_main git.c:985
    #11 0x55c1a771cb89 in main common-main.c:9
    #12 0x7f29b83ef574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f29b83ef627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55c1a75e9da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==215815==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fd3702848eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x563bff99e783 in xrealloc wrapper.c:140
    #2 0x563bff951928 in strbuf_grow strbuf.c:114
    #3 0x563bff952538 in strbuf_add strbuf.c:313
    #4 0x563bff77ef91 in strbuf_addstr strbuf.h:310
    #5 0x563bff77fedf in add_branch_prefix branch.c:379
    #6 0x563bff638651 in cmd_branch builtin/branch.c:1007
    #7 0x563bff61edee in run_builtin git.c:506
    #8 0x563bff61f309 in handle_builtin git.c:780
    #9 0x563bff61f62d in run_argv git.c:863
    #10 0x563bff61faf0 in cmd_main git.c:985
    #11 0x563bff74fb89 in main common-main.c:9
    #12 0x7fd370035574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7fd370035627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x563bff61cda4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==216513==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f35002c18eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55fa95a4f783 in xrealloc wrapper.c:140
    #2 0x55fa95a02928 in strbuf_grow strbuf.c:114
    #3 0x55fa95a03538 in strbuf_add strbuf.c:313
    #4 0x55fa9582ff91 in strbuf_addstr strbuf.h:310
    #5 0x55fa95830edf in add_branch_prefix branch.c:379
    #6 0x55fa956e9651 in cmd_branch builtin/branch.c:1007
    #7 0x55fa956cfdee in run_builtin git.c:506
    #8 0x55fa956d0309 in handle_builtin git.c:780
    #9 0x55fa956d062d in run_argv git.c:863
    #10 0x55fa956d0af0 in cmd_main git.c:985
    #11 0x55fa95800b89 in main common-main.c:9
    #12 0x7f3500072574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f3500072627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55fa956cdda4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==217140==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f39d8b6d8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55c9cdcb5783 in xrealloc wrapper.c:140
    #2 0x55c9cdc68928 in strbuf_grow strbuf.c:114
    #3 0x55c9cdc69538 in strbuf_add strbuf.c:313
    #4 0x55c9cda95f91 in strbuf_addstr strbuf.h:310
    #5 0x55c9cda96edf in add_branch_prefix branch.c:379
    #6 0x55c9cd94f651 in cmd_branch builtin/branch.c:1007
    #7 0x55c9cd935dee in run_builtin git.c:506
    #8 0x55c9cd936309 in handle_builtin git.c:780
    #9 0x55c9cd93662d in run_argv git.c:863
    #10 0x55c9cd936af0 in cmd_main git.c:985
    #11 0x55c9cda66b89 in main common-main.c:9
    #12 0x7f39d891e574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f39d891e627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55c9cd933da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==217855==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f47ddb8f8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x558424bd1783 in xrealloc wrapper.c:140
    #2 0x558424b84928 in strbuf_grow strbuf.c:114
    #3 0x558424b85538 in strbuf_add strbuf.c:313
    #4 0x5584249b1f91 in strbuf_addstr strbuf.h:310
    #5 0x5584249b2edf in add_branch_prefix branch.c:379
    #6 0x55842486b651 in cmd_branch builtin/branch.c:1007
    #7 0x558424851dee in run_builtin git.c:506
    #8 0x558424852309 in handle_builtin git.c:780
    #9 0x55842485262d in run_argv git.c:863
    #10 0x558424852af0 in cmd_main git.c:985
    #11 0x558424982b89 in main common-main.c:9
    #12 0x7f47dd940574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f47dd940627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55842484fda4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==218794==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f4782d408eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55ec23c87783 in xrealloc wrapper.c:140
    #2 0x55ec23c3a928 in strbuf_grow strbuf.c:114
    #3 0x55ec23c3b538 in strbuf_add strbuf.c:313
    #4 0x55ec23a67f91 in strbuf_addstr strbuf.h:310
    #5 0x55ec23a68edf in add_branch_prefix branch.c:379
    #6 0x55ec23921651 in cmd_branch builtin/branch.c:1007
    #7 0x55ec23907dee in run_builtin git.c:506
    #8 0x55ec23908309 in handle_builtin git.c:780
    #9 0x55ec2390862d in run_argv git.c:863
    #10 0x55ec23908af0 in cmd_main git.c:985
    #11 0x55ec23a38b89 in main common-main.c:9
    #12 0x7f4782af1574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f4782af1627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55ec23905da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==220019==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fa6a98f68eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x56387cef4783 in xrealloc wrapper.c:140
    #2 0x56387cea7928 in strbuf_grow strbuf.c:114
    #3 0x56387cea8538 in strbuf_add strbuf.c:313
    #4 0x56387ccd4f91 in strbuf_addstr strbuf.h:310
    #5 0x56387ccd5edf in add_branch_prefix branch.c:379
    #6 0x56387cb8e651 in cmd_branch builtin/branch.c:1007
    #7 0x56387cb74dee in run_builtin git.c:506
    #8 0x56387cb75309 in handle_builtin git.c:780
    #9 0x56387cb7562d in run_argv git.c:863
    #10 0x56387cb75af0 in cmd_main git.c:985
    #11 0x56387cca5b89 in main common-main.c:9
    #12 0x7fa6a96a7574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7fa6a96a7627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x56387cb72da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==222315==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f2769d408eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x5608a18cd783 in xrealloc wrapper.c:140
    #2 0x5608a1880928 in strbuf_grow strbuf.c:114
    #3 0x5608a1881538 in strbuf_add strbuf.c:313
    #4 0x5608a16adf91 in strbuf_addstr strbuf.h:310
    #5 0x5608a16aeedf in add_branch_prefix branch.c:379
    #6 0x5608a1567651 in cmd_branch builtin/branch.c:1007
    #7 0x5608a154ddee in run_builtin git.c:506
    #8 0x5608a154e309 in handle_builtin git.c:780
    #9 0x5608a154e62d in run_argv git.c:863
    #10 0x5608a154eaf0 in cmd_main git.c:985
    #11 0x5608a167eb89 in main common-main.c:9
    #12 0x7f2769af1574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f2769af1627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x5608a154bda4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==224380==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f0e5b15d8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55d562a88783 in xrealloc wrapper.c:140
    #2 0x55d562a3b928 in strbuf_grow strbuf.c:114
    #3 0x55d562a3c538 in strbuf_add strbuf.c:313
    #4 0x55d562868f91 in strbuf_addstr strbuf.h:310
    #5 0x55d562869edf in add_branch_prefix branch.c:379
    #6 0x55d562722651 in cmd_branch builtin/branch.c:1007
    #7 0x55d562708dee in run_builtin git.c:506
    #8 0x55d562709309 in handle_builtin git.c:780
    #9 0x55d56270962d in run_argv git.c:863
    #10 0x55d562709af0 in cmd_main git.c:985
    #11 0x55d562839b89 in main common-main.c:9
    #12 0x7f0e5af0e574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f0e5af0e627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55d562706da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==224824==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7feb54aee8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x5584acab1783 in xrealloc wrapper.c:140
    #2 0x5584aca64928 in strbuf_grow strbuf.c:114
    #3 0x5584aca65538 in strbuf_add strbuf.c:313
    #4 0x5584ac891f91 in strbuf_addstr strbuf.h:310
    #5 0x5584ac892edf in add_branch_prefix branch.c:379
    #6 0x5584ac74b651 in cmd_branch builtin/branch.c:1007
    #7 0x5584ac731dee in run_builtin git.c:506
    #8 0x5584ac732309 in handle_builtin git.c:780
    #9 0x5584ac73262d in run_argv git.c:863
    #10 0x5584ac732af0 in cmd_main git.c:985
    #11 0x5584ac862b89 in main common-main.c:9
    #12 0x7feb5489f574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7feb5489f627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x5584ac72fda4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==225590==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f41426b08eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55966fa8f783 in xrealloc wrapper.c:140
    #2 0x55966fa42928 in strbuf_grow strbuf.c:114
    #3 0x55966fa43538 in strbuf_add strbuf.c:313
    #4 0x55966f86ff91 in strbuf_addstr strbuf.h:310
    #5 0x55966f870edf in add_branch_prefix branch.c:379
    #6 0x55966f729651 in cmd_branch builtin/branch.c:1007
    #7 0x55966f70fdee in run_builtin git.c:506
    #8 0x55966f710309 in handle_builtin git.c:780
    #9 0x55966f71062d in run_argv git.c:863
    #10 0x55966f710af0 in cmd_main git.c:985
    #11 0x55966f840b89 in main common-main.c:9
    #12 0x7f4142461574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f4142461627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55966f70dda4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==226263==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f67c18d68eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55cfbac74783 in xrealloc wrapper.c:140
    #2 0x55cfbac27928 in strbuf_grow strbuf.c:114
    #3 0x55cfbac28538 in strbuf_add strbuf.c:313
    #4 0x55cfbaa54f91 in strbuf_addstr strbuf.h:310
    #5 0x55cfbaa55edf in add_branch_prefix branch.c:379
    #6 0x55cfba90e651 in cmd_branch builtin/branch.c:1007
    #7 0x55cfba8f4dee in run_builtin git.c:506
    #8 0x55cfba8f5309 in handle_builtin git.c:780
    #9 0x55cfba8f562d in run_argv git.c:863
    #10 0x55cfba8f5af0 in cmd_main git.c:985
    #11 0x55cfbaa25b89 in main common-main.c:9
    #12 0x7f67c1687574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f67c1687627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55cfba8f2da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==229554==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f9d88cfb8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x556fda41c783 in xrealloc wrapper.c:140
    #2 0x556fda3cf928 in strbuf_grow strbuf.c:114
    #3 0x556fda3d0538 in strbuf_add strbuf.c:313
    #4 0x556fda1fcf91 in strbuf_addstr strbuf.h:310
    #5 0x556fda1fdedf in add_branch_prefix branch.c:379
    #6 0x556fda0b6651 in cmd_branch builtin/branch.c:1007
    #7 0x556fda09cdee in run_builtin git.c:506
    #8 0x556fda09d309 in handle_builtin git.c:780
    #9 0x556fda09d62d in run_argv git.c:863
    #10 0x556fda09daf0 in cmd_main git.c:985
    #11 0x556fda1cdb89 in main common-main.c:9
    #12 0x7f9d88aac574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f9d88aac627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x556fda09ada4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==229555==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f481e27a8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x555ba7148783 in xrealloc wrapper.c:140
    #2 0x555ba70fb928 in strbuf_grow strbuf.c:114
    #3 0x555ba70fc538 in strbuf_add strbuf.c:313
    #4 0x555ba6f28f91 in strbuf_addstr strbuf.h:310
    #5 0x555ba6f29edf in add_branch_prefix branch.c:379
    #6 0x555ba6de2651 in cmd_branch builtin/branch.c:1007
    #7 0x555ba6dc8dee in run_builtin git.c:506
    #8 0x555ba6dc9309 in handle_builtin git.c:780
    #9 0x555ba6dc962d in run_argv git.c:863
    #10 0x555ba6dc9af0 in cmd_main git.c:985
    #11 0x555ba6ef9b89 in main common-main.c:9
    #12 0x7f481e02b574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f481e02b627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x555ba6dc6da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==232477==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f8de766b8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55ec92384783 in xrealloc wrapper.c:140
    #2 0x55ec92337928 in strbuf_grow strbuf.c:114
    #3 0x55ec92338538 in strbuf_add strbuf.c:313
    #4 0x55ec92164f91 in strbuf_addstr strbuf.h:310
    #5 0x55ec92165edf in add_branch_prefix branch.c:379
    #6 0x55ec9201e651 in cmd_branch builtin/branch.c:1007
    #7 0x55ec92004dee in run_builtin git.c:506
    #8 0x55ec92005309 in handle_builtin git.c:780
    #9 0x55ec9200562d in run_argv git.c:863
    #10 0x55ec92005af0 in cmd_main git.c:985
    #11 0x55ec92135b89 in main common-main.c:9
    #12 0x7f8de741c574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f8de741c627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55ec92002da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==233327==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7ff16e91a8eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55ae28d5b783 in xrealloc wrapper.c:140
    #2 0x55ae28d0e928 in strbuf_grow strbuf.c:114
    #3 0x55ae28d0f538 in strbuf_add strbuf.c:313
    #4 0x55ae28b3bf91 in strbuf_addstr strbuf.h:310
    #5 0x55ae28b3cedf in add_branch_prefix branch.c:379
    #6 0x55ae289f5651 in cmd_branch builtin/branch.c:1007
    #7 0x55ae289dbdee in run_builtin git.c:506
    #8 0x55ae289dc309 in handle_builtin git.c:780
    #9 0x55ae289dc62d in run_argv git.c:863
    #10 0x55ae289dcaf0 in cmd_main git.c:985
    #11 0x55ae28b0cb89 in main common-main.c:9
    #12 0x7ff16e6cb574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7ff16e6cb627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55ae289d9da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==234197==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f596f6d88eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55cc132e2783 in xrealloc wrapper.c:140
    #2 0x55cc13295928 in strbuf_grow strbuf.c:114
    #3 0x55cc13296538 in strbuf_add strbuf.c:313
    #4 0x55cc130c2f91 in strbuf_addstr strbuf.h:310
    #5 0x55cc130c3edf in add_branch_prefix branch.c:379
    #6 0x55cc12f7c651 in cmd_branch builtin/branch.c:1007
    #7 0x55cc12f62dee in run_builtin git.c:506
    #8 0x55cc12f63309 in handle_builtin git.c:780
    #9 0x55cc12f6362d in run_argv git.c:863
    #10 0x55cc12f63af0 in cmd_main git.c:985
    #11 0x55cc13093b89 in main common-main.c:9
    #12 0x7f596f489574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7f596f489627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55cc12f60da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==234747==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fc190c728eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x55e6481e0783 in xrealloc wrapper.c:140
    #2 0x55e648193928 in strbuf_grow strbuf.c:114
    #3 0x55e648194538 in strbuf_add strbuf.c:313
    #4 0x55e647fc0f91 in strbuf_addstr strbuf.h:310
    #5 0x55e647fc1edf in add_branch_prefix branch.c:379
    #6 0x55e647e7a651 in cmd_branch builtin/branch.c:1007
    #7 0x55e647e60dee in run_builtin git.c:506
    #8 0x55e647e61309 in handle_builtin git.c:780
    #9 0x55e647e6162d in run_argv git.c:863
    #10 0x55e647e61af0 in cmd_main git.c:985
    #11 0x55e647f91b89 in main common-main.c:9
    #12 0x7fc190a23574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7fc190a23627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x55e647e5eda4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).

=================================================================
==git==235559==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7ff55fa078eb in realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:99
    #1 0x563a182e9783 in xrealloc wrapper.c:140
    #2 0x563a1829c928 in strbuf_grow strbuf.c:114
    #3 0x563a1829d538 in strbuf_add strbuf.c:313
    #4 0x563a180c9f91 in strbuf_addstr strbuf.h:310
    #5 0x563a180caedf in add_branch_prefix branch.c:379
    #6 0x563a17f83651 in cmd_branch builtin/branch.c:1007
    #7 0x563a17f69dee in run_builtin git.c:506
    #8 0x563a17f6a309 in handle_builtin git.c:780
    #9 0x563a17f6a62d in run_argv git.c:863
    #10 0x563a17f6aaf0 in cmd_main git.c:985
    #11 0x563a1809ab89 in main common-main.c:9
    #12 0x7ff55f7b8574  (/lib/x86_64-linux-gnu/libc.so.6+0x2a574) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #13 0x7ff55f7b8627 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a627) (BuildId: a5b27db7ef3036c1dacf2e4ddc2e052767129439)
    #14 0x563a17f67da4 in _start (git+0x1fda4) (BuildId: e47a92a08c1ad825ab853bd9b269426cf5d41a19)

DEDUP_TOKEN: ___interceptor_realloc--xrealloc--strbuf_grow--strbuf_add--strbuf_addstr--add_branch_prefix--cmd_branch--run_builtin--handle_builtin--run_argv--cmd_main--main----__libc_start_main--_start
SUMMARY: LeakSanitizer: 24 byte(s) leaked in 1 allocation(s).
Our logs revealed a memory leak...

The reason for this is that the newly-added add_branch_prefix() call allocates memory, which is correctly released iff recurse_submodules is zero. But if it is non-zero, there is a goto out that forces that strbuf_release() call to be skipped, and the memory leaks.

I suggest to add another strbuf_release(&new_branch_name); call inside the if (recurse_submodules) block, it's inelegant to duplicate the logic, but we do not really have any alternative to that, Git is full of such code patterns.

@valeriyoann
Copy link
Author

/allow

Thanks a lot for the /allow!

And also thanks for the explanation, I indeed did not check other parts of the CI, only the steps that failed.
Added your suggestion, with a little bit of improvement on the code to avoid duplication.

@valeriyoann valeriyoann force-pushed the branch-with-prefix branch 2 times, most recently from 0178d02 to 30a6d8e Compare February 18, 2026 15:02
@valeriyoann
Copy link
Author

/submit

@gitgitgadget-git
Copy link

Submitted as pull.2202.git.git.1771574833967.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2202/valeriyoann/branch-with-prefix-v1

To fetch this version to local tag pr-git-2202/valeriyoann/branch-with-prefix-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2202/valeriyoann/branch-with-prefix-v1

@gitgitgadget-git
Copy link

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Yoann Valeri via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: VALERI Yoann <yoann.valeri@cea.fr>
>
> This patch adds a new configuration parameter for the branch creation
> feature: 'branch.addCurrentBranchAsPrefix'. When set to true, if one

We generally do not add a configuration variable before the concept
proves useful by being available as a command line option for some
time.  Have we had a command line option that corresponds to this
feature for a year or two?  Such a command line option will be
necessary even after we decide to add a configuration variable to
allow users to override the configured value per-invocation basis,
e.g., "git branch --no-current-branch-prefix maint-2.54 v2.54.0",
when you want to use the feature for most of your branches but want
to deviate from that convention in selected cases.

Thanks.

@gitgitgadget-git
Copy link

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

By the way, the address at @cea.fr used as the author ident and for
sign-off seems to be bouncing, due to "550 mailbox unavailable".

Two requests:

 * To the author of the patch.  Could you make sure to sign-off with
   reachable e-mail address?  It cannot be helped that years after a
   patch is written, the author may become unreachable, but we do
   not want to see it happen even before we accept the patch.

 * To GitGitGadget maintainers.  Could you think about ways to catch
   an incident like this, perhaps by sending a ping e-mail to first
   time contributors to request response before allowing /submit or
   something?


@valeriyoann valeriyoann force-pushed the branch-with-prefix branch 3 times, most recently from 03cccd9 to 0fbdf03 Compare February 27, 2026 13:18
@valeriyoann
Copy link
Author

/submit

@gitgitgadget-git
Copy link

Submitted as pull.2202.v2.git.git.1772207333.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2202/valeriyoann/branch-with-prefix-v2

To fetch this version to local tag pr-git-2202/valeriyoann/branch-with-prefix-v2:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2202/valeriyoann/branch-with-prefix-v2

@@ -713,7 +713,8 @@ int cmd_branch(int argc,
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"VALERI Yoann via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: VALERI Yoann <yoann.valeri@cea.fr>
>
> This patch adds a '--no-prefix' option to 'git branch' to selectively
> override the 'branch.addCurrentBranchAsPrefix' configuration parameter.
> Signed-off-by: VALERI Yoann <yoann.valeri@cea.fr>
> ---

That is unusual in multiple ways.

The usual way to do so is to give a command line option that is
usable without needing any configuration.  This happens first in
early patches in a series.

And then, assuming that the command line option is widely supported
as useful (but cumbersome to specify every time), help the users by
adding a configuration variable, that can be overridden via the
command line option.  That happens next in later patches in a
series.

And in order to help users discover these two features more easily,
it is customery to give them very similar names.  In other words,
adding "--[no-]prefix-current-branch-name" may be more
understandable if it is added in patch [1/2], if we want to make the
matching configuration "branch.addCurrentBranchAsPrefix" in patch
[2/2].

Even better, have you considered leaving the door open for _others_
to come up with better ideas _later_ by making it extensible, e.g.,

    --no-name-prefix
    --name-prefix=<token>

where the initial implementation the only supported <token> is
"current" (to signal "current branch name")?  That would mean that
the corresponding configuration variable would also be a string, not
a boolean, e.g., "branch.namePrefix = current".

Perhaps those who work with more than one remotes want to give their
branches meant to be pushed to remote A with prefix A- while naming
the branches meant to be pushed to remote B with prefix B-, or
something, that is not based on the current branch but something
else (e.g., @{push} in this hypothetical example).  I am not saying
that you should add such a support to the feature in this series
(quite honestly, I am not convinced at all if prefixing with the
current branch name is even something worth adding myself), but we
do not want to end up with millions of branch.add${Foo}AsPrefix with
different values of ${Foo} when we discover that such prefixing
scheme is useful in the future.

Thanks.

This patch adds a '--name-prefix' option to add a prefix to a newly
created branch. It can use a regular string or a token as prefix. The
only token currently handled is '@{current}', which is substituted for
the current branch's name.

Signed-off-by: VALERI Yoann <yoann.valeri@cea.fr>
This patch adds a new configuration parameter for the branch creation
feature: 'branch.namePrefix'. It corresponds to the '--name-prefix'
option of 'git branch' made as configuration parameter, and behaves
exactly like it.

Signed-off-by: VALERI Yoann <yoann.valeri@cea.fr>
This patch adds the '--no-name-prefix' option to prevent adding any
prefix to the branch being created, whether through the '--name-prefix'
option or the 'branch.namePrefix' configuration parameter.
Signed-off-by: VALERI Yoann <yoann.valeri@cea.fr>
Copy link

@Anjalo133 Anjalo133 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mg

@Anjalo133
Copy link

H

@valeriyoann valeriyoann changed the title branch: add 'branch.addCurrentBranchAsPrefix' config param branch: add prefixes to new branch names Mar 6, 2026
@valeriyoann
Copy link
Author

/submit

@gitgitgadget-git
Copy link

Submitted as pull.2202.v3.git.git.1772802872.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2202/valeriyoann/branch-with-prefix-v3

To fetch this version to local tag pr-git-2202/valeriyoann/branch-with-prefix-v3:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2202/valeriyoann/branch-with-prefix-v3

@gitgitgadget-git
Copy link

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Yoann Valeri via GitGitGadget" <gitgitgadget@gmail.com> writes:

> This PR adds a way to add prefixes to a new branch being created. The goal
> is mostly to ease the developer process of creating new branches by adding
> shortcuts that can be set either with a command-line option or with
> configuration parameter. This is useful especially when you have to do
> similar backports on multiple branches, removing a bit of the need for
> finding names or typing the names over and over again.
>
> Changes since v1:
>
>  * Added a '--no-prefix' option to git branch
>
> Changes since v2:
>
>  * Changed the PR structure, with 3 patches:
>    * first patch adds the '--name-prefix' option
>    * second adds the 'branch.namePrefix' configuration parameter
>    * third adds the '--no-name-prefix' option
>  * Those patches only target 'git branch' now

I haven't read the actual patches, but the first step that adds
"--name-prefix" should also support "--no-name-prefix" at the same
time, with or without patches 2 and 3.  Doing so would allow users
with an alias

    [alias] bn = branch --name-prefix=blah

, who want to almost always add "blah" to their branches, to defeat
the prefix in rare occasions with

    $ git bn --no-name-prefix foo

@@ -713,7 +713,8 @@ int cmd_branch(int argc,
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"VALERI Yoann via GitGitGadget" <gitgitgadget@gmail.com> writes:

> -		OPT_STRING(0, "name-prefix", &name_prefix, N_("name"), N_("prefix for the branch to create")),
> +		OPT_STRING_F(0, "name-prefix", &name_prefix, N_("name"), N_("prefix for the branch to create"), PARSE_OPT_NONEG),
> +		OPT_BOOL(0, "no-name-prefix", &no_name_prefix, N_("do not use any prefix for the branch to create")),

You do not want a separate "no-*" entry in the options[] table.
If we look at parse-options.c to see how OPTION_STRING is handled,
we find:

	case OPTION_STRING:
		if (unset)
			*(const char **)opt->value = NULL;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			*(const char **)opt->value = (const char *)opt->defval;
		else
			return get_arg(p, opt, flags, (const char **)opt->value);
		return 0;

which tells us

 * "--no-name-prefix" is caught by "if (unset)" and causes the
   name_prefix variable set to NULL.

 * if we give OPT_OPTARG, we can allow "--name-prefix" (with no
   parameter) to default to opt->defval value; this feature is not
   very useful in our application.

 * Otherwise we get the string after "--name-prefix=".

So you do not need to do anything strange.  To correctly implement
the order of handling configuration and command line, you would do:

 * initialize name_prefix to NULL.  By default no name_prefix is
   used.

 * early in the cmd_branch() before you call parse_options(),
   consult the configuration and pick up branch.nameprefix
   and set it to name_prefix variable.

 * then you call parse_options().  If the command line has
   "--no-name-prefix", "if (unset)" kicks in and clears the
   name_prefix variable pointed at by the opt->value.  If the
   command line has "--name-prefix=blah", the name_prefix variable,
   which may have obtained a value from the configuration, is
   overwritten with "blah".  If the command line does not do
   anything, then the name_prefix variable will retain whatever
   value it got from the configuration.



@gitgitgadget-git
Copy link

Eric Sunshine wrote on the Git mailing list (how to reply to this email):

On Fri, Mar 6, 2026 at 8:14 AM Yoann Valeri via GitGitGadget
<gitgitgadget@gmail.com> wrote:
> This PR adds a way to add prefixes to a new branch being created. The goal
> is mostly to ease the developer process of creating new branches by adding
> shortcuts that can be set either with a command-line option or with
> configuration parameter. This is useful especially when you have to do
> similar backports on multiple branches, removing a bit of the need for
> finding names or typing the names over and over again.

Sorry, but I'm having trouble understanding the value of this patch
series. Neither the cover letter nor the patches themselves provide
enough context to really understand how this feature would be helpful.
Adding some real-world examples of how this simplifies your workflow
*might* help sell the idea. Without such examples, it's difficult to
imagine that you can't achieve the same with some simple aliases or
tooling/scripting on your side.

My other concern is that this implementation is too special-case by
assuming that users will only want to apply the "special value" as a
prefix. It is easy to imagine some users instead wanting the special
value added as a suffix or embedded. As such, a (possibly) more
palatable implementation (assuming this feature is even desirable at
all) might be to instead allow the user to specify some sort of format
string into which the special value (or values) is interpolated.

@gitgitgadget-git
Copy link

User Eric Sunshine <sunshine@sunshineco.com> has been added to the cc: list.

@@ -17,7 +17,8 @@ git branch [--color[=<when>] | --no-color] [--show-current]
[(-r|--remotes) | (-a|--all)]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eric Sunshine wrote on the Git mailing list (how to reply to this email):

On Fri, Mar 6, 2026 at 8:15 AM VALERI Yoann via GitGitGadget
<gitgitgadget@gmail.com> wrote:
> This patch adds a '--name-prefix' option to add a prefix to a newly
> created branch. It can use a regular string or a token as prefix. The
> only token currently handled is '@{current}', which is substituted for
> the current branch's name.
>
> Signed-off-by: VALERI Yoann <yoann.valeri@cea.fr>
> ---
> diff --git a/Documentation/git-branch.adoc b/Documentation/git-branch.adoc
> @@ -64,6 +65,10 @@ Note that this will create the new branch, but it will not switch the
> +With a `--name-prefix` option, you can add a prefix to the branch to create.
> +This can either a simple name, or a token. Currently, only '@{current}' is
> +managed as token, and will use the current branch name as prefix.

s/This can/& be/

> diff --git a/branch.c b/branch.c
> @@ -365,6 +365,23 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name)
> +void add_branch_prefix(const char *name_prefix,
> +                                          const char *current_branch, struct strbuf *buf)
> +{
> +       int value = 0;

What is `value`? It doesn't seem to be used at all in this function.

> +       if (!name_prefix)
> +               return;
> +
> +       if (name_prefix[0] != '@') {
> +               strbuf_addstr(buf, name_prefix);
> +               return;
> +       }
> +
> +       if (strcmp(name_prefix, "@{current}") == 0)
> +               strbuf_addstr(buf, current_branch);
> +}

I would expect this function to produce some sort of diagnostic
warning when the user has given it a "@{token}" it doesn't recognize.

> diff --git a/branch.h b/branch.h
> @@ -148,6 +148,18 @@ int install_branch_config(int flag, const char *local, const char *origin, const
> +/*
> + * Store in 'buf' a prefix to the name of a branch to create by using the given
> + * string 'name_prefix'. It can either be a simple string to a shorthand
> + * starting with '@'.
> + *
> + * Currently, only '@{current}' is managed, and will use 'current_branch' as
> + * prefix.
> + */
> +void add_branch_prefix(const char *name_prefix, const char *current_branch,
> +                                          struct strbuf *buf);

It feels unnecessarily burdensome to force the caller to compute and
pass in `current_branch`. Intuitively, one would expect
add_branch_prefix() to compute the current branch itself if it
discovers that "@{current}" has been requested.

Moveover, this approach will not scale well when support for
additional "@{tokens}" is added down the road since it burdens *all*
callers with providing the values for *all* possible tokens.

> diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
> @@ -1716,4 +1716,22 @@ test_expect_success 'errors if given a bad branch name' '
> +test_expect_success 'create branch with --name-prefix' '
> +       git config branch.autosetupmerge false &&

Let's use `test_config` which will ensure that this setting is
reverted at the end of the test.


> +       git branch branch-with-prefix &&
> +       git branch --name-prefix "blob" -- -with-prefix &&
> +       test_must_fail git branch --name-prefix "blob" -- -with-prefix &&
> +       git branch --name-prefix "@{current}" -- -with-prefix &&
> +       git switch blob-with-prefix &&
> +       git branch --name-prefix "@{current}" -- -with-prefix &&
> +       test_must_fail git branch --name-prefix "@{current}" -- -with-prefix &&
> +       test_ref_exists refs/heads/branch-with-prefix &&
> +       test_ref_exists refs/heads/main-with-prefix &&
> +       test_ref_exists refs/heads/blob-with-prefix &&
> +       test_ref_exists refs/heads/blob-with-prefix-with-prefix &&
> +       git checkout main &&
> +       git branch -D branch-with-prefix main-with-prefix blob-with-prefix &&
> +       git branch -D blob-with-prefix-with-prefix
> +'

@@ -35,6 +35,11 @@ This option defaults to `never`.
value of this variable will be used as the default.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eric Sunshine wrote on the Git mailing list (how to reply to this email):

On Fri, Mar 6, 2026 at 8:15 AM VALERI Yoann via GitGitGadget
<gitgitgadget@gmail.com> wrote:
> This patch adds a new configuration parameter for the branch creation
> feature: 'branch.namePrefix'. It corresponds to the '--name-prefix'
> option of 'git branch' made as configuration parameter, and behaves
> exactly like it.
>
> Signed-off-by: VALERI Yoann <yoann.valeri@cea.fr>
> ---
> diff --git a/Documentation/config/branch.adoc b/Documentation/config/branch.adoc
> @@ -35,6 +35,11 @@ This option defaults to `never`.
> +`branch.namePrefix`::
> +       When a new branch is created with `git branch`, use the provided value as
> +       prefix for its name. Can be '@{current}' to use the current branch's name
> +       as prefix.

This probably ought to mention --[no]-name-prefix to let the user know
that the configuration value can be overridden.

> diff --git a/branch.c b/branch.c
> @@ -368,18 +368,22 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name)
>  void add_branch_prefix(const char *name_prefix,
>                                            const char *current_branch, struct strbuf *buf)
>  {
> -       int value = 0;
> +       char *config_prefix = NULL;
>
> -       if (!name_prefix)
> -               return;
> +       if (!name_prefix) {
> +               if (repo_config_get_string(the_repository, "branch.namePrefix",
> +                                                                  &config_prefix))
> +                       return;
>
> -       if (name_prefix[0] != '@') {
> -               strbuf_addstr(buf, name_prefix);
> -               return;
> +               name_prefix = config_prefix;
>         }
>
> -       if (strcmp(name_prefix, "@{current}") == 0)
> +       if (name_prefix[0] != '@')
> +               strbuf_addstr(buf, name_prefix);
> +       else if (strcmp(name_prefix, "@{current}") == 0)
>                 strbuf_addstr(buf, current_branch);
> +
> +    free(config_prefix);
>  }

This "diff" is very difficult to read because it's rewriting much of
the logic which was first introduced in patch [1/3]. When you reroll,
it would be a good idea to get the overall logic straight in patch
[1/3] so that subsequent patches only make small changes to it to
improve it (if necessary).

@gitgitgadget-git
Copy link

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Eric Sunshine <sunshine@sunshineco.com> writes:

> Sorry, but I'm having trouble understanding the value of this patch
> series. Neither the cover letter nor the patches themselves provide
> enough context to really understand how this feature would be helpful.
> Adding some real-world examples of how this simplifies your workflow
> *might* help sell the idea. Without such examples, it's difficult to
> imagine that you can't achieve the same with some simple aliases or
> tooling/scripting on your side.

Very reasonable suggestion.  Thanks.

@@ -17,7 +17,8 @@ git branch [--color[=<when>] | --no-color] [--show-current]
[(-r|--remotes) | (-a|--all)]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"VALERI Yoann via GitGitGadget" <gitgitgadget@gmail.com> writes:

> diff --git a/Documentation/git-branch.adoc b/Documentation/git-branch.adoc
> index c0afddc424..00967fa758 100644
> --- a/Documentation/git-branch.adoc
> +++ b/Documentation/git-branch.adoc
> @@ -17,7 +17,8 @@ git branch [--color[=<when>] | --no-color] [--show-current]
>  	   [(-r|--remotes) | (-a|--all)]
>  	   [--list] [<pattern>...]
>  git branch [--track[=(direct|inherit)] | --no-track] [-f]
> -	   [--recurse-submodules] <branch-name> [<start-point>]
> +	   [--recurse-submodules] [--name-prefix=<token>]
> +           <branch-name> [<start-point>]

The indentation of the last line seems a bit off; the previous line
uses leading HT both in the original and in the updated version, but
the last line uses SP indent.

> @@ -64,6 +65,10 @@ Note that this will create the new branch, but it will not switch the
>  working tree to it; use `git switch <new-branch>` to switch to the
>  new branch.
>  
> +With a `--name-prefix` option, you can add a prefix to the branch to create.
> +This can either a simple name, or a token. Currently, only '@{current}' is
> +managed as token, and will use the current branch name as prefix.

"can either" -> "can either be".
"managed" -> "supported".

> @@ -319,6 +324,10 @@ superproject's "origin/main", but tracks the submodule's "origin/main".
>  	and the object it points at.  _<format>_ is the same as
>  	that of linkgit:git-for-each-ref[1].
>  
> +`--name-prefix <token>`::
> +	A string that will be used as prefix to the name of the new branch to
> +        create. Can be '@{current}' to use the current branch's name.
> +
>  _<branch-name>_::
>  	The name of the branch to create or delete.
>  	The new branch name must pass all checks defined by
> diff --git a/branch.c b/branch.c
> index 243db7d0fc..c24d7ce823 100644
> --- a/branch.c
> +++ b/branch.c
> @@ -365,6 +365,23 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name)
>  	return 0;
>  }
>  
> +void add_branch_prefix(const char *name_prefix,
> +					   const char *current_branch, struct strbuf *buf)

Overly deep indentation here.  Our tab-width is always 8, and you
would align the first "const char" on these two lines.

> +{
> +	int value = 0;

Unused variable?

> +	if (!name_prefix)
> +		return;
> +
> +	if (name_prefix[0] != '@') {
> +		strbuf_addstr(buf, name_prefix);
> +		return;
> +	}
> +
> +	if (strcmp(name_prefix, "@{current}") == 0)
> +		strbuf_addstr(buf, current_branch);
> +}

What happens when we need to support more than the @{current}?  Will
this function grow more parameters and the callers need to prepare
more parameters, even if only one of them may be picked by this
function?  That does not smell like a sound way to make things
maintainable.

> diff --git a/builtin/branch.c b/builtin/branch.c
> index c577b5d20f..58631913c7 100644
> --- a/builtin/branch.c
> +++ b/builtin/branch.c
> ...
> +		add_branch_prefix(name_prefix, start_name, &new_branch_name);


Here, `start_name` is passed as `current_branch` to `add_branch_prefix`.
However, `start_name` is the `<start-point>` (e.g., another branch,
a tag, or a commit). If the user runs:

    $ git branch --name-prefix=@{current} new-branch other-branch

the prefix will be `other-branch` instead of the *current* branch
name as advertised in the documentation.  It _may_ be how the
feature was intended to work, but then the name "current" and the
way the documentation describes the token are both misleading.

> +			create_branch(the_repository, new_branch_name.buf, start_name,
> +						  force, 0, reflog, quiet, track, 0);

Overly deep indentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

X Tutup