@@ -44,6 +44,8 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
4444 this . _contextMenuStaged = new Menu ( { commands } ) ;
4545 this . _contextMenuUnstaged = new Menu ( { commands } ) ;
4646 this . _contextMenuUntracked = new Menu ( { commands } ) ;
47+ this . _contextMenuSimpleUntracked = new Menu ( { commands } ) ;
48+ this . _contextMenuSimpleTracked = new Menu ( { commands } ) ;
4749
4850 this . state = {
4951 selectedFile : null
@@ -134,7 +136,7 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
134136 label : 'Discard' ,
135137 caption : 'Discard recent changes of selected file' ,
136138 execute : ( ) => {
137- this . discardChanges ( this . state . selectedFile . to ) ;
139+ this . discardChanges ( this . state . selectedFile ) ;
138140 }
139141 } ) ;
140142 }
@@ -159,6 +161,18 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
159161 [ CommandIDs . gitFileOpen , CommandIDs . gitFileTrack ] . forEach ( command => {
160162 this . _contextMenuUntracked . addItem ( { command } ) ;
161163 } ) ;
164+
165+ [
166+ CommandIDs . gitFileOpen ,
167+ CommandIDs . gitFileDiscard ,
168+ CommandIDs . gitFileDiffWorking
169+ ] . forEach ( command => {
170+ this . _contextMenuSimpleTracked . addItem ( { command } ) ;
171+ } ) ;
172+
173+ [ CommandIDs . gitFileOpen ] . forEach ( command => {
174+ this . _contextMenuSimpleUntracked . addItem ( { command } ) ;
175+ } ) ;
162176 }
163177
164178 /** Handle right-click on a staged file */
@@ -179,6 +193,18 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
179193 this . _contextMenuUntracked . open ( event . clientX , event . clientY ) ;
180194 } ;
181195
196+ /** Handle right-click on an untracked file in Simple mode*/
197+ contextMenuSimpleUntracked = ( event : React . MouseEvent ) => {
198+ event . preventDefault ( ) ;
199+ this . _contextMenuSimpleUntracked . open ( event . clientX , event . clientY ) ;
200+ } ;
201+
202+ /** Handle right-click on an tracked file in Simple mode*/
203+ contextMenuSimpleTracked = ( event : React . MouseEvent ) => {
204+ event . preventDefault ( ) ;
205+ this . _contextMenuSimpleTracked . open ( event . clientX , event . clientY ) ;
206+ } ;
207+
182208 /** Reset all staged files */
183209 resetAllStagedFiles = async ( ) => {
184210 await this . props . model . reset ( ) ;
@@ -234,23 +260,31 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
234260 } ;
235261
236262 /** Discard changes in a specific unstaged or staged file */
237- discardChanges = async ( file : string ) => {
263+ discardChanges = async ( file : Git . IStatusFile ) => {
238264 const result = await showDialog ( {
239265 title : 'Discard changes' ,
240266 body : (
241267 < span >
242- Are you sure you want to permanently discard changes to < b > { file } </ b > ?
243- This action cannot be undone.
268+ Are you sure you want to permanently discard changes to{ ' ' }
269+ < b > { file . to } </ b > ? This action cannot be undone.
244270 </ span >
245271 ) ,
246272 buttons : [ Dialog . cancelButton ( ) , Dialog . warnButton ( { label : 'Discard' } ) ]
247273 } ) ;
248274 if ( result . button . accept ) {
249275 try {
250- await this . props . model . reset ( file ) ;
251- await this . props . model . checkout ( { filename : file } ) ;
276+ if ( file . status === 'staged' || file . status === 'partially-staged' ) {
277+ await this . props . model . reset ( file . to ) ;
278+ }
279+ if (
280+ file . status === 'unstaged' ||
281+ ( file . status === 'partially-staged' && file . x !== 'A' )
282+ ) {
283+ // resetting an added file moves it to untracked category => checkout will fail
284+ await this . props . model . checkout ( { filename : file . to } ) ;
285+ }
252286 } catch ( reason ) {
253- showErrorMessage ( `Discard changes for ${ file } failed.` , reason , [
287+ showErrorMessage ( `Discard changes for ${ file . to } failed.` , reason , [
254288 Dialog . warnButton ( { label : 'DISMISS' } )
255289 ] ) ;
256290 }
@@ -297,6 +331,16 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
297331 case 'untracked' :
298332 untrackedFiles . push ( file ) ;
299333 break ;
334+ case 'partially-staged' :
335+ stagedFiles . push ( {
336+ ...file ,
337+ status : 'staged'
338+ } ) ;
339+ unstagedFiles . push ( {
340+ ...file ,
341+ status : 'unstaged'
342+ } ) ;
343+ break ;
300344
301345 default :
302346 break ;
@@ -325,7 +369,8 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
325369 this . state . selectedFile . x === candidate . x &&
326370 this . state . selectedFile . y === candidate . y &&
327371 this . state . selectedFile . from === candidate . from &&
328- this . state . selectedFile . to === candidate . to
372+ this . state . selectedFile . to === candidate . to &&
373+ this . state . selectedFile . status === candidate . status
329374 ) ;
330375 }
331376
@@ -443,7 +488,7 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
443488 iconName = { 'git-discard' }
444489 title = { 'Discard changes' }
445490 onClick = { ( ) => {
446- this . discardChanges ( file . to ) ;
491+ this . discardChanges ( file ) ;
447492 } }
448493 />
449494 < ActionButton
@@ -569,9 +614,13 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
569614 ? ( ) : void => undefined
570615 : openFile ;
571616
572- let diffButton : JSX . Element ;
573- if ( file . status === 'unstaged' ) {
574- diffButton = this . _createDiffButton ( file , 'WORKING' ) ;
617+ let contextMenu = this . contextMenuSimpleUntracked ;
618+
619+ if (
620+ file . status === 'unstaged' ||
621+ file . status === 'partially-staged'
622+ ) {
623+ const diffButton = this . _createDiffButton ( file , 'WORKING' ) ;
575624 actions = (
576625 < React . Fragment >
577626 < ActionButton
@@ -586,7 +635,7 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
586635 iconName = { 'git-discard' }
587636 title = { 'Discard changes' }
588637 onClick = { ( ) => {
589- this . discardChanges ( file . to ) ;
638+ this . discardChanges ( file ) ;
590639 } }
591640 />
592641 </ React . Fragment >
@@ -596,8 +645,9 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
596645 ? ( ) => this . _openDiffView ( file , 'WORKING' )
597646 : ( ) => undefined
598647 : openFile ;
648+ contextMenu = this . contextMenuSimpleTracked ;
599649 } else if ( file . status === 'staged' ) {
600- diffButton = this . _createDiffButton ( file , 'INDEX' ) ;
650+ const diffButton = this . _createDiffButton ( file , 'INDEX' ) ;
601651 actions = (
602652 < React . Fragment >
603653 < ActionButton
@@ -607,13 +657,22 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
607657 onClick = { openFile }
608658 />
609659 { diffButton }
660+ < ActionButton
661+ className = { hiddenButtonStyle }
662+ iconName = { 'git-discard' }
663+ title = { 'Discard changes' }
664+ onClick = { ( ) => {
665+ this . discardChanges ( file ) ;
666+ } }
667+ />
610668 </ React . Fragment >
611669 ) ;
612670 onDoubleClick = doubleClickDiff
613671 ? diffButton
614672 ? ( ) => this . _openDiffView ( file , 'INDEX' )
615673 : ( ) => undefined
616674 : openFile ;
675+ contextMenu = this . contextMenuSimpleTracked ;
617676 }
618677
619678 return (
@@ -624,6 +683,8 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
624683 markBox = { true }
625684 model = { this . props . model }
626685 onDoubleClick = { onDoubleClick }
686+ contextMenu = { contextMenu }
687+ selectFile = { this . updateSelectedFile }
627688 />
628689 ) ;
629690 } ) }
@@ -683,4 +744,6 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
683744 private _contextMenuStaged : Menu ;
684745 private _contextMenuUnstaged : Menu ;
685746 private _contextMenuUntracked : Menu ;
747+ private _contextMenuSimpleTracked : Menu ;
748+ private _contextMenuSimpleUntracked : Menu ;
686749}
0 commit comments