@@ -26,6 +26,8 @@ export interface GitQuickAction {
2626 hint ?: string ;
2727}
2828
29+ const FALLBACK_DEFAULT_BRANCH_NAMES = new Set ( [ "main" , "master" ] ) ;
30+
2931export interface DefaultBranchActionDialogCopy {
3032 title : string ;
3133 description : string ;
@@ -105,6 +107,22 @@ export function buildGitActionProgressStages(input: {
105107const withDescription = ( title : string , description : string | undefined ) =>
106108 description ? { title, description } : { title } ;
107109
110+ function extractTrackedBranchName ( upstreamBranch : string | null | undefined ) : string | null {
111+ if ( ! upstreamBranch ) return null ;
112+ const branchName = upstreamBranch . trim ( ) ;
113+ return branchName . length > 0 ? branchName : null ;
114+ }
115+
116+ function tracksDefaultUpstream (
117+ gitStatus : GitStatusResult ,
118+ defaultBranchName ?: string | null ,
119+ ) : boolean {
120+ const trackedBranchName = extractTrackedBranchName ( gitStatus . upstreamBranch ) ;
121+ if ( ! trackedBranchName ) return false ;
122+ if ( defaultBranchName ) return trackedBranchName === defaultBranchName ;
123+ return FALLBACK_DEFAULT_BRANCH_NAMES . has ( trackedBranchName ) ;
124+ }
125+
108126export function summarizeGitResult ( result : GitRunStackedActionResult ) : {
109127 title : string ;
110128 description ?: string ;
@@ -140,13 +158,19 @@ export function buildMenuItems(
140158 isBusy : boolean ,
141159 hasOriginRemote = true ,
142160 isDefaultBranch = false ,
161+ defaultBranchName ?: string | null ,
143162) : GitActionMenuItem [ ] {
144163 if ( ! gitStatus ) return [ ] ;
145164
146165 const hasBranch = gitStatus . branch !== null ;
147166 const hasChanges = gitStatus . hasWorkingTreeChanges ;
148167 const hasOpenPr = gitStatus . pr ?. state === "open" ;
149168 const isBehind = gitStatus . behindCount > 0 ;
169+ const canCreateCleanPublishedPr =
170+ ! isDefaultBranch &&
171+ gitStatus . hasUpstream &&
172+ gitStatus . upstreamBranch !== null &&
173+ ! tracksDefaultUpstream ( gitStatus , defaultBranchName ) ;
150174 const canPushWithoutUpstream = hasOriginRemote && ! gitStatus . hasUpstream ;
151175 const canCommit = ! isBusy && hasChanges ;
152176 const canPush =
@@ -168,7 +192,7 @@ export function buildMenuItems(
168192 ! hasChanges &&
169193 ! hasOpenPr &&
170194 ! isBehind &&
171- ( ( ! isDefaultBranch && gitStatus . hasUpstream ) ||
195+ ( canCreateCleanPublishedPr ||
172196 ( gitStatus . aheadCount > 0 && ( gitStatus . hasUpstream || canPushWithoutUpstream ) ) ) ;
173197 const canOpenPr = ! isBusy && hasOpenPr ;
174198
@@ -226,6 +250,7 @@ export function resolveQuickAction(
226250 isDefaultBranch = false ,
227251 hasOriginRemote = true ,
228252 shouldOfferCreateBranch = false ,
253+ defaultBranchName ?: string | null ,
229254) : GitQuickAction {
230255 if ( isBusy ) {
231256 return { label : "Commit" , disabled : true , kind : "show_hint" , hint : "Git action in progress." } ;
@@ -246,6 +271,8 @@ export function resolveQuickAction(
246271 const isAhead = gitStatus . aheadCount > 0 ;
247272 const isBehind = gitStatus . behindCount > 0 ;
248273 const isDiverged = isAhead && isBehind ;
274+ const isTrackingDefaultUpstream = tracksDefaultUpstream ( gitStatus , defaultBranchName ) ;
275+ const hasKnownUpstreamBranch = gitStatus . upstreamBranch !== null ;
249276
250277 if ( ! hasBranch ) {
251278 return {
@@ -288,7 +315,12 @@ export function resolveQuickAction(
288315 return { label : "Commit" , disabled : false , kind : "run_action" , action : "commit" } ;
289316 }
290317 if ( hasOpenPr || isDefaultBranch ) {
291- return { label : "Commit & push" , disabled : false , kind : "run_action" , action : "commit_push" } ;
318+ return {
319+ label : "Commit & push" ,
320+ disabled : false ,
321+ kind : "run_action" ,
322+ action : "commit_push" ,
323+ } ;
292324 }
293325 return {
294326 label : "Commit, push & PR" ,
@@ -358,6 +390,24 @@ export function resolveQuickAction(
358390 return { label : "View PR" , disabled : false , kind : "open_pr" } ;
359391 }
360392
393+ if ( gitStatus . hasUpstream && ! hasKnownUpstreamBranch ) {
394+ return {
395+ label : "Create PR" ,
396+ disabled : true ,
397+ kind : "show_hint" ,
398+ hint : "No branch changes to include in a PR." ,
399+ } ;
400+ }
401+
402+ if ( isTrackingDefaultUpstream ) {
403+ return {
404+ label : "Create PR" ,
405+ disabled : true ,
406+ kind : "show_hint" ,
407+ hint : "No branch changes to include in a PR." ,
408+ } ;
409+ }
410+
361411 if ( ! isDefaultBranch ) {
362412 return {
363413 label : "Create PR" ,
0 commit comments