@@ -9,14 +9,21 @@ import { ensureArray } from '../../system/array';
99import { formatDate , fromNow } from '../../system/date' ;
1010import { gate } from '../../system/decorators/-webview/gate' ;
1111import { memoize } from '../../system/decorators/-webview/memoize' ;
12+ import { Lazy } from '../../system/lazy' ;
1213import { getLoggableName } from '../../system/logger' ;
1314import { getSettledValue } from '../../system/promise' ;
1415import { pluralize } from '../../system/string' ;
1516import type { DiffRange , PreviousRangeComparisonUrisResult } from '../gitProvider' ;
1617import { GitUri } from '../gitUri' ;
1718import type { RemoteProvider } from '../remotes/remoteProvider' ;
1819import { getChangedFilesCount } from '../utils/commit.utils' ;
19- import { isSha , isUncommitted , isUncommittedStaged , isUncommittedWithParentSuffix } from '../utils/revision.utils' ;
20+ import {
21+ isSha ,
22+ isUncommitted ,
23+ isUncommittedStaged ,
24+ isUncommittedStagedWithParentSuffix ,
25+ isUncommittedWithParentSuffix ,
26+ } from '../utils/revision.utils' ;
2027import type { GitDiffFileStats } from './diff' ;
2128import type { GitFile } from './file' ;
2229import { GitFileChange } from './fileChange' ;
@@ -122,9 +129,9 @@ export class GitCommit implements GitRevisionReference {
122129 return this . container . CommitDateFormatting . dateSource === 'committed' ? this . committer . date : this . author . date ;
123130 }
124131
125- private _file : GitFileChange | undefined ;
132+ private _file : Lazy < GitFileChange | undefined > | undefined ;
126133 get file ( ) : GitFileChange | undefined {
127- return this . _file ;
134+ return this . _file ?. value ;
128135 }
129136
130137 private _fileset : GitCommitFileset | undefined ;
@@ -133,7 +140,7 @@ export class GitCommit implements GitRevisionReference {
133140 }
134141 private set fileset ( value : GitCommitFileset | undefined ) {
135142 if ( value == null ) {
136- this . _fileset = value ;
143+ this . _fileset = undefined ;
137144 this . _file = undefined ;
138145 return ;
139146 }
@@ -144,41 +151,42 @@ export class GitCommit implements GitRevisionReference {
144151 }
145152 this . _fileset = value ;
146153
147- let file ;
148- if ( value . pathspec ) {
149- if ( value . files . length === 1 ) {
150- [ file ] = value . files ;
151- } else {
152- let files = value . files . filter ( f => f . path === value . pathspec ! ) ;
153- // If we found multiple files with the same path and is uncommitted, then use the existing file if we have one, otherwise use the first
154- if ( files . length > 1 ) {
155- if ( this . isUncommitted ) {
156- file = this . _file ?? files [ 0 ] ;
157- }
158- } else if ( files . length === 1 ) {
159- [ file ] = files ;
154+ const current = this . _file ?. value ;
155+ this . _file = new Lazy ( ( ) => {
156+ let file ;
157+ if ( value . pathspec ) {
158+ if ( value . files . length === 1 ) {
159+ [ file ] = value . files ;
160160 } else {
161- files = value . files . filter ( f => f . path . startsWith ( value . pathspec ! ) ) ;
162- file = files . length === 1 ? files [ 0 ] : undefined ;
161+ let files = value . files . filter ( f => f . path === value . pathspec ! ) ;
162+ // If we found multiple files with the same path and is uncommitted, then use the existing file if we have one, otherwise use the first
163+ if ( files . length > 1 ) {
164+ if ( this . isUncommitted ) {
165+ file = current ?? files [ 0 ] ;
166+ }
167+ } else if ( files . length === 1 ) {
168+ [ file ] = files ;
169+ } else {
170+ files = value . files . filter ( f => f . path . startsWith ( value . pathspec ! ) ) ;
171+ file = files . length === 1 ? files [ 0 ] : undefined ;
172+ }
163173 }
164174 }
165- }
166175
167- if ( file != null ) {
168- this . _file = new GitFileChange (
176+ if ( file == null ) return undefined ;
177+
178+ return new GitFileChange (
169179 this . container ,
170180 file . repoPath ,
171181 file . path ,
172182 file . status ,
173- file . originalPath ?? this . _file ?. originalPath ,
174- file . previousSha ?? this . _file ?. previousSha ,
175- file . stats ?? this . _file ?. stats ,
176- file . staged ?? this . _file ?. staged ,
177- file . range ?? this . _file ?. range ,
183+ file . originalPath ?? current ?. originalPath ,
184+ file . previousSha ?? current ?. previousSha ,
185+ file . stats ?? current ?. stats ,
186+ file . staged ?? current ?. staged ,
187+ file . range ?? current ?. range ,
178188 ) ;
179- } else {
180- this . _file = undefined ;
181- }
189+ } ) ;
182190 }
183191
184192 get formattedDate ( ) : string {
@@ -230,14 +238,18 @@ export class GitCommit implements GitRevisionReference {
230238 this . _resolvedPreviousSha ??
231239 ( this . file != null ? this . file . previousSha : this . parents [ 0 ] ) ??
232240 `${ this . sha } ^` ;
233- return isUncommittedWithParentSuffix ( previousSha ) ? 'HEAD' : previousSha ;
241+ return isUncommittedWithParentSuffix ( previousSha )
242+ ? isUncommittedStagedWithParentSuffix ( previousSha )
243+ ? 'HEAD'
244+ : uncommittedStaged
245+ : previousSha ;
234246 }
235247
236248 private _etagFileSystem : number | undefined ;
237249
238250 hasFullDetails ( options ?: {
239251 allowFilteredFiles ?: boolean ;
240- include ?: { stats ?: boolean } ;
252+ include ?: { stats ?: boolean ; uncommittedFiles ?: boolean } ;
241253 } ) : this is GitCommitWithFullDetails {
242254 if ( this . message == null || this . fileset == null ) return false ;
243255 if ( this . fileset . filtered && ! options ?. allowFilteredFiles ) return false ;
@@ -259,7 +271,10 @@ export class GitCommit implements GitRevisionReference {
259271 }
260272
261273 @gate ( )
262- async ensureFullDetails ( options ?: { allowFilteredFiles ?: boolean ; include ?: { stats ?: boolean } } ) : Promise < void > {
274+ async ensureFullDetails ( options ?: {
275+ allowFilteredFiles ?: boolean ;
276+ include ?: { stats ?: boolean ; uncommittedFiles ?: boolean } ;
277+ } ) : Promise < void > {
263278 if ( this . hasFullDetails ( options ) ) return ;
264279
265280 const repo = this . container . git . getRepository ( this . repoPath ) ;
@@ -268,7 +283,7 @@ export class GitCommit implements GitRevisionReference {
268283 if ( this . isUncommitted ) {
269284 this . _etagFileSystem = repo ?. etagFileSystem ;
270285
271- if ( this . _etagFileSystem != null ) {
286+ if ( this . _etagFileSystem != null || options ?. include ?. uncommittedFiles ) {
272287 const status = await repo ?. git . status ( ) . getStatus ( ) ;
273288 if ( status != null ) {
274289 let files = status . files . flatMap ( f => f . getPseudoFileChanges ( ) ) ;
@@ -576,10 +591,10 @@ export class GitCommit implements GitRevisionReference {
576591
577592 @memoize ( )
578593 getGitUri ( previous : boolean = false ) : GitUri {
579- const uri = this . _file ?. uri ?? this . container . git . getAbsoluteUri ( this . repoPath , this . repoPath ) ;
594+ const uri = this . file ?. uri ?? this . container . git . getAbsoluteUri ( this . repoPath , this . repoPath ) ;
580595 if ( ! previous ) return new GitUri ( uri , this ) ;
581596
582- return new GitUri ( this . _file ?. originalUri ?? uri , {
597+ return new GitUri ( this . file ?. originalUri ?? uri , {
583598 repoPath : this . repoPath ,
584599 sha : this . unresolvedPreviousSha ,
585600 } ) ;
0 commit comments