@@ -78,6 +78,7 @@ import {
7878 ReloadComposerCommand ,
7979} from './protocol' ;
8080import type { ComposerWebviewShowingArgs } from './registration' ;
81+ import type { WorkingTreeDiffs } from './utils' ;
8182import {
8283 convertToComposerDiffInfo ,
8384 createCombinedDiffForCommit ,
@@ -108,6 +109,9 @@ export class ComposerWebviewProvider implements WebviewProvider<State, State, Co
108109 // Telemetry context - tracks composer-specific data for getTelemetryContext
109110 private _context : ComposerContext ;
110111
112+ // Flag to ignore index change tracking for when we need to stage untracked files
113+ private _ignoreIndexChange = false ;
114+
111115 constructor (
112116 protected readonly container : Container ,
113117 protected readonly host : WebviewHost < 'gitlens.composer' > ,
@@ -299,13 +303,30 @@ export class ComposerWebviewProvider implements WebviewProvider<State, State, Co
299303 source ?: Sources ,
300304 isReload ?: boolean ,
301305 ) : Promise < State > {
306+ // Stop repo change subscription so we can deal with untracked files
307+ this . _repositorySubscription ?. dispose ( ) ;
308+ const status = await repo . git . status ?. getStatus ( ) ;
309+ const untrackedPaths = status ?. untrackedChanges . map ( f => f . path ) ;
310+ if ( untrackedPaths ?. length ) {
311+ try {
312+ await repo . git . staging ?. stageFiles ( untrackedPaths , { intentToAdd : true } ) ;
313+ this . _ignoreIndexChange = true ;
314+ } catch { }
315+ }
316+
302317 const [ diffsResult , commitResult , branchResult ] = await Promise . allSettled ( [
303318 // Handle baseCommit - could be string (old format) or ComposerBaseCommit (new format)
304319 getWorkingTreeDiffs ( repo ) ,
305320 repo . git . commits . getCommit ( 'HEAD' ) ,
306321 repo . git . branches . getBranch ( ) ,
307322 ] ) ;
308323
324+ if ( untrackedPaths ?. length ) {
325+ try {
326+ await repo . git . staging ?. unstageFiles ( untrackedPaths ) ;
327+ } catch { }
328+ }
329+
309330 const diffs = getSettledValue ( diffsResult ) ! ;
310331
311332 this . _context . diff . unstagedIncluded = false ;
@@ -755,9 +776,13 @@ export class ComposerWebviewProvider implements WebviewProvider<State, State, Co
755776
756777 private async onRepositoryChanged ( e : RepositoryChangeEvent ) : Promise < void > {
757778 if ( e . repository . id !== this . _currentRepository ?. id ) return ;
758-
779+ const ignoreIndexChange = this . _ignoreIndexChange ;
780+ this . _ignoreIndexChange = false ;
759781 // Only care about index changes (staged/unstaged changes)
760- if ( ! e . changed ( RepositoryChange . Index , RepositoryChangeComparisonMode . Any ) ) {
782+ if (
783+ ! e . changed ( RepositoryChange . Index , RepositoryChangeComparisonMode . Any ) ||
784+ ( ignoreIndexChange && e . changed ( RepositoryChange . Index , RepositoryChangeComparisonMode . Exclusive ) )
785+ ) {
761786 return ;
762787 }
763788
@@ -1089,7 +1114,26 @@ export class ComposerWebviewProvider implements WebviewProvider<State, State, Co
10891114 ) ;
10901115
10911116 // Validate repository safety state before proceeding
1092- const validation = await validateSafetyState ( repo , this . _safetyState , hunksBeingCommitted ) ;
1117+ // Stop repo change subscription so we can deal with untracked files
1118+ let workingTreeDiffs : WorkingTreeDiffs | undefined ;
1119+ if ( this . _context . diff . unstagedIncluded ) {
1120+ this . _repositorySubscription ?. dispose ( ) ;
1121+ const status = await repo . git . status ?. getStatus ( ) ;
1122+ const untrackedPaths = status ?. untrackedChanges . map ( f => f . path ) ;
1123+ if ( untrackedPaths ?. length ) {
1124+ try {
1125+ workingTreeDiffs = await getWorkingTreeDiffs ( repo ) ;
1126+ await repo . git . staging ?. stageFiles ( untrackedPaths ) ;
1127+ } catch { }
1128+ }
1129+ }
1130+
1131+ const validation = await validateSafetyState (
1132+ repo ,
1133+ this . _safetyState ,
1134+ hunksBeingCommitted ,
1135+ workingTreeDiffs ,
1136+ ) ;
10931137 if ( ! validation . isValid ) {
10941138 // Clear loading state and show safety error
10951139 await this . host . notify ( DidFinishCommittingNotification , undefined ) ;
@@ -1197,7 +1241,7 @@ export class ComposerWebviewProvider implements WebviewProvider<State, State, Co
11971241 if (
11981242 stashCommit &&
11991243 stashCommit . ref !== previousStashCommit ?. ref &&
1200- stashCommit . message === stashMessage
1244+ stashCommit . message ?. includes ( stashMessage )
12011245 ) {
12021246 stashedSuccessfully = true ;
12031247 }
0 commit comments