Repository: microsoft/vscode
File: extensions/git/src/repository.ts (TypeScript)

Code before:
			// copy operation.
			this._copyWorktreeIncludeFiles(worktreePath!);

			return worktreePath!;
		});
	}

	private async _getWorktreeIncludeFiles(): Promise<Set<string>> {
		const config = workspace.getConfiguration('git', Uri.file(this.root));
		const worktreeIncludeFiles = config.get<string[]>('worktreeIncludeFiles', ['**/node_modules/**']);

		if (worktreeIncludeFiles.length === 0) {
			return new Set<string>();
		}

		try {
			// Expand the glob patterns
			const matchedFiles = new Set<string>();
			for (const pattern of worktreeIncludeFiles) {
				for await (const file of fsPromises.glob(pattern, { cwd: this.root })) {
					matchedFiles.add(file);
				}
			}

			// Collect unique directories from all the matched files. Check
			// first whether directories are ignored in order to limit the
			// number of git check-ignore calls.
			const directoriesToCheck = new Set<string>();
			for (const file of matchedFiles) {
				let parent = path.dirname(file);
				while (parent && parent !== '.') {
					directoriesToCheck.add(path.join(this.root, parent));
					parent = path.dirname(parent);
				}
			}

			const gitIgnoredDirectories = await this.checkIgnore(Array.from(directoriesToCheck));

			// Files under a git ignored directory are ignored
			const gitIgnoredFiles = new Set<string>();
			const filesToCheck: string[] = [];

			for (const file of matchedFiles) {
				const fullPath = path.join(this.root, file);
				let parent = path.dirname(fullPath);
				let isUnderIgnoredDir = false;

				while (parent !== this.root && parent.length > this.root.length) {
					if (gitIgnoredDirectories.has(parent)) {
						isUnderIgnoredDir = true;
						break;

Review comment (suggestion):
I suspect this would be a good place to apply the new ignoreGlobCase option, but perhaps internally at the API entry point vs. passing as an argument...

Code after:
			// copy operation.
			this._copyWorktreeIncludeFiles(worktreePath!);

			return worktreePath!;
		});
	}

	private async _getWorktreeIncludeFiles(): Promise<Set<string>> {
		const config = workspace.getConfiguration('git', Uri.file(this.root));
		const worktreeIncludeFiles = config.get<string[]>('worktreeIncludeFiles', ['**/node_modules/**']);

		if (worktreeIncludeFiles.length === 0) {
			return new Set<string>();
		}

		const filePattern = worktreeIncludeFiles
			.map(pattern => new RelativePattern(this.root, pattern));

		// Get all files matching the globs (no ignore files applied)
		const allFiles = await workspace.findFiles2(filePattern, {
			useExcludeSettings: ExcludeSettingOptions.None,
			useIgnoreFiles: { local: false, parent: false, global: false }
		});

		// Get files matching the globs with git ignore files applied
		const nonIgnoredFiles = await workspace.findFiles2(filePattern, {
			useExcludeSettings: ExcludeSettingOptions.None,
			useIgnoreFiles: { local: true, parent: true, global: true }
		});

		// Files that are git ignored = all files - non-ignored files
		const gitIgnoredFiles = new Set(allFiles.map(uri => uri.fsPath));
		for (const uri of nonIgnoredFiles) {
			gitIgnoredFiles.delete(uri.fsPath);
		}

		return gitIgnoredFiles;
	}

	private async _copyWorktreeIncludeFiles(worktreePath: string): Promise<void> {
		const ignoredFiles = await this._getWorktreeIncludeFiles();
		if (ignoredFiles.size === 0) {
			return;
		}

		try {
			// Copy files
			let copiedFiles = 0;
			const results = await window.withProgress({
				location: ProgressLocation.Notification,
				title: l10n.t('Copying additional files to the worktree'),