mirror of
https://github.com/github/gh-stack.git
synced 2026-09-14 20:26:28 +08:00
remove silent prefix detection in init (#126)
* Remove silent prefix detection from args path in init When explicit branch names containing slashes were passed to `gh stack init` (e.g. `gh stack init myprefix/branch`), detectPrefix would silently extract the prefix and store it in the stack config. This caused `gh stack add otherbranch` to unexpectedly produce `myprefix/otherbranch` without the user ever opting in. Remove the automatic prefix detection from the args path so that explicit branch names are taken literally. Users who want a prefix should use `--prefix`. The interactive path (no args) continues to prompt for confirmation before setting a prefix. * Remove dead detectPrefix function and its tests After removing the silent prefix detection from the args path, detectPrefix has no production callers. Remove the function and its table-driven unit test to avoid maintaining unused code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
-30
@@ -149,13 +149,6 @@ func runInit(cfg *config.Config, opts *initOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Prefix detection (only when --prefix not explicitly set)
|
||||
if opts.prefix == "" {
|
||||
if detected := detectPrefix(branches); detected != "" {
|
||||
opts.prefix = detected
|
||||
}
|
||||
}
|
||||
|
||||
} else if opts.numbered {
|
||||
// === NUMBERED PATH (unchanged) ===
|
||||
if opts.prefix == "" && cfg.IsInteractive() {
|
||||
@@ -455,29 +448,6 @@ func promptBranchName(cfg *config.Config, prefix string) (string, error) {
|
||||
return branchName, nil
|
||||
}
|
||||
|
||||
// detectPrefix finds a common prefix across branches by splitting each
|
||||
// at its last slash. Returns the prefix (without trailing slash) if all
|
||||
// branches share the same one, or "" otherwise.
|
||||
func detectPrefix(branches []string) string {
|
||||
if len(branches) == 0 {
|
||||
return ""
|
||||
}
|
||||
var common string
|
||||
for i, b := range branches {
|
||||
lastSlash := strings.LastIndex(b, "/")
|
||||
if lastSlash <= 0 {
|
||||
return "" // no slash or leading slash — no prefix
|
||||
}
|
||||
prefix := b[:lastSlash]
|
||||
if i == 0 {
|
||||
common = prefix
|
||||
} else if prefix != common {
|
||||
return "" // different prefixes
|
||||
}
|
||||
}
|
||||
return common
|
||||
}
|
||||
|
||||
// printWhatsNext prints the scenario-aware "What's next" block after init.
|
||||
func printWhatsNext(cfg *config.Config, s *stack.Stack, branches []string, hasAdopted bool, prCount int) {
|
||||
lastBranch := branches[len(branches)-1]
|
||||
|
||||
+7
-27
@@ -465,7 +465,9 @@ func TestInit_ImplicitAdopt_Mixed(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInit_PrefixDetection_ArgsCommonPrefix(t *testing.T) {
|
||||
// Scenario 9: args all share prefix → set silently
|
||||
// Explicit branch names with a common prefix should NOT auto-detect
|
||||
// a prefix — the slash is part of the branch name, not a convention.
|
||||
// Users who want a prefix should use --prefix.
|
||||
gitDir := t.TempDir()
|
||||
restore := git.SetOps(&git.MockOps{
|
||||
GitDirFn: func() (string, error) { return gitDir, nil },
|
||||
@@ -481,7 +483,7 @@ func TestInit_PrefixDetection_ArgsCommonPrefix(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
sf, _ := stack.Load(gitDir)
|
||||
assert.Equal(t, "feat", sf.Stacks[0].Prefix)
|
||||
assert.Equal(t, "", sf.Stacks[0].Prefix)
|
||||
}
|
||||
|
||||
func TestInit_PrefixDetection_ArgsMixedPrefix(t *testing.T) {
|
||||
@@ -525,7 +527,8 @@ func TestInit_PrefixDetection_ArgsNoSlash(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInit_PrefixDetection_NestedPrefix(t *testing.T) {
|
||||
// Scenario 6: sameen/feat/x → prefix "sameen/feat"
|
||||
// Explicit branch names with nested slashes should NOT auto-detect
|
||||
// a prefix — the user typed the full branch name deliberately.
|
||||
gitDir := t.TempDir()
|
||||
restore := git.SetOps(&git.MockOps{
|
||||
GitDirFn: func() (string, error) { return gitDir, nil },
|
||||
@@ -541,7 +544,7 @@ func TestInit_PrefixDetection_NestedPrefix(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
sf, _ := stack.Load(gitDir)
|
||||
assert.Equal(t, "sameen/feat", sf.Stacks[0].Prefix)
|
||||
assert.Equal(t, "", sf.Stacks[0].Prefix)
|
||||
}
|
||||
|
||||
func TestInit_ExplicitPrefixSkipsDetection(t *testing.T) {
|
||||
@@ -795,26 +798,3 @@ func TestInit_TwoPassValidation_InvalidRefName(t *testing.T) {
|
||||
assert.Contains(t, output, "invalid branch name")
|
||||
assert.Empty(t, created, "no branches should be created when an arg has an invalid ref name")
|
||||
}
|
||||
|
||||
func TestDetectPrefix(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
branches []string
|
||||
want string
|
||||
}{
|
||||
{"common prefix", []string{"feat/a", "feat/b", "feat/c"}, "feat"},
|
||||
{"nested prefix", []string{"sameen/feat/a", "sameen/feat/b"}, "sameen/feat"},
|
||||
{"mixed prefixes", []string{"feat/a", "bug/b"}, ""},
|
||||
{"no slashes", []string{"auth", "api", "ui"}, ""},
|
||||
{"empty list", []string{}, ""},
|
||||
{"single branch with slash", []string{"feat/x"}, "feat"},
|
||||
{"single branch no slash", []string{"auth"}, ""},
|
||||
{"leading slash only", []string{"/x"}, ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := detectPrefix(tt.branches)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user