[PATCH v3 1/3] branch: add '--name-prefix' option
- From
- VALERI Yoann via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Mar 6, 2026, 13:14 UTC
- Message-ID
- <6cbb950d8bc3b647d7fff72a72f938ee369b552c.1772802872.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2202.v3.git.git.1772802872.gitgitgadget@gmail.com>
From: VALERI Yoann <yoann.valeri@cea.fr>
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> --- Documentation/git-branch.adoc | 11 ++++++++++- branch.c | 17 +++++++++++++++++ branch.h | 12 ++++++++++++ builtin/branch.c | 20 +++++++++++++------- t/t3200-branch.sh | 18 ++++++++++++++++++ 5 files changed, 70 insertions(+), 8 deletions(-)
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>] git branch (--set-upstream-to=<upstream>|-u <upstream>) [<branch-name>] git branch --unset-upstream [<branch-name>] git branch (-m|-M) [<old-branch>] <new-branch> @@ -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. + When a local branch is started off a remote-tracking branch, Git sets up the branch (specifically the `branch.<name>.remote` and `branch.<name>.merge` configuration entries) so that `git pull` will appropriately merge from @@ -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) +{ + int value = 0; + + 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); +} + /* * Check if 'name' can be a valid name for a branch; die otherwise. * Return 1 if the named branch already exists; return 0 otherwise. diff --git a/branch.h b/branch.h index ec2f35fda4..f4ac1e9bbd 100644 --- a/branch.h +++ b/branch.h @@ -148,6 +148,18 @@ int install_branch_config(int flag, const char *local, const char *origin, const */ int read_branch_desc(struct strbuf *, const char *branch_name); +/* + * 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); + + /* * Check if a branch is checked out in the main worktree or any linked * worktree and die (with a message describing its checkout location) if diff --git a/builtin/branch.c b/builtin/branch.c index c577b5d20f..58631913c7 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -725,6 +725,7 @@ int cmd_branch(int argc, struct string_list sorting_options = STRING_LIST_INIT_DUP; struct ref_format format = REF_FORMAT_INIT; int ret; + const char *name_prefix = NULL; struct option options[] = { OPT_GROUP(N_("Generic options")), @@ -776,6 +777,7 @@ int cmd_branch(int argc, OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")), OPT_BOOL(0, "recurse-submodules", &recurse_submodules_explicit, N_("recurse through submodules")), OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")), + OPT_STRING(0, "name-prefix", &name_prefix, N_("name"), N_("prefix for the branch to create")), OPT_END(), }; @@ -995,6 +997,7 @@ int cmd_branch(int argc, } else if (!noncreate_actions && argc > 0 && argc <= 2) { const char *branch_name = argv[0]; const char *start_name = argc == 2 ? argv[1] : head; + struct strbuf new_branch_name = STRBUF_INIT; if (filter.kind != FILTER_REFS_BRANCHES) die(_("the -a, and -r, options to 'git branch' do not take a branch name.\n" @@ -1003,15 +1006,18 @@ int cmd_branch(int argc, if (track == BRANCH_TRACK_OVERRIDE) die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead")); - if (recurse_submodules) { - create_branches_recursively(the_repository, branch_name, + add_branch_prefix(name_prefix, start_name, &new_branch_name); + strbuf_addstr(&new_branch_name, branch_name); + + if (recurse_submodules) + create_branches_recursively(the_repository, new_branch_name.buf, start_name, NULL, force, reflog, quiet, track, 0); - ret = 0; - goto out; - } - create_branch(the_repository, branch_name, start_name, force, 0, - reflog, quiet, track, 0); + else + create_branch(the_repository, new_branch_name.buf, start_name, + force, 0, reflog, quiet, track, 0); + + strbuf_release(&new_branch_name); } else usage_with_options(builtin_branch_usage, options); diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index c58e505c43..550989a2bb 100755 --- 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_cmp expect actual ' +test_expect_success 'create branch with --name-prefix' ' + git config branch.autosetupmerge false && + 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 +' + test_done
-- gitgitgadget