Git - scaffold the git extension API (#305643)

* Git - scaffold the git extension API

* Pull request feedback
This commit is contained in:
Ladislau Szomoru
2026-03-27 13:56:36 +00:00
committed by GitHub
parent 0ed75f3304
commit bdea2b4df8
5 changed files with 46 additions and 1 deletions

View File

@@ -158,6 +158,10 @@ export class ApiRepository implements Repository {
return this.#repository.clean(paths.map(p => Uri.file(p)));
}
restore(paths: string[], options?: { staged?: boolean; ref?: string }) {
return this.#repository.restore(paths.map(p => Uri.file(p)), options);
}
diff(cached?: boolean) {
return this.#repository.diff(cached);
}

View File

@@ -259,6 +259,7 @@ export interface Repository {
add(paths: string[]): Promise<void>;
revert(paths: string[]): Promise<void>;
clean(paths: string[]): Promise<void>;
restore(paths: string[], options?: { staged?: boolean; ref?: string }): Promise<void>;
apply(patch: string, reverse?: boolean): Promise<void>;
apply(patch: string, options?: { allowEmpty?: boolean; reverse?: boolean; threeWay?: boolean; }): Promise<void>;

View File

@@ -2345,6 +2345,26 @@ export class Repository {
}
}
async restore(paths: string[], options?: { staged?: boolean; ref?: string }): Promise<void> {
const args = ['restore'];
if (options?.staged) {
args.push('--staged');
}
if (options?.ref) {
args.push('--source', options.ref);
}
if (paths.length > 0) {
for (const chunk of splitInChunks(paths.map(p => this.sanitizeRelativePath(p)), MAX_CLI_LENGTH)) {
await this.exec([...args, '--', ...chunk]);
}
} else {
await this.exec([...args, '--', '.']);
}
}
async addRemote(name: string, url: string): Promise<void> {
const args = ['remote', 'add', name, url];
await this.exec(args);

View File

@@ -52,6 +52,7 @@ export const enum OperationKind {
RebaseAbort = 'RebaseAbort',
RebaseContinue = 'RebaseContinue',
Refresh = 'Refresh',
Restore = 'Restore',
RevertFiles = 'RevertFiles',
RevList = 'RevList',
RevParse = 'RevParse',
@@ -72,7 +73,7 @@ export type Operation = AddOperation | ApplyOperation | BlameOperation | BranchO
GetBranchOperation | GetBranchesOperation | GetCommitTemplateOperation | GetObjectDetailsOperation | GetObjectFilesOperation | GetRefsOperation |
GetRemoteRefsOperation | HashObjectOperation | IgnoreOperation | LogOperation | LogFileOperation | MergeOperation | MergeAbortOperation |
MergeBaseOperation | MoveOperation | PostCommitCommandOperation | PullOperation | PushOperation | RemoteOperation | RenameBranchOperation |
RemoveOperation | ResetOperation | RebaseOperation | RebaseAbortOperation | RebaseContinueOperation | RefreshOperation | RevertFilesOperation |
RemoveOperation | ResetOperation | RebaseOperation | RebaseAbortOperation | RebaseContinueOperation | RefreshOperation | RestoreOperation | RevertFilesOperation |
RevListOperation | RevParseOperation | SetBranchUpstreamOperation | ShowOperation | StageOperation | StatusOperation | StashOperation |
SubmoduleUpdateOperation | SyncOperation | TagOperation | WorktreeOperation;
@@ -121,6 +122,7 @@ export type RebaseOperation = BaseOperation & { kind: OperationKind.Rebase };
export type RebaseAbortOperation = BaseOperation & { kind: OperationKind.RebaseAbort };
export type RebaseContinueOperation = BaseOperation & { kind: OperationKind.RebaseContinue };
export type RefreshOperation = BaseOperation & { kind: OperationKind.Refresh };
export type RestoreOperation = BaseOperation & { kind: OperationKind.Restore };
export type RevertFilesOperation = BaseOperation & { kind: OperationKind.RevertFiles };
export type RevListOperation = BaseOperation & { kind: OperationKind.RevList };
export type RevParseOperation = BaseOperation & { kind: OperationKind.RevParse };
@@ -179,6 +181,7 @@ export const Operation = {
RebaseAbort: { kind: OperationKind.RebaseAbort, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RebaseAbortOperation,
RebaseContinue: { kind: OperationKind.RebaseContinue, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RebaseContinueOperation,
Refresh: { kind: OperationKind.Refresh, blocking: false, readOnly: false, remote: false, retry: false, showProgress: true } as RefreshOperation,
Restore: (showProgress: boolean) => ({ kind: OperationKind.Restore, blocking: false, readOnly: false, remote: false, retry: false, showProgress } as RestoreOperation),
RevertFiles: (showProgress: boolean) => ({ kind: OperationKind.RevertFiles, blocking: false, readOnly: false, remote: false, retry: false, showProgress } as RevertFilesOperation),
RevList: { kind: OperationKind.RevList, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as RevListOperation,
RevParse: { kind: OperationKind.RevParse, blocking: false, readOnly: true, remote: false, retry: false, showProgress: false } as RevParseOperation,

View File

@@ -1365,6 +1365,23 @@ export class Repository implements Disposable {
});
}
async restore(resources: Uri[], options?: { staged?: boolean; ref?: string }): Promise<void> {
await this.run(
Operation.Restore(!this.optimisticUpdateEnabled()),
async () => {
const resourcePaths = resources.map(r => r.fsPath);
await this.repository.restore(resourcePaths, options);
if (options?.staged) {
// Index was modified;
this.closeDiffEditors([], resourcePaths);
} else {
// Working tree was modified;
this.closeDiffEditors(resourcePaths, []);
}
});
}
async commit(message: string | undefined, opts: CommitOptions = Object.create(null)): Promise<void> {
const indexResources = [...this.indexGroup.resourceStates.map(r => r.resourceUri.fsPath)];
const workingGroupResources = opts.all && opts.all !== 'tracked' ?