mirror of
https://github.com/abhinav/git-spice.git
synced 2026-08-31 07:47:47 +02:00
submit: Use collision-resolved upstream bases (#1430)
autofix.ci / autofix (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Generate test matrix (push) Waiting to run
CI / Test / ${{ matrix.name }} (push) Blocked by required conditions
CI / OK (push) Blocked by required conditions
GitHub Pages / build (push) Waiting to run
GitHub Pages / deploy (push) Blocked by required conditions
autofix.ci / autofix (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Generate test matrix (push) Waiting to run
CI / Test / ${{ matrix.name }} (push) Blocked by required conditions
CI / OK (push) Blocked by required conditions
GitHub Pages / build (push) Waiting to run
GitHub Pages / deploy (push) Blocked by required conditions
When `stack submit` encounters remote branches with the same names as local stack members, it allocates collision-free upstream names. Upper pull requests still used the occupied local names as their bases, so the first submission produced an incorrect pull request chain. Carry each selected upstream name through the batch and prefer it over the preloaded graph snapshot when submitting the next branch. This preserves graph reuse while creating the correct base chain on the first submission. Fixes #1394
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
kind: Fixed
|
||||
body: 'stack submit: Pull requests are now created with the correct base branches when existing remote branches have the same names as the local stack.'
|
||||
time: 2026-08-30T12:34:54.354962-07:00
|
||||
@@ -236,19 +236,29 @@ func (h *Handler) SubmitBatch(ctx context.Context, req *BatchRequest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
resolvedUpstreams := make(map[string]string)
|
||||
var branchesToComment []string
|
||||
for _, branch := range req.Branches {
|
||||
branchInfo, ok := graph.Lookup(branch)
|
||||
if !ok {
|
||||
return fmt.Errorf("submit branch %s: lookup branch: %w", branch, state.ErrNotExist)
|
||||
}
|
||||
|
||||
// Shallow copy the options because submitBranch may modify them.
|
||||
opts := *opts
|
||||
status, err := h.submitBranch(
|
||||
ctx,
|
||||
graph,
|
||||
branch,
|
||||
&submitOptions{Options: &opts},
|
||||
&submitOptions{
|
||||
Options: &opts,
|
||||
upstreamBase: resolvedUpstreams[branchInfo.Base],
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("submit branch %s: %w", branch, err)
|
||||
}
|
||||
resolvedUpstreams[branch] = status.upstreamBranch
|
||||
if status.Submitted {
|
||||
branchesToComment = append(branchesToComment, branch)
|
||||
}
|
||||
@@ -347,12 +357,15 @@ type submitStatus struct {
|
||||
// If yes, comments will be added or updated
|
||||
// based on the NavComment option.
|
||||
Submitted bool
|
||||
|
||||
upstreamBranch string
|
||||
}
|
||||
|
||||
type submitOptions struct {
|
||||
*Options
|
||||
|
||||
Title, Body string
|
||||
Title, Body string
|
||||
upstreamBase string
|
||||
}
|
||||
|
||||
func (h *Handler) submitBranch(
|
||||
@@ -405,6 +418,9 @@ func (h *Handler) submitBranch(
|
||||
if err != nil {
|
||||
return status, fmt.Errorf("resolve upstream branch: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
status.upstreamBranch = upstreamBranch
|
||||
}()
|
||||
|
||||
// Similarly, if the branch's base has a different name upstream,
|
||||
// use that name instead.
|
||||
@@ -414,7 +430,7 @@ func (h *Handler) submitBranch(
|
||||
if !ok {
|
||||
return status, fmt.Errorf("lookup base branch: %w", state.ErrNotExist)
|
||||
}
|
||||
upstreamBase = cmp.Or(baseBranch.UpstreamBranch, branch.Base)
|
||||
upstreamBase = cmp.Or(opts.upstreamBase, baseBranch.UpstreamBranch, branch.Base)
|
||||
}
|
||||
|
||||
var existingChange *forge.FindChangeItem
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
# 'stack submit' uses collision-resolved upstream names as PR bases.
|
||||
#
|
||||
# https://github.com/abhinav/git-spice/issues/1394
|
||||
|
||||
as 'Test <test@example.com>'
|
||||
at '2026-08-30T19:28:02Z'
|
||||
|
||||
# Setup.
|
||||
cd repo
|
||||
git init
|
||||
git commit --allow-empty -m 'Initial commit'
|
||||
|
||||
# Set up a fake GitHub remote with the desired branch names already taken.
|
||||
shamhub-setup
|
||||
shamhub register alice
|
||||
shamhub new origin alice/example.git
|
||||
git push origin main main:float-1 main:float-2 main:float-3
|
||||
gs repo init
|
||||
|
||||
env SHAMHUB_USERNAME=alice
|
||||
gs auth login
|
||||
|
||||
# Create the local float-1 -> float-2 -> float-3 stack.
|
||||
git add float-1.txt
|
||||
gs branch create float-1 -m 'Add float 1'
|
||||
git add float-2.txt
|
||||
gs branch create float-2 -m 'Add float 2'
|
||||
git add float-3.txt
|
||||
gs branch create float-3 -m 'Add float 3'
|
||||
|
||||
# Each local branch needs a collision-free upstream name.
|
||||
# Upper PRs must target those resolved names during the same submission.
|
||||
gs stack submit --fill
|
||||
stderr 'float-1: Using upstream name ''float-1-2'' instead'
|
||||
stderr 'float-2: Using upstream name ''float-2-2'' instead'
|
||||
stderr 'float-3: Using upstream name ''float-3-2'' instead'
|
||||
|
||||
shamhub dump changes
|
||||
cmpenvJSON stdout $WORK/golden/changes.json
|
||||
|
||||
-- repo/float-1.txt --
|
||||
Float 1
|
||||
-- repo/float-2.txt --
|
||||
Float 2
|
||||
-- repo/float-3.txt --
|
||||
Float 3
|
||||
-- golden/changes.json --
|
||||
[
|
||||
{
|
||||
"number": 1,
|
||||
"html_url": "$SHAMHUB_URL/alice/example/change/1",
|
||||
"state": "open",
|
||||
"title": "Add float 1",
|
||||
"body": "",
|
||||
"base": {
|
||||
"repository": {
|
||||
"owner": "alice",
|
||||
"name": "example"
|
||||
},
|
||||
"ref": "main",
|
||||
"sha": "41127951a5bcb2b7258946d758cbe8549dde8fd2"
|
||||
},
|
||||
"head": {
|
||||
"repository": {
|
||||
"owner": "alice",
|
||||
"name": "example"
|
||||
},
|
||||
"ref": "float-1-2",
|
||||
"sha": "19b5f4c2b2d7362f0d02649e1351083ebc7a3d42"
|
||||
}
|
||||
},
|
||||
{
|
||||
"number": 2,
|
||||
"html_url": "$SHAMHUB_URL/alice/example/change/2",
|
||||
"state": "open",
|
||||
"title": "Add float 2",
|
||||
"body": "",
|
||||
"base": {
|
||||
"repository": {
|
||||
"owner": "alice",
|
||||
"name": "example"
|
||||
},
|
||||
"ref": "float-1-2",
|
||||
"sha": "19b5f4c2b2d7362f0d02649e1351083ebc7a3d42"
|
||||
},
|
||||
"head": {
|
||||
"repository": {
|
||||
"owner": "alice",
|
||||
"name": "example"
|
||||
},
|
||||
"ref": "float-2-2",
|
||||
"sha": "bb5562b20af515520df4bcc17277fe7cbda2221b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"number": 3,
|
||||
"html_url": "$SHAMHUB_URL/alice/example/change/3",
|
||||
"state": "open",
|
||||
"title": "Add float 3",
|
||||
"body": "",
|
||||
"base": {
|
||||
"repository": {
|
||||
"owner": "alice",
|
||||
"name": "example"
|
||||
},
|
||||
"ref": "float-2-2",
|
||||
"sha": "bb5562b20af515520df4bcc17277fe7cbda2221b"
|
||||
},
|
||||
"head": {
|
||||
"repository": {
|
||||
"owner": "alice",
|
||||
"name": "example"
|
||||
},
|
||||
"ref": "float-3-2",
|
||||
"sha": "d1a14cc8a8ecd178c66856d80489bb09a3e79ccf"
|
||||
}
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user