Skip to content

Commit b7a8657

Browse files
committed
address review comment
1 parent 1aeb0c0 commit b7a8657

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

‎cmd/link.go‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,16 @@ func runLink(cfg *config.Config, opts *linkOptions, args []string) error {
153153
// of that stack. It returns the matched stack (or nil) and the PR arguments to
154154
// resolve — args[1:] in add mode, or all args otherwise.
155155
//
156-
// Only a bare positive integer can name a stack. Because stack, PR, and issue
157-
// numbers share one repo-scoped numberspace, a number that matches a stack can
158-
// never also be a PR number, so this never shadows a create/update invocation.
156+
// Only a bare positive integer that isn't also a local branch name can name a
157+
// stack. Stack, PR, and issue numbers share one repo-scoped numberspace (so a
158+
// number never doubles as a PR), but branch names don't — a branch literally
159+
// named like a stack number is kept as a branch.
159160
func detectAddMode(args []string, stacks []github.RemoteStack) (*github.RemoteStack, []string) {
160161
if len(args) < 2 {
161162
return nil, args
162163
}
163164
n, err := strconv.Atoi(args[0])
164-
if err != nil || n <= 0 {
165+
if err != nil || n <= 0 || git.BranchExists(args[0]) {
165166
return nil, args
166167
}
167168
for i := range stacks {

‎cmd/link_test.go‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,51 @@ func TestLink_NumericArg_PRNotFound_TreatedAsBranch(t *testing.T) {
11771177
assert.Equal(t, []int{50, 51}, stackedPRs)
11781178
}
11791179

1180+
func TestLink_NumericFirstArgIsLocalBranch_NotAddMode(t *testing.T) {
1181+
// Branch "123" exists locally and stack #123 also exists. The numeric
1182+
// branch name must win over add mode, so the args form a new stack rather
1183+
// than appending #456 to the unrelated stack #123.
1184+
restore := git.SetOps(newLinkGitMock("123", "456"))
1185+
defer restore()
1186+
1187+
var createdPRs []int
1188+
cfg, _, _ := config.NewTestConfig()
1189+
cfg.GitHubClientOverride = &github.MockClient{
1190+
FindPRByNumberFn: func(int) (*github.PullRequest, error) { return nil, nil },
1191+
FindPRForBranchFn: func(branch string) (*github.PullRequest, error) {
1192+
switch branch {
1193+
case "123":
1194+
return &github.PullRequest{Number: 50, HeadRefName: "123", BaseRefName: "main", URL: "https://github.com/o/r/pull/50"}, nil
1195+
case "456":
1196+
return &github.PullRequest{Number: 51, HeadRefName: "456", BaseRefName: "123", URL: "https://github.com/o/r/pull/51"}, nil
1197+
}
1198+
return nil, nil
1199+
},
1200+
ListStacksFn: func() ([]github.RemoteStack, error) {
1201+
return []github.RemoteStack{
1202+
linkRemoteStack(123, linkPR(90, "unrelated-a"), linkPR(91, "unrelated-b")),
1203+
}, nil
1204+
},
1205+
AddToStackFn: func(int, []int) (*github.RemoteStack, error) {
1206+
t.Fatal("AddToStack must not be called: a numeric branch name should not trigger add mode")
1207+
return nil, nil
1208+
},
1209+
CreateStackFn: func(prNumbers []int) (*github.RemoteStack, error) {
1210+
createdPRs = prNumbers
1211+
return &github.RemoteStack{ID: 42, Number: 42}, nil
1212+
},
1213+
}
1214+
1215+
cmd := LinkCmd(cfg)
1216+
cmd.SetArgs([]string{"123", "456"})
1217+
cmd.SetOut(io.Discard)
1218+
cmd.SetErr(io.Discard)
1219+
err := cmd.Execute()
1220+
1221+
assert.NoError(t, err)
1222+
assert.Equal(t, []int{50, 51}, createdPRs)
1223+
}
1224+
11801225
func TestLink_FixesBaseBranches(t *testing.T) {
11811226
restore := git.SetOps(newLinkGitMock("feat-a", "feat-b"))
11821227
defer restore()

0 commit comments

Comments
 (0)