3.5 KB107 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {ImportStack} from 'shared/types/stack';
9import type {PartialSelection} from '../partialSelection';
10import type {
11 ApplyUncommittedChangesPreviewsFuncType,
12 UncommittedChangesPreviewContext,
13} from '../previews';
14import type {RepoRelativePath, UncommittedChanges} from '../types';
15
16import {t} from '../i18n';
17import {Operation} from './Operation';
18
19/**
20 * "Discard" is not an actual command, but the effect of removing all uncommitted changes is accomplished by `goto --clean .`
21 * This leaves behind untracked files, which may be separately removed by `purge --files`.
22 */
23export class DiscardOperation extends Operation {
24 static opName = 'Discard';
25
26 constructor() {
27 super('DiscardOperation');
28 }
29
30 getArgs() {
31 const args = ['goto', '--clean', '.'];
32 return args;
33 }
34
35 makeOptimisticUncommittedChangesApplier?(
36 context: UncommittedChangesPreviewContext,
37 ): ApplyUncommittedChangesPreviewsFuncType | undefined {
38 const trackedChangeTypes = ['M', 'A', 'R', '!'];
39 if (
40 context.uncommittedChanges.length === 0 ||
41 // some files may become untracked after clean goto
42 context.uncommittedChanges.every(change => !trackedChangeTypes.includes(change.status))
43 ) {
44 return undefined;
45 }
46
47 const func: ApplyUncommittedChangesPreviewsFuncType = (changes: UncommittedChanges) => {
48 // clean goto leaves behind untracked files
49 return changes.filter(change => !trackedChangeTypes.includes(change.status));
50 };
51 return func;
52 }
53}
54
55/**
56 * Removes selected uncommitted changes to make them disappare from `status` or `diff`.
57 * - Delete selected `A` or `?` files, so they disappear from `status`
58 * - Restore selected `R` or `!` files, so they disappear from `status`.
59 * - Revert selected `M` files, so they disappear from status.
60 * - For partially selected files, their content will be reverted by dropping
61 * the selected changes (line insertions or deletions), similar to `revert -i`.
62 * The selected changes will disappear from `diff` output.
63 *
64 * This might replace DiscardOperation in the future. For now they might still be different,
65 * since this operation only writes the working copy without changing the dirstate.
66 */
67export class PartialDiscardOperation extends Operation {
68 static opName = 'Discard';
69
70 constructor(
71 private selection: PartialSelection,
72 private allFiles: Array<RepoRelativePath>,
73 ) {
74 super('PartialDiscardOperation');
75 }
76
77 getArgs() {
78 return ['debugimportstack'];
79 }
80
81 getStdin(): string | undefined {
82 const inverse = true;
83 const files = this.selection.calculateImportStackFiles(this.allFiles, inverse);
84 const importStack: ImportStack = [['write', files]];
85 return JSON.stringify(importStack);
86 }
87
88 getDescriptionForDisplay() {
89 return {
90 description: t('Discarding selected changes'),
91 tooltip: t(
92 'This operation does not have a traditional command line equivalent. \n' +
93 'You can use `revert -i`, `goto --clean`, `purge` for similar effects.',
94 ),
95 };
96 }
97
98 makeOptimisticUncommittedChangesApplier?(
99 _context: UncommittedChangesPreviewContext,
100 ): ApplyUncommittedChangesPreviewsFuncType | undefined {
101 const func: ApplyUncommittedChangesPreviewsFuncType = (changes: UncommittedChanges) => {
102 return changes.filter(change => !this.selection.isFullySelected(change.path));
103 };
104 return func;
105 }
106}
107