Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/git/src/operation.ts
3314 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
/* eslint-disable local/code-no-dangerous-type-assertions */
6
7
import { LogOutputChannel } from 'vscode';
8
9
export const enum OperationKind {
10
Add = 'Add',
11
Apply = 'Apply',
12
Blame = 'Blame',
13
Branch = 'Branch',
14
CheckIgnore = 'CheckIgnore',
15
Checkout = 'Checkout',
16
CheckoutTracking = 'CheckoutTracking',
17
CherryPick = 'CherryPick',
18
Clean = 'Clean',
19
Commit = 'Commit',
20
Config = 'Config',
21
DeleteBranch = 'DeleteBranch',
22
DeleteRef = 'DeleteRef',
23
DeleteRemoteRef = 'DeleteRemoteRef',
24
DeleteTag = 'DeleteTag',
25
DeleteWorktree = 'DeleteWorktree',
26
Diff = 'Diff',
27
Fetch = 'Fetch',
28
FindTrackingBranches = 'GetTracking',
29
GetBranch = 'GetBranch',
30
GetBranches = 'GetBranches',
31
GetCommitTemplate = 'GetCommitTemplate',
32
GetObjectDetails = 'GetObjectDetails',
33
GetObjectFiles = 'GetObjectFiles',
34
GetRefs = 'GetRefs',
35
GetWorktrees = 'GetWorktrees',
36
GetRemoteRefs = 'GetRemoteRefs',
37
HashObject = 'HashObject',
38
Ignore = 'Ignore',
39
Log = 'Log',
40
LogFile = 'LogFile',
41
Merge = 'Merge',
42
MergeAbort = 'MergeAbort',
43
MergeBase = 'MergeBase',
44
Move = 'Move',
45
PostCommitCommand = 'PostCommitCommand',
46
Pull = 'Pull',
47
Push = 'Push',
48
Remote = 'Remote',
49
RenameBranch = 'RenameBranch',
50
Remove = 'Remove',
51
Reset = 'Reset',
52
Rebase = 'Rebase',
53
RebaseAbort = 'RebaseAbort',
54
RebaseContinue = 'RebaseContinue',
55
Refresh = 'Refresh',
56
RevertFiles = 'RevertFiles',
57
RevList = 'RevList',
58
RevParse = 'RevParse',
59
SetBranchUpstream = 'SetBranchUpstream',
60
Show = 'Show',
61
Stage = 'Stage',
62
Status = 'Status',
63
Stash = 'Stash',
64
SubmoduleUpdate = 'SubmoduleUpdate',
65
Sync = 'Sync',
66
Tag = 'Tag',
67
Worktree = 'Worktree'
68
}
69
70
export type Operation = AddOperation | ApplyOperation | BlameOperation | BranchOperation | CheckIgnoreOperation | CherryPickOperation |
71
CheckoutOperation | CheckoutTrackingOperation | CleanOperation | CommitOperation | ConfigOperation | DeleteBranchOperation |
72
DeleteRefOperation | DeleteRemoteRefOperation | DeleteTagOperation | DeleteWorktreeOperation | DiffOperation | FetchOperation | FindTrackingBranchesOperation |
73
GetBranchOperation | GetBranchesOperation | GetCommitTemplateOperation | GetObjectDetailsOperation | GetObjectFilesOperation | GetRefsOperation | GetWorktreesOperation |
74
GetRemoteRefsOperation | HashObjectOperation | IgnoreOperation | LogOperation | LogFileOperation | MergeOperation | MergeAbortOperation |
75
MergeBaseOperation | MoveOperation | PostCommitCommandOperation | PullOperation | PushOperation | RemoteOperation | RenameBranchOperation |
76
RemoveOperation | ResetOperation | RebaseOperation | RebaseAbortOperation | RebaseContinueOperation | RefreshOperation | RevertFilesOperation |
77
RevListOperation | RevParseOperation | SetBranchUpstreamOperation | ShowOperation | StageOperation | StatusOperation | StashOperation |
78
SubmoduleUpdateOperation | SyncOperation | TagOperation | WorktreeOperation;
79
80
type BaseOperation = { kind: OperationKind; blocking: boolean; readOnly: boolean; remote: boolean; retry: boolean; showProgress: boolean };
81
export type AddOperation = BaseOperation & { kind: OperationKind.Add };
82
export type ApplyOperation = BaseOperation & { kind: OperationKind.Apply };
83
export type BlameOperation = BaseOperation & { kind: OperationKind.Blame };
84
export type BranchOperation = BaseOperation & { kind: OperationKind.Branch };
85
export type CheckIgnoreOperation = BaseOperation & { kind: OperationKind.CheckIgnore };
86
export type CherryPickOperation = BaseOperation & { kind: OperationKind.CherryPick };
87
export type CheckoutOperation = BaseOperation & { kind: OperationKind.Checkout; refLabel: string };
88
export type CheckoutTrackingOperation = BaseOperation & { kind: OperationKind.CheckoutTracking; refLabel: string };
89
export type CleanOperation = BaseOperation & { kind: OperationKind.Clean };
90
export type CommitOperation = BaseOperation & { kind: OperationKind.Commit };
91
export type ConfigOperation = BaseOperation & { kind: OperationKind.Config };
92
export type DeleteBranchOperation = BaseOperation & { kind: OperationKind.DeleteBranch };
93
export type DeleteRefOperation = BaseOperation & { kind: OperationKind.DeleteRef };
94
export type DeleteRemoteRefOperation = BaseOperation & { kind: OperationKind.DeleteRemoteRef };
95
export type DeleteTagOperation = BaseOperation & { kind: OperationKind.DeleteTag };
96
export type DeleteWorktreeOperation = BaseOperation & { kind: OperationKind.DeleteWorktree };
97
export type DiffOperation = BaseOperation & { kind: OperationKind.Diff };
98
export type FetchOperation = BaseOperation & { kind: OperationKind.Fetch };
99
export type FindTrackingBranchesOperation = BaseOperation & { kind: OperationKind.FindTrackingBranches };
100
export type GetBranchOperation = BaseOperation & { kind: OperationKind.GetBranch };
101
export type GetBranchesOperation = BaseOperation & { kind: OperationKind.GetBranches };
102
export type GetCommitTemplateOperation = BaseOperation & { kind: OperationKind.GetCommitTemplate };
103
export type GetObjectDetailsOperation = BaseOperation & { kind: OperationKind.GetObjectDetails };
104
export type GetObjectFilesOperation = BaseOperation & { kind: OperationKind.GetObjectFiles };
105
export type GetRefsOperation = BaseOperation & { kind: OperationKind.GetRefs };
106
export type GetWorktreesOperation = BaseOperation & { kind: OperationKind.GetWorktrees };
107
export type GetRemoteRefsOperation = BaseOperation & { kind: OperationKind.GetRemoteRefs };
108
export type HashObjectOperation = BaseOperation & { kind: OperationKind.HashObject };
109
export type IgnoreOperation = BaseOperation & { kind: OperationKind.Ignore };
110
export type LogOperation = BaseOperation & { kind: OperationKind.Log };
111
export type LogFileOperation = BaseOperation & { kind: OperationKind.LogFile };
112
export type MergeOperation = BaseOperation & { kind: OperationKind.Merge };
113
export type MergeAbortOperation = BaseOperation & { kind: OperationKind.MergeAbort };
114
export type MergeBaseOperation = BaseOperation & { kind: OperationKind.MergeBase };
115
export type MoveOperation = BaseOperation & { kind: OperationKind.Move };
116
export type PostCommitCommandOperation = BaseOperation & { kind: OperationKind.PostCommitCommand };
117
export type PullOperation = BaseOperation & { kind: OperationKind.Pull };
118
export type PushOperation = BaseOperation & { kind: OperationKind.Push };
119
export type RemoteOperation = BaseOperation & { kind: OperationKind.Remote };
120
export type RenameBranchOperation = BaseOperation & { kind: OperationKind.RenameBranch };
121
export type RemoveOperation = BaseOperation & { kind: OperationKind.Remove };
122
export type ResetOperation = BaseOperation & { kind: OperationKind.Reset };
123
export type RebaseOperation = BaseOperation & { kind: OperationKind.Rebase };
124
export type RebaseAbortOperation = BaseOperation & { kind: OperationKind.RebaseAbort };
125
export type RebaseContinueOperation = BaseOperation & { kind: OperationKind.RebaseContinue };
126
export type RefreshOperation = BaseOperation & { kind: OperationKind.Refresh };
127
export type RevertFilesOperation = BaseOperation & { kind: OperationKind.RevertFiles };
128
export type RevListOperation = BaseOperation & { kind: OperationKind.RevList };
129
export type RevParseOperation = BaseOperation & { kind: OperationKind.RevParse };
130
export type SetBranchUpstreamOperation = BaseOperation & { kind: OperationKind.SetBranchUpstream };
131
export type ShowOperation = BaseOperation & { kind: OperationKind.Show };
132
export type StageOperation = BaseOperation & { kind: OperationKind.Stage };
133
export type StatusOperation = BaseOperation & { kind: OperationKind.Status };
134
export type StashOperation = BaseOperation & { kind: OperationKind.Stash };
135
export type SubmoduleUpdateOperation = BaseOperation & { kind: OperationKind.SubmoduleUpdate };
136
export type SyncOperation = BaseOperation & { kind: OperationKind.Sync };
137
export type TagOperation = BaseOperation & { kind: OperationKind.Tag };
138
export type WorktreeOperation = BaseOperation & { kind: OperationKind.Worktree };
139
140
export const Operation = {
141
Add: (showProgress: boolean): AddOperation => ({ kind: OperationKind.Add, blocking: false, readOnly: false, remote: false, retry: false, showProgress }),
142
Apply: { kind: OperationKind.Apply, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as ApplyOperation,
143
Blame: (showProgress: boolean) => ({ kind: OperationKind.Blame, blocking: false, readOnly: true, remote: false, retry: false, showProgress } as BlameOperation),
144
Branch: { kind: OperationKind.Branch, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as BranchOperation,
145
CheckIgnore: { kind: OperationKind.CheckIgnore, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as CheckIgnoreOperation,
146
CherryPick: { kind: OperationKind.CherryPick, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as CherryPickOperation,
147
Checkout: (refLabel: string) => ({ kind: OperationKind.Checkout, blocking: true, readOnly: false, remote: false, retry: false, showProgress: true, refLabel } as CheckoutOperation),
148
CheckoutTracking: (refLabel: string) => ({ kind: OperationKind.CheckoutTracking, blocking: true, readOnly: false, remote: false, retry: false, showProgress: true, refLabel } as CheckoutTrackingOperation),
149
Clean: (showProgress: boolean) => ({ kind: OperationKind.Clean, blocking: false, readOnly: false, remote: false, retry: false, showProgress } as CleanOperation),
150
Commit: { kind: OperationKind.Commit, blocking: true, readOnly: false, remote: false, retry: false, showProgress: true } as CommitOperation,
151
Config: (readOnly: boolean) => ({ kind: OperationKind.Config, blocking: false, readOnly, remote: false, retry: false, showProgress: false } as ConfigOperation),
152
DeleteBranch: { kind: OperationKind.DeleteBranch, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as DeleteBranchOperation,
153
DeleteRef: { kind: OperationKind.DeleteRef, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as DeleteRefOperation,
154
DeleteRemoteRef: { kind: OperationKind.DeleteRemoteRef, blocking: false, readOnly: false, remote: true, retry: false, showProgress: true } as DeleteRemoteRefOperation,
155
DeleteTag: { kind: OperationKind.DeleteTag, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as DeleteTagOperation,
156
DeleteWorktree: { kind: OperationKind.DeleteWorktree, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as DeleteWorktreeOperation,
157
Diff: { kind: OperationKind.Diff, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as DiffOperation,
158
Fetch: (showProgress: boolean) => ({ kind: OperationKind.Fetch, blocking: false, readOnly: false, remote: true, retry: true, showProgress } as FetchOperation),
159
FindTrackingBranches: { kind: OperationKind.FindTrackingBranches, blocking: false, readOnly: true, remote: false, retry: false, showProgress: true } as FindTrackingBranchesOperation,
160
GetBranch: { kind: OperationKind.GetBranch, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as GetBranchOperation,
161
GetBranches: { kind: OperationKind.GetBranches, blocking: false, readOnly: true, remote: false, retry: false, showProgress: true } as GetBranchesOperation,
162
GetCommitTemplate: { kind: OperationKind.GetCommitTemplate, blocking: false, readOnly: true, remote: false, retry: false, showProgress: true } as GetCommitTemplateOperation,
163
GetObjectDetails: { kind: OperationKind.GetObjectDetails, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as GetObjectDetailsOperation,
164
GetObjectFiles: { kind: OperationKind.GetObjectFiles, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as GetObjectFilesOperation,
165
GetRefs: { kind: OperationKind.GetRefs, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as GetRefsOperation,
166
GetWorktrees: { kind: OperationKind.GetWorktrees, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as GetWorktreesOperation,
167
GetRemoteRefs: { kind: OperationKind.GetRemoteRefs, blocking: false, readOnly: true, remote: true, retry: false, showProgress: false } as GetRemoteRefsOperation,
168
HashObject: { kind: OperationKind.HashObject, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as HashObjectOperation,
169
Ignore: { kind: OperationKind.Ignore, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as IgnoreOperation,
170
Log: (showProgress: boolean) => ({ kind: OperationKind.Log, blocking: false, readOnly: true, remote: false, retry: false, showProgress }) as LogOperation,
171
LogFile: { kind: OperationKind.LogFile, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as LogFileOperation,
172
Merge: { kind: OperationKind.Merge, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as MergeOperation,
173
MergeAbort: { kind: OperationKind.MergeAbort, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as MergeAbortOperation,
174
MergeBase: { kind: OperationKind.MergeBase, blocking: false, readOnly: true, remote: false, retry: false, showProgress: true } as MergeBaseOperation,
175
Move: { kind: OperationKind.Move, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as MoveOperation,
176
PostCommitCommand: { kind: OperationKind.PostCommitCommand, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as PostCommitCommandOperation,
177
Pull: { kind: OperationKind.Pull, blocking: true, readOnly: false, remote: true, retry: true, showProgress: true } as PullOperation,
178
Push: { kind: OperationKind.Push, blocking: true, readOnly: false, remote: true, retry: false, showProgress: true } as PushOperation,
179
Remote: { kind: OperationKind.Remote, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RemoteOperation,
180
RenameBranch: { kind: OperationKind.RenameBranch, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RenameBranchOperation,
181
Remove: { kind: OperationKind.Remove, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RemoveOperation,
182
Reset: { kind: OperationKind.Reset, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as ResetOperation,
183
Rebase: { kind: OperationKind.Rebase, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RebaseOperation,
184
RebaseAbort: { kind: OperationKind.RebaseAbort, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RebaseAbortOperation,
185
RebaseContinue: { kind: OperationKind.RebaseContinue, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RebaseContinueOperation,
186
Refresh: { kind: OperationKind.Refresh, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RefreshOperation,
187
RevertFiles: (showProgress: boolean) => ({ kind: OperationKind.RevertFiles, blocking: false, readOnly: false, remote: false, retry: false, showProgress } as RevertFilesOperation),
188
RevList: { kind: OperationKind.RevList, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as RevListOperation,
189
RevParse: { kind: OperationKind.RevParse, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as RevParseOperation,
190
SetBranchUpstream: { kind: OperationKind.SetBranchUpstream, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as SetBranchUpstreamOperation,
191
Show: { kind: OperationKind.Show, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as ShowOperation,
192
Stage: { kind: OperationKind.Stage, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as StageOperation,
193
Status: { kind: OperationKind.Status, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as StatusOperation,
194
Stash: { kind: OperationKind.Stash, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as StashOperation,
195
SubmoduleUpdate: { kind: OperationKind.SubmoduleUpdate, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as SubmoduleUpdateOperation,
196
Sync: { kind: OperationKind.Sync, blocking: true, readOnly: false, remote: true, retry: true, showProgress: true } as SyncOperation,
197
Tag: { kind: OperationKind.Tag, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as TagOperation,
198
Worktree: { kind: OperationKind.Worktree, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as WorktreeOperation
199
};
200
201
export interface OperationResult {
202
operation: Operation;
203
error: any;
204
}
205
206
interface IOperationManager {
207
getOperations(operationKind: OperationKind): Operation[];
208
isIdle(): boolean;
209
isRunning(operationKind: OperationKind): boolean;
210
shouldDisableCommands(): boolean;
211
shouldShowProgress(): boolean;
212
}
213
214
export class OperationManager implements IOperationManager {
215
216
private operations = new Map<OperationKind, Set<Operation>>();
217
218
constructor(private readonly logger: LogOutputChannel) { }
219
220
start(operation: Operation): void {
221
if (this.operations.has(operation.kind)) {
222
this.operations.get(operation.kind)!.add(operation);
223
} else {
224
this.operations.set(operation.kind, new Set([operation]));
225
}
226
227
this.logger.trace(`[OperationManager][start] ${operation.kind} (blocking: ${operation.blocking}, readOnly: ${operation.readOnly}; retry: ${operation.retry}; showProgress: ${operation.showProgress})`);
228
}
229
230
end(operation: Operation): void {
231
const operationSet = this.operations.get(operation.kind);
232
if (operationSet) {
233
operationSet.delete(operation);
234
if (operationSet.size === 0) {
235
this.operations.delete(operation.kind);
236
}
237
}
238
239
this.logger.trace(`[OperationManager][end] ${operation.kind} (blocking: ${operation.blocking}, readOnly: ${operation.readOnly}; retry: ${operation.retry}; showProgress: ${operation.showProgress})`);
240
}
241
242
getOperations(operationKind: OperationKind): Operation[] {
243
const operationSet = this.operations.get(operationKind);
244
return operationSet ? Array.from(operationSet) : [];
245
}
246
247
isIdle(): boolean {
248
const operationSets = this.operations.values();
249
250
for (const operationSet of operationSets) {
251
for (const operation of operationSet) {
252
if (!operation.readOnly) {
253
return false;
254
}
255
}
256
}
257
258
return true;
259
}
260
261
isRunning(operationKind: OperationKind): boolean {
262
return this.operations.has(operationKind);
263
}
264
265
shouldDisableCommands(): boolean {
266
const operationSets = this.operations.values();
267
268
for (const operationSet of operationSets) {
269
for (const operation of operationSet) {
270
if (operation.blocking) {
271
return true;
272
}
273
}
274
}
275
276
return false;
277
}
278
279
shouldShowProgress(): boolean {
280
const operationSets = this.operations.values();
281
282
for (const operationSet of operationSets) {
283
for (const operation of operationSet) {
284
if (operation.showProgress) {
285
return true;
286
}
287
}
288
}
289
290
return false;
291
}
292
}
293
294