fix: detect existing PRs and always update stack comments on sync#68
fix: detect existing PRs and always update stack comments on sync#68nvandessel merged 1 commit intomainfrom
Conversation
Greptile SummaryThis PR fixes three related gaps in how Key observations:
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| cmd/push.go | Adds pre-push PR adoption: checks GitHub for an existing open PR when none is in state, stores it, and continues with normal retargeting logic. State is written correctly on adoption. The adopted flag drives human-readable output but is not reflected in the JSON result struct. |
| cmd/track.go | Adds optional PR detection on frond track via gh.PRForBranch; correctly guards with gh.Available() since track doesn't require gh. PR number stored in state and surfaced in both human-readable and JSON output. |
| cmd/sync.go | Moves updateStackComments out of the merge-only block so it runs unconditionally on every sync. The call correctly occurs after merged-PR comment updates and before the "already up to date" early-return check, ensuring comment API calls fire even with no merges or rebases. |
| internal/gh/gh.go | New PRForBranch helper wraps gh pr list --head <branch> --state open --json number --limit 1. Logic is correct; minor redundant strings.TrimSpace call since run() already trims output. |
| internal/gh/testdata/fakegh/main.go | Adds pr list handler controlled by FAKEGH_PR_FOR_BRANCH=branch:number. Functional for current tests but limited to a single branch:number pair, which could be a constraint for future multi-branch adoption tests. |
| cmd/results.go | Adds PR *int field to trackResult for JSON output. pushResult still lacks an adopted field, creating an inconsistency between human-readable and JSON output for the adopted-PR case. |
| cmd/cmd_test.go | Four new integration tests covering all three fixes plus the nil-PR case. Tests correctly use FAKEGH_PR_FOR_BRANCH, verify state after commands, and check that comment API calls are made during sync without merges. |
Sequence Diagram
sequenceDiagram
participant User
participant frond
participant State
participant gh as gh CLI / GitHub
Note over User,gh: frond track <branch>
User->>frond: track <branch> --on <parent>
frond->>gh: gh pr list --head <branch> --state open
gh-->>frond: PR #N (or empty)
frond->>State: write {branch, parent, PR: #N or nil}
frond-->>User: "Tracking branch..." [+ "Found existing PR #N"]
Note over User,gh: frond push (no PR in state)
User->>frond: push
frond->>gh: git push origin <branch>
frond->>gh: gh pr list --head <branch> --state open
alt PR already exists on GitHub
gh-->>frond: PR #N
frond->>State: write {PR: #N} (adopted)
frond->>gh: gh pr view #N (check base)
frond-->>User: "Pushed <branch>. PR #N [adopted]"
else No existing PR
gh-->>frond: []
frond->>gh: gh pr create --base <parent> --head <branch>
gh-->>frond: PR #M
frond->>State: write {PR: #M}
frond-->>User: "Pushed <branch>. PR #M [created]"
end
frond->>gh: updateStackComments (API calls)
Note over User,gh: frond sync
User->>frond: sync
frond->>gh: git fetch
frond->>gh: gh pr view (check merged state per branch)
opt Merges detected
frond->>State: reparent children, delete merged branches
frond->>gh: updateMergedComments
end
frond->>gh: updateStackComments (always)
frond->>gh: git rebase (topological order)
frond-->>User: sync summary
Comments Outside Diff (3)
-
cmd/results.go, line 24-28 (link)pushResultmissingadoptedfieldWhen a PR is adopted,
--jsonoutput still emits"created": false, which is identical to the "updated" case. Scripts consuming the JSON output have no way to distinguish between an adopted PR (previously unknown tofrond) and a routine push update. The human-readable path already distinguishes the three states (created,adopted,updated), but the JSON API does not.Then in
push.gothe JSON output should be updated to includeAdopted: adopted. -
internal/gh/testdata/fakegh/main.go, line 133-153 (link)FAKEGH_PR_FOR_BRANCHonly supports a singlebranch:numberpairThe current format
"branch:number"can only simulate one branch having a pre-existing PR at a time. Any future test that needs two tracked branches to both have existing PRs (e.g., testing stack adoption) would need to set the env var twice or use a different mechanism. Consider a comma-delimited format like"branch1:55,branch2:77"to future-proof this:prForBranch := os.Getenv("FAKEGH_PR_FOR_BRANCH") if prForBranch != "" { var headBranch string for i := 2; i < len(args); i++ { if args[i] == "--head" && i+1 < len(args) { headBranch = args[i+1] break } } for _, entry := range strings.Split(prForBranch, ",") { parts := strings.SplitN(entry, ":", 2) if len(parts) == 2 && parts[0] == headBranch { fmt.Printf("[{\"number\": %s}]\n", parts[1]) os.Exit(0) } } } fmt.Println("[]")
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
-
internal/gh/gh.go, line 196-219 (link)Redundant
strings.TrimSpacecallThe
run()helper (line 54) already callsstrings.TrimSpaceon stdout before returning. The secondTrimSpaceon line 204 is a no-op.(Remove the
out = strings.TrimSpace(out)line 204.)
Last reviewed commit: 5db7fab
…ts on sync Three related bugs prevented stack comments from appearing on PRs created outside of `frond push`: 1. `frond sync` only called updateStackComments when merges were detected. Now it runs unconditionally after state is written. 2. `frond track` did not check GitHub for an existing PR on the tracked branch. Now it calls gh.PRForBranch and stores the PR number if found. 3. `frond push` would always try to create a new PR even when one already existed on GitHub. Now it checks for an existing PR first and adopts it. Adds gh.PRForBranch helper, fakegh support for `pr list`, and tests for all three fixes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8f33e6f to
5db7fab
Compare
Summary
frond syncnow always updates stack comments, not only when merges are detected. This ensures PRs tracked after creation (e.g., viafrond track) get their stack comments posted on the next sync.frond trackdetects existing PRs on GitHub for the tracked branch and stores the PR number in state, sosyncandpushknow about them immediately.frond pushadopts pre-existing PRs instead of trying to create a duplicate. If a PR already exists for the branch on GitHub, it is adopted and its number stored in state.gh.PRForBranchhelper function, fakeghpr listsupport, and tests for all three fixes.Test plan
TestSyncUpdatesCommentsWithoutMerges— verifies stack comment API calls happen during sync even with no mergesTestTrackDetectsExistingPR— verifiesfrond trackstores the PR number when a PR existsTestTrackNoPRStoresNil— verifiesfrond trackstores nil when no PR existsTestPushAdoptsExistingPR— verifiesfrond pushadopts an existing PR instead of creating a new one🤖 Generated with Claude Code