branch split: prefill names with branch prefix (#1126)
autofix.ci / autofix (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Generate test matrix (push) Has been cancelled
CI / Test / ${{ matrix.name }} (push) Has been cancelled
CI / OK (push) Has been cancelled
GitHub Pages / build (push) Has been cancelled
GitHub Pages / deploy (push) Has been cancelled

## Problem

branch split does not currently respect the configured branch prefix.
Unfortunately, there are issues with applying the branch prefix
to branch split unconditionally,
or even as an implicit post-processing step,
as that leaves the current branch name unusable for reuse.

Reusing the current branch name is already a meaningful split operation:
it means "move this existing branch to this split point."
If `feature` is the current branch and `prefix/` is configured,
then always adding the prefix after input changes the meaning:

    current branch: feature
    typed name:     feature
    final name:     prefix/feature

That creates or selects `prefix/feature`
instead of referring to the current branch `feature`.

It's confusing to add prefixing for all branches
except the current branch, with or without exceptions like,
"only if it doesn't already start with the prefix."

## Solution

Rather than deal with confusing or ambiguous behavior,
we seed the interactive branch-name input
with the configured prefix.

With `prefix/` configured, the prompt starts as:

    Branch name: prefix/[cursor]

The prefix is normal editable text.
Users can accept or extend it for new prefixed branches,
or delete it and type the current branch name when they want to reuse
it.

`--at` remains literal because it already spells out the exact branch
name to use:

    gs branch split --at HEAD~2:feature

Because, again, we want to allow reuse of the current branch name
without prefixing.

Resolves #1119
This commit is contained in:
Abhinav Gupta
2026-04-25 20:17:56 -07:00
committed by GitHub
parent 060c64a52a
commit 47366ef811
9 changed files with 215 additions and 0 deletions
@@ -0,0 +1,3 @@
kind: Changed
body: 'branch split: Branch name prompts now start with the configured branch creation prefix.'
time: 2026-04-25T10:19:22.267463-07:00
+4
View File
@@ -20,6 +20,8 @@ type branchSplitCmd struct {
split.Options
Branch string `placeholder:"NAME" help:"Branch to split commits of."`
Prefix string `default:"" config:"branchCreate.prefix" hidden:""`
}
func (*branchSplitCmd) Help() string {
@@ -151,6 +153,7 @@ func (cmd *branchSplitCmd) Run(
fields := make([]ui.Field, 0, len(selected)+1) // +1 for deferred HEAD field
theme := view.Theme()
for i, commit := range selected {
branchNames[i] = cmd.Prefix
desc := cmd.commitDescription(theme, commit, false /* head */)
input := branchNameWidget(desc, &branchNames[i])
fields = append(fields, input)
@@ -171,6 +174,7 @@ func (cmd *branchSplitCmd) Run(
desc := cmd.commitDescription(theme, headCommit, true /* head */) +
" [" + cmd.Branch + "]"
headBranchName = cmd.Prefix
return branchNameWidget(desc, &headBranchName)
}))
+2
View File
@@ -828,6 +828,8 @@ would require a new name to be provided for commit 3.
* `--at=COMMIT:NAME,...`: Commits to split the branch at.
* `--branch=NAME`: Branch to split commits of.
**Configuration**: [spice.branchCreate.prefix](/cli/config.md#spicebranchcreateprefix)
### git-spice branch squash {#gs-branch-squash}
```
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d0c084185b05810ed4612584ebaddd4ee4d0f7a7bdb8beb38a5e6a71ee97e9a7
size 153506
@@ -0,0 +1,48 @@
# Demo of 'branch split' pre-filling names with the configured prefix.
Output "20260426-branch-split-prefix-prompt.gif"
Set Shell "bash"
Set FontSize 16
Set Width 640
Set Height 420
Set Padding 10
Set CursorBlink false
Hide
Type "cd $(mktemp -d) && git init && git commit --allow-empty -m 'Initial commit'" Enter
Type "alias gs=git-spice" Enter
Type "gs repo init" Enter Sleep 100ms
Type "mkdir stardrive && touch stardrive/chimes && git add stardrive && gs branch create stardrive -m 'Tune warp chimes'" Enter Sleep 100ms
Type "touch stardrive/glitter-nebula && git add stardrive/glitter-nebula && gs commit create -m 'Chart glitter nebula'" Enter Sleep 100ms
Type "touch stardrive/comet-tea && git add stardrive/comet-tea && gs commit create -m 'Brew comet tea'" Enter Sleep 100ms
Type "git config spice.branchCreate.prefix 'fleet/'" Enter Sleep 100ms
Type "clear" Enter Sleep 100ms
Show
Sleep 500ms
Type "gs ll" Enter
Sleep 2s
Type "gs branch split" Enter
Sleep 2s
Enter
Sleep 800ms
Enter
Sleep 800ms
Enter
Sleep 1s
Type "warp-chimes"
Sleep 500ms
Enter
Sleep 1s
Type "nebula-chart"
Sleep 500ms
Enter
Sleep 1s
Type "gs ll" Enter
Sleep 3s
+3
View File
@@ -43,3 +43,6 @@ Global Flags:
-v, --verbose Enable verbose output ($GIT_SPICE_VERBOSE)
-C, --dir=DIR Change to DIR before doing anything
--[no-]prompt Whether to prompt for missing information
Configuration (🔧):
spice.branchCreate.prefix
+46
View File
@@ -0,0 +1,46 @@
# branch split leaves --at names literal when a branch prefix is configured.
#
# https://github.com/abhinav/git-spice/issues/1119
as 'Test <test@example.com>'
at '2024-06-23T09:50:12Z'
cd repo
git init
git commit --allow-empty -m 'Initial commit'
gs repo init
git add feature1.txt
gs bc features -m 'Add feature1'
git add feature2.txt
gs cc -m 'Add feature2'
git add feature3.txt
gs cc -m 'Add feature3'
git config spice.branchCreate.prefix 'myuser/'
gs branch split --at HEAD~2:feature1 --at HEAD^:feature2
gs ls -a
cmp stderr $WORK/golden/after.txt
git graph --branches
cmp stdout $WORK/golden/graph.txt
-- repo/feature1.txt --
feature1
-- repo/feature2.txt --
feature2
-- repo/feature3.txt --
feature3
-- golden/after.txt --
┏━■ features ◀
┏━┻□ feature2
┏━┻□ feature1
main
-- golden/graph.txt --
* 99827e4 (HEAD -> features) Add feature3
* a1192a4 (feature2) Add feature2
* b9014d5 (feature1) Add feature1
* 5c2596e (main) Initial commit
+62
View File
@@ -0,0 +1,62 @@
# branch split prompts with the configured branch creation prefix.
#
# https://github.com/abhinav/git-spice/issues/1119
as 'Test <test@example.com>'
at '2024-06-23T10:00:12Z'
cd repo
git init
git commit --allow-empty -m 'Initial commit'
gs repo init
git add feature1.txt
gs bc -m 'Add feature1' features
git add feature2.txt
gs cc -m 'Add feature2'
git add feature3.txt
gs cc -m 'Add feature3'
git config spice.branchCreate.prefix 'myuser/'
env ROBOT_INPUT=$WORK/robot.golden ROBOT_OUTPUT=$WORK/robot.actual
gs branch split
cmp $WORK/robot.actual $WORK/robot.golden
gs ll -a
cmp stderr $WORK/golden/after.txt
-- repo/feature1.txt --
feature1
-- repo/feature2.txt --
feature2
-- repo/feature3.txt --
feature3
-- golden/after.txt --
┏━■ features ◀
┃ 1b17c72 Add feature3 (now)
┏━┻□ myuser/feature2
┃ 0c7ed55 Add feature2 (now)
┏━┻□ myuser/feature1
┃ a3a4c59 Add feature1 (now)
main
-- robot.golden --
===
> Select commits:
> ▶ a3a4c59 Add feature1 (now)
> 0c7ed55 Add feature2 (now)
> ■ 1b17c72 Add feature3 (now) [features]
> Done
> Select commits to split the branch at
[
"a3a4c59",
"0c7ed55"
]
===
> Branch name: myuser/
> □ a3a4c59 Add feature1 (now)
"myuser/feature1"
===
> Branch name: myuser/
> □ 0c7ed55 Add feature2 (now)
"myuser/feature2"
+44
View File
@@ -0,0 +1,44 @@
# branch split leaves --at names literal,
# including intentional reuse of the original branch name.
as 'Test <test@example.com>'
at '2024-06-23T10:00:12Z'
cd repo
git init
git commit --allow-empty -m 'Initial commit'
gs repo init
git add feature1.txt
gs bc -m 'Add feature1' features
git add feature2.txt
gs cc -m 'Add feature2'
git add feature3.txt
gs cc -m 'Add feature3'
git config spice.branchCreate.prefix 'myuser/'
gs branch split --at a3a4c59:features --at 0c7ed55:feature2 --at 1b17c72:feature3
gs ll -a
cmp stderr $WORK/golden/after.txt
git branch --show-current
cmp stdout $WORK/golden/current_branch.txt
-- repo/feature1.txt --
feature1
-- repo/feature2.txt --
feature2
-- repo/feature3.txt --
feature3
-- golden/after.txt --
┏━■ feature3 ◀
┃ 1b17c72 Add feature3 (now)
┏━┻□ feature2
┃ 0c7ed55 Add feature2 (now)
┏━┻□ features
┃ a3a4c59 Add feature1 (now)
main
-- golden/current_branch.txt --
feature3