@@ -11,19 +11,35 @@ interface MergeFlags {
1111export async function merge ( flags : MergeFlags = { } ) : Promise < void > {
1212 const jj = createJJ ( ) ;
1313 const github = new GitHub ( process . cwd ( ) ) ;
14+ const trunk = jj . getTrunk ( ) ;
1415
15- const { workingCopy } = unwrap ( await jj . status ( ) ) ;
16+ const { workingCopy, parents } = unwrap ( await jj . status ( ) ) ;
1617
17- if ( workingCopy . bookmarks . length === 0 ) {
18+ let bookmarkName : string | null = null ;
19+ let changeId : string | null = null ;
20+
21+ if ( workingCopy . bookmarks . length > 0 ) {
22+ bookmarkName = workingCopy . bookmarks [ 0 ] ;
23+ changeId = workingCopy . changeId ;
24+ } else if ( workingCopy . isEmpty && workingCopy . description . trim ( ) === "" ) {
25+ // On empty WC, look at the parent below for a bookmark with a PR
26+ for ( const parent of parents ) {
27+ if ( parent . bookmarks . length > 0 ) {
28+ bookmarkName = parent . bookmarks [ 0 ] ;
29+ changeId = parent . changeId ;
30+ break ;
31+ }
32+ }
33+ }
34+
35+ if ( ! bookmarkName ) {
1836 console . error (
1937 formatError (
2038 "No bookmark on current change. Submit first with 'arr submit'" ,
2139 ) ,
2240 ) ;
2341 process . exit ( 1 ) ;
2442 }
25-
26- const bookmarkName = workingCopy . bookmarks [ 0 ] ;
2743 const pr = unwrap ( await github . getPRForBranch ( bookmarkName ) ) ;
2844
2945 if ( ! pr ) {
@@ -45,15 +61,43 @@ export async function merge(flags: MergeFlags = {}): Promise<void> {
4561 process . exit ( 1 ) ;
4662 }
4763
64+ // Check if this is a stacked PR (base is not trunk)
65+ if ( pr . baseRefName !== trunk ) {
66+ console . error (
67+ formatError (
68+ `Cannot merge: PR #${ pr . number } is stacked on ${ cyan ( pr . baseRefName ) } ` ,
69+ ) ,
70+ ) ;
71+ console . log (
72+ dim ( ` Merge the base PR first, or use 'arr merge --stack' to merge all` ) ,
73+ ) ;
74+ process . exit ( 1 ) ;
75+ }
76+
4877 let method : "merge" | "squash" | "rebase" = "squash" ;
4978 if ( flags . merge ) method = "merge" ;
5079 if ( flags . rebase ) method = "rebase" ;
5180
5281 console . log ( `Merging PR #${ cyan ( String ( pr . number ) ) } : ${ pr . title } ` ) ;
5382
54- unwrap ( await github . mergePR ( pr . number , { method } ) ) ;
83+ // Merge and delete the remote branch to prevent stale references
84+ unwrap (
85+ await github . mergePR ( pr . number , {
86+ method,
87+ deleteHead : true ,
88+ headRef : bookmarkName ,
89+ } ) ,
90+ ) ;
5591 console . log ( formatSuccess ( `Merged PR #${ pr . number } ` ) ) ;
5692
93+ // Clean up local state: delete bookmark and abandon change
94+ if ( bookmarkName ) {
95+ await jj . deleteBookmark ( bookmarkName ) ;
96+ }
97+ if ( changeId ) {
98+ await jj . abandon ( changeId ) ;
99+ }
100+
57101 console . log ( dim ( " Syncing to update local state..." ) ) ;
58102 unwrap ( await jj . sync ( ) ) ;
59103 console . log ( formatSuccess ( "Done! Change has been merged and synced." ) ) ;
0 commit comments