Skip to content

feat: add multi-commit PR support via local branches/bookmarks#2

Open
jucor wants to merge 6 commits into
jj-compatfrom
claude/multi-commit-pr-support-YMmNK
Open

feat: add multi-commit PR support via local branches/bookmarks#2
jucor wants to merge 6 commits into
jj-compatfrom
claude/multi-commit-pr-support-YMmNK

Conversation

@jucor
Copy link
Copy Markdown
Owner

@jucor jucor commented Apr 2, 2026

Add optional multi-commit PR mode where local git branches or jj bookmarks define PR boundaries. Each branch/bookmark on the linear history from trunk to HEAD marks the tip of a PR group. Commits above the last branch are treated as WIP.

Key changes:

  • Config: multiCommitPRs and concatCommitMessages settings
  • Commit struct: new Branches field for branch/bookmark annotations
  • Git: detect local branches on commits, auto-update branch positions after spr's own rebase using commit-id trailer matching
  • JJ: parse bookmarks from extended jj log template
  • Grouping: new PRGroup type and GroupCommitsIntoPRs() function
  • spr.go: Update/Merge/Status flows use tip commits from groups
  • Templates: support spr-pr-title:/spr-pr-body: markers in tip commit, concatenate commit messages in PR body (configurable)
  • All existing tests pass, new tests for grouping, parsing, templates

https://claude.ai/code/session_01PDskCvL2BSTTEwKRucykbh

jucor and others added 6 commits March 30, 2026 17:32
When spr detects a jj-colocated repo (.jj/ directory present), it uses
jj commands for history-rewriting operations instead of git rebase.
This preserves jj change IDs across spr update/merge/amend/edit cycles.

Key changes:
- New vcs/ package with VCSOperations interface abstracting the 7
  operations where git and jj differ (FetchAndRebase, GetLocalCommitStack,
  AmendInto, EditStart/Finish/Abort, PrepareForPush)
- GitOps: pure extraction of existing git logic (no behavior change)
- JjOps: jj-native implementation using jj describe, jj rebase,
  jj squash, jj edit (preserves change IDs)
- Auto-detection: .jj/ directory triggers jj mode
- Opt-out: --no-jj flag, SPR_NOJJ env var, or noJJ: true in ~/.spr.yml
- 31 new tests, all existing tests pass unchanged

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GetInfo previously called git.GetLocalCommitStack internally, bypassing the
VCSOperations abstraction. In jj mode this panicked because git rebase cannot
add commit-id trailers to jj commits. Now all callers provide commits via
vcsOps.GetLocalCommitStack, and GetInfo receives them as a parameter.

Also adds CheckStackCompleteness to warn when @ has descendants in jj mode
(commits above @ would be excluded from trunk()..@), prompting for confirmation
before proceeding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JjCmd.Jj() uses strings.Fields to split args, which breaks template
strings containing spaces (e.g. -T 'commit_id ++ ...'). Switch to
JjArgs which passes pre-split arguments directly to exec.Command,
bypassing shell quoting entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed JJ_CONFIG= from jj command execution. Setting this env var
to empty caused jj to skip loading user config, resulting in empty
committer name/email on every rebase and describe operation.
Add optional multi-commit PR mode where local git branches or jj
bookmarks define PR boundaries. Each branch/bookmark on the linear
history from trunk to HEAD marks the tip of a PR group. Commits
above the last branch are treated as WIP.

Key changes:
- Config: multiCommitPRs and concatCommitMessages settings
- Commit struct: new Branches field for branch/bookmark annotations
- Git: detect local branches on commits, auto-update branch positions
  after spr's own rebase using commit-id trailer matching
- JJ: parse bookmarks from extended jj log template
- Grouping: new PRGroup type and GroupCommitsIntoPRs() function
- spr.go: Update/Merge/Status flows use tip commits from groups
- Templates: support spr-pr-title:/spr-pr-body: markers in tip commit,
  concatenate commit messages in PR body (configurable)
- All existing tests pass, new tests for grouping, parsing, templates

https://claude.ai/code/session_01PDskCvL2BSTTEwKRucykbh
@jucor jucor force-pushed the jj-compat branch 2 times, most recently from ef2d8fd to 3e041d5 Compare April 2, 2026 19:45
@jucor jucor force-pushed the jj-compat branch 4 times, most recently from 7f657d8 to b3946a1 Compare May 20, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants