mirror of
https://github.com/github/gh-stack.git
synced 2026-09-14 20:26:28 +08:00
fix for rev-parse error during sync
This commit is contained in:
+10
-4
@@ -125,10 +125,16 @@ func runSync(cfg *config.Config, opts *syncOptions) error {
|
||||
// Sync PR state to detect merged PRs before rebasing.
|
||||
syncStackPRs(cfg, s)
|
||||
|
||||
// Save original refs so we can restore on conflict
|
||||
branchNames := make([]string, len(s.Branches))
|
||||
for i, b := range s.Branches {
|
||||
branchNames[i] = b.Branch
|
||||
// Save original refs so we can restore on conflict.
|
||||
// Merged branches that no longer exist locally have no ref to
|
||||
// resolve. They are always skipped during rebase but we must
|
||||
// also exclude them here to avoid a rev-parse error.
|
||||
branchNames := make([]string, 0, len(s.Branches))
|
||||
for _, b := range s.Branches {
|
||||
if b.IsMerged() && !git.BranchExists(b.Branch) {
|
||||
continue
|
||||
}
|
||||
branchNames = append(branchNames, b.Branch)
|
||||
}
|
||||
originalRefs, _ := git.RevParseMap(branchNames)
|
||||
|
||||
|
||||
@@ -535,6 +535,7 @@ func TestSync_SquashMergedBranch_UsesOnto(t *testing.T) {
|
||||
}
|
||||
|
||||
mock := newSyncMock(tmpDir, "b2")
|
||||
mock.BranchExistsFn = func(name string) bool { return true }
|
||||
// Trunk behind remote to trigger rebase
|
||||
mock.RevParseFn = func(ref string) (string, error) {
|
||||
if ref == "main" {
|
||||
@@ -647,3 +648,79 @@ func TestSync_PushFailureAfterRebase(t *testing.T) {
|
||||
assert.True(t, pushCalls[0].force, "push after rebase should use force")
|
||||
assert.Contains(t, output, "Push failed")
|
||||
}
|
||||
|
||||
func TestSync_MergedBranchDeletedFromRemote(t *testing.T) {
|
||||
s := stack.Stack{
|
||||
Trunk: stack.BranchRef{Branch: "main"},
|
||||
Branches: []stack.BranchRef{
|
||||
{Branch: "b1", PullRequest: &stack.PullRequestRef{Number: 1, Merged: true}},
|
||||
{Branch: "b2"},
|
||||
},
|
||||
}
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
writeStackFile(t, tmpDir, s)
|
||||
|
||||
var rebaseOntoCalls []rebaseCall
|
||||
|
||||
mock := newSyncMock(tmpDir, "b2")
|
||||
mock.BranchExistsFn = func(name string) bool {
|
||||
// b1 does not exist locally (deleted from remote after merge)
|
||||
return name != "b1"
|
||||
}
|
||||
mock.RevParseMultiFn = func(refs []string) ([]string, error) {
|
||||
shas := make([]string, len(refs))
|
||||
for i, r := range refs {
|
||||
if r == "b1" {
|
||||
t.Fatalf("RevParseMulti should not be called with non-existent branch b1")
|
||||
}
|
||||
if r == "main" {
|
||||
shas[i] = "local-sha"
|
||||
} else if r == "origin/main" {
|
||||
shas[i] = "remote-sha"
|
||||
} else {
|
||||
shas[i] = "sha-" + r
|
||||
}
|
||||
}
|
||||
return shas, nil
|
||||
}
|
||||
// Trunk behind remote to trigger rebase
|
||||
mock.RevParseFn = func(ref string) (string, error) {
|
||||
if ref == "main" {
|
||||
return "local-sha", nil
|
||||
}
|
||||
if ref == "origin/main" {
|
||||
return "remote-sha", nil
|
||||
}
|
||||
return "sha-" + ref, nil
|
||||
}
|
||||
mock.IsAncestorFn = func(a, d string) (bool, error) {
|
||||
return a == "local-sha" && d == "remote-sha", nil
|
||||
}
|
||||
mock.UpdateBranchRefFn = func(string, string) error { return nil }
|
||||
mock.CheckoutBranchFn = func(string) error { return nil }
|
||||
mock.RebaseOntoFn = func(newBase, oldBase, branch string) error {
|
||||
rebaseOntoCalls = append(rebaseOntoCalls, rebaseCall{newBase, oldBase, branch})
|
||||
return nil
|
||||
}
|
||||
|
||||
restore := git.SetOps(mock)
|
||||
defer restore()
|
||||
|
||||
cfg, _, errR := config.NewTestConfig()
|
||||
cmd := SyncCmd(cfg)
|
||||
cmd.SetOut(io.Discard)
|
||||
cmd.SetErr(io.Discard)
|
||||
err := cmd.Execute()
|
||||
|
||||
cfg.Err.Close()
|
||||
errOut, _ := io.ReadAll(errR)
|
||||
output := string(errOut)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, output, "Skipping b1")
|
||||
|
||||
// Only b2 should be rebased
|
||||
require.Len(t, rebaseOntoCalls, 1)
|
||||
assert.Equal(t, "b2", rebaseOntoCalls[0].branch)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user