Skip to content

Commit 17c88bf

Browse files
authored
Git - extract code into UnsafeRepositoryManager (microsoft#184896)
1 parent 70dff6d commit 17c88bf

File tree

2 files changed

+60
-46
lines changed

2 files changed

+60
-46
lines changed

extensions/git/src/commands.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3503,10 +3503,10 @@ export class CommandCenter {
35033503

35043504
const allRepositoriesLabel = l10n.t('All Repositories');
35053505
const allRepositoriesQuickPickItem: QuickPickItem = { label: allRepositoriesLabel };
3506-
const repositoriesQuickPickItems: QuickPickItem[] = Array.from(this.model.unsafeRepositories.keys())
3506+
const repositoriesQuickPickItems: QuickPickItem[] = this.model.unsafeRepositories
35073507
.sort(compareRepositoryLabel).map(r => new RepositoryItem(r));
35083508

3509-
quickpick.items = this.model.unsafeRepositories.size === 1 ? [...repositoriesQuickPickItems] :
3509+
quickpick.items = this.model.unsafeRepositories.length === 1 ? [...repositoriesQuickPickItems] :
35103510
[...repositoriesQuickPickItems, { label: '', kind: QuickPickItemKind.Separator }, allRepositoriesQuickPickItem];
35113511

35123512
quickpick.show();
@@ -3523,19 +3523,19 @@ export class CommandCenter {
35233523

35243524
if (repositoryItem.label === allRepositoriesLabel) {
35253525
// All Repositories
3526-
unsafeRepositories.push(...this.model.unsafeRepositories.keys());
3526+
unsafeRepositories.push(...this.model.unsafeRepositories);
35273527
} else {
35283528
// One Repository
35293529
unsafeRepositories.push((repositoryItem as RepositoryItem).path);
35303530
}
35313531

35323532
for (const unsafeRepository of unsafeRepositories) {
35333533
// Mark as Safe
3534-
await this.git.addSafeDirectory(this.model.unsafeRepositories.get(unsafeRepository)!);
3534+
await this.git.addSafeDirectory(this.model.getUnsafeRepositoryPath(unsafeRepository)!);
35353535

35363536
// Open Repository
35373537
await this.model.openRepository(unsafeRepository);
3538-
this.model.unsafeRepositories.delete(unsafeRepository);
3538+
this.model.deleteUnsafeRepository(unsafeRepository);
35393539
}
35403540
}
35413541

extensions/git/src/model.ts

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,40 +34,6 @@ class RepositoryPick implements QuickPickItem {
3434
constructor(public readonly repository: Repository, public readonly index: number) { }
3535
}
3636

37-
abstract class RepositoryMap<T = void> extends Map<string, T> {
38-
constructor() {
39-
super();
40-
this.updateContextKey();
41-
}
42-
43-
override set(key: string, value: T): this {
44-
const result = super.set(key, value);
45-
this.updateContextKey();
46-
47-
return result;
48-
}
49-
50-
override delete(key: string): boolean {
51-
const result = super.delete(key);
52-
this.updateContextKey();
53-
54-
return result;
55-
}
56-
57-
abstract updateContextKey(): void;
58-
}
59-
60-
/**
61-
* Key - normalized path used in user interface
62-
* Value - path extracted from the output of the `git status` command
63-
* used when calling `git config --global --add safe.directory`
64-
*/
65-
class UnsafeRepositoryMap extends RepositoryMap<string> {
66-
updateContextKey(): void {
67-
commands.executeCommand('setContext', 'git.unsafeRepositoryCount', this.size);
68-
}
69-
}
70-
7137
export interface ModelChangeEvent {
7238
repository: Repository;
7339
uri: Uri;
@@ -159,6 +125,45 @@ class ParentRepositoriesManager {
159125
}
160126
}
161127

128+
class UnsafeRepositoriesManager {
129+
130+
/**
131+
* Key - normalized path used in user interface
132+
* Value - path extracted from the output of the `git status` command
133+
* used when calling `git config --global --add safe.directory`
134+
*/
135+
private _repositories = new Map<string, string>();
136+
get repositories(): string[] {
137+
return [...this._repositories.keys()];
138+
}
139+
140+
addRepository(repository: string, path: string): void {
141+
this._repositories.set(repository, path);
142+
this.onDidChangeRepositories();
143+
}
144+
145+
deleteRepository(repository: string): boolean {
146+
const result = this._repositories.delete(repository);
147+
if (result) {
148+
this.onDidChangeRepositories();
149+
}
150+
151+
return result;
152+
}
153+
154+
getRepositoryPath(repository: string): string | undefined {
155+
return this._repositories.get(repository);
156+
}
157+
158+
hasRepository(repository: string): boolean {
159+
return this._repositories.has(repository);
160+
}
161+
162+
private onDidChangeRepositories(): void {
163+
commands.executeCommand('setContext', 'git.unsafeRepositoryCount', this._repositories.size);
164+
}
165+
}
166+
162167
export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePublisherRegistry, IPostCommitCommandsProviderRegistry, IPushErrorHandlerRegistry {
163168

164169
private _onDidOpenRepository = new EventEmitter<Repository>();
@@ -226,9 +231,9 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
226231

227232
private pushErrorHandlers = new Set<PushErrorHandler>();
228233

229-
private _unsafeRepositories = new UnsafeRepositoryMap();
230-
get unsafeRepositories(): UnsafeRepositoryMap {
231-
return this._unsafeRepositories;
234+
private _unsafeRepositoriesManager: UnsafeRepositoriesManager;
235+
get unsafeRepositories(): string[] {
236+
return this._unsafeRepositoriesManager.repositories;
232237
}
233238

234239
private _parentRepositoriesManager: ParentRepositoriesManager;
@@ -257,6 +262,7 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
257262
// Repositories managers
258263
this._closedRepositoriesManager = new ClosedRepositoriesManager(workspaceState);
259264
this._parentRepositoriesManager = new ParentRepositoriesManager(globalState);
265+
this._unsafeRepositoriesManager = new UnsafeRepositoriesManager();
260266

261267
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
262268
window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables);
@@ -296,7 +302,7 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
296302
parentRepositoryConfig === 'prompt') {
297303
// Parent repositories notification
298304
this.showParentRepositoryNotification();
299-
} else if (this._unsafeRepositories.size !== 0) {
305+
} else if (this.unsafeRepositories.length !== 0) {
300306
// Unsafe repositories notification
301307
this.showUnsafeRepositoryNotification();
302308
}
@@ -547,11 +553,11 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
547553
this.logger.trace(`Unsafe repository: ${repositoryRoot}`);
548554

549555
// Show a notification if the unsafe repository is opened after the initial scan
550-
if (this._state === 'initialized' && !this._unsafeRepositories.has(repositoryRoot)) {
556+
if (this._state === 'initialized' && !this._unsafeRepositoriesManager.hasRepository(repositoryRoot)) {
551557
this.showUnsafeRepositoryNotification();
552558
}
553559

554-
this._unsafeRepositories.set(repositoryRoot, unsafeRepositoryMatch[2]);
560+
this._unsafeRepositoriesManager.addRepository(repositoryRoot, unsafeRepositoryMatch[2]);
555561

556562
return;
557563
}
@@ -903,6 +909,14 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
903909
return [...this.pushErrorHandlers];
904910
}
905911

912+
getUnsafeRepositoryPath(repository: string): string | undefined {
913+
return this._unsafeRepositoriesManager.getRepositoryPath(repository);
914+
}
915+
916+
deleteUnsafeRepository(repository: string): boolean {
917+
return this._unsafeRepositoriesManager.deleteRepository(repository);
918+
}
919+
906920
private async isRepositoryOutsideWorkspace(repositoryPath: string): Promise<boolean> {
907921
const workspaceFolders = (workspace.workspaceFolders || [])
908922
.filter(folder => folder.uri.scheme === 'file');
@@ -969,7 +983,7 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
969983
return;
970984
}
971985

972-
const message = this._unsafeRepositories.size === 1 ?
986+
const message = this.unsafeRepositories.length === 1 ?
973987
l10n.t('The git repository in the current folder is potentially unsafe as the folder is owned by someone other than the current user.') :
974988
l10n.t('The git repositories in the current folder are potentially unsafe as the folders are owned by someone other than the current user.');
975989

0 commit comments

Comments
 (0)