Browse Source

Moves path normalization to system/path

Abstracts node path imports to system/path
main
Eric Amodio 2 years ago
parent
commit
681368353b
37 changed files with 151 additions and 155 deletions
  1. +1
    -1
      src/annotations/fileAnnotationController.ts
  2. +1
    -1
      src/commands/browseRepoAtRevision.ts
  3. +1
    -1
      src/commands/common.ts
  4. +1
    -1
      src/commands/diffWith.ts
  5. +3
    -3
      src/commands/diffWithRevisionFrom.ts
  6. +2
    -2
      src/commands/git/coauthors.ts
  7. +2
    -2
      src/commands/openFileAtRevisionFrom.ts
  8. +10
    -10
      src/env/node/git/git.ts
  9. +26
    -29
      src/env/node/git/localGitProvider.ts
  10. +1
    -1
      src/git/formatters/statusFormatter.ts
  11. +3
    -3
      src/git/fsProvider.ts
  12. +6
    -5
      src/git/gitProviderService.ts
  13. +16
    -11
      src/git/gitUri.ts
  14. +1
    -1
      src/git/models/repository.ts
  15. +3
    -3
      src/git/parsers/blameParser.ts
  16. +4
    -4
      src/git/parsers/logParser.ts
  17. +2
    -1
      src/git/parsers/stashParser.ts
  18. +4
    -10
      src/git/parsers/statusParser.ts
  19. +1
    -1
      src/quickpicks/commitQuickPickItems.ts
  20. +0
    -1
      src/system.ts
  21. +32
    -10
      src/system/path.ts
  22. +0
    -25
      src/system/string.ts
  23. +2
    -2
      src/views/nodes/branchTrackingStatusFilesNode.ts
  24. +1
    -1
      src/views/nodes/commitFileNode.ts
  25. +2
    -2
      src/views/nodes/commitNode.ts
  26. +1
    -1
      src/views/nodes/fileHistoryNode.ts
  27. +1
    -1
      src/views/nodes/fileRevisionAsCommitNode.ts
  28. +1
    -1
      src/views/nodes/mergeConflictFileNode.ts
  29. +2
    -2
      src/views/nodes/mergeStatusNode.ts
  30. +3
    -3
      src/views/nodes/rebaseStatusNode.ts
  31. +1
    -1
      src/views/nodes/resultsFileNode.ts
  32. +2
    -2
      src/views/nodes/resultsFilesNode.ts
  33. +2
    -2
      src/views/nodes/stashNode.ts
  34. +1
    -1
      src/views/nodes/statusFileNode.ts
  35. +2
    -2
      src/views/nodes/statusFilesNode.ts
  36. +7
    -6
      src/vsls/host.ts
  37. +3
    -2
      src/webviews/rebaseEditor.ts

+ 1
- 1
src/annotations/fileAnnotationController.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { basename } from 'path';
import { import {
ConfigurationChangeEvent, ConfigurationChangeEvent,
DecorationRangeBehavior, DecorationRangeBehavior,
@ -30,6 +29,7 @@ import { Container } from '../container';
import { KeyboardScope } from '../keyboard'; import { KeyboardScope } from '../keyboard';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { Functions, Iterables } from '../system'; import { Functions, Iterables } from '../system';
import { basename } from '../system/path';
import { import {
DocumentBlameStateChangeEvent, DocumentBlameStateChangeEvent,
DocumentDirtyStateChangeEvent, DocumentDirtyStateChangeEvent,

+ 1
- 1
src/commands/browseRepoAtRevision.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { basename } from 'path';
import { commands, TextEditor, Uri } from 'vscode'; import { commands, TextEditor, Uri } from 'vscode';
import { BuiltInCommands } from '../constants'; import { BuiltInCommands } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
@ -7,6 +6,7 @@ import { toGitLensFSUri } from '../git/fsProvider';
import { GitUri } from '../git/gitUri'; import { GitUri } from '../git/gitUri';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { Messages } from '../messages'; import { Messages } from '../messages';
import { basename } from '../system/path';
import { import {
ActiveEditorCommand, ActiveEditorCommand,
command, command,

+ 1
- 1
src/commands/common.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { extname } from 'path';
import { import {
commands, commands,
Disposable, Disposable,
@ -32,6 +31,7 @@ import {
} from '../git/models'; } from '../git/models';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { CommandQuickPickItem, RepositoryPicker } from '../quickpicks'; import { CommandQuickPickItem, RepositoryPicker } from '../quickpicks';
import { extname } from '../system/path';
import { ViewNode, ViewRefNode } from '../views/nodes'; import { ViewNode, ViewRefNode } from '../views/nodes';
export const enum Commands { export const enum Commands {

+ 1
- 1
src/commands/diffWith.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { basename } from 'path';
import { commands, Range, TextDocumentShowOptions, Uri, ViewColumn } from 'vscode'; import { commands, Range, TextDocumentShowOptions, Uri, ViewColumn } from 'vscode';
import { BuiltInCommands, GlyphChars } from '../constants'; import { BuiltInCommands, GlyphChars } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
@ -7,6 +6,7 @@ import { GitUri } from '../git/gitUri';
import { GitCommit, GitRevision } from '../git/models'; import { GitCommit, GitRevision } from '../git/models';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { Messages } from '../messages'; import { Messages } from '../messages';
import { basename } from '../system/path';
import { command, Command, Commands } from './common'; import { command, Command, Commands } from './common';
export interface DiffWithCommandArgsRevision { export interface DiffWithCommandArgsRevision {

+ 3
- 3
src/commands/diffWithRevisionFrom.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { basename, relative } from 'path';
import { TextDocumentShowOptions, TextEditor, Uri } from 'vscode'; import { TextDocumentShowOptions, TextEditor, Uri } from 'vscode';
import { GlyphChars, quickPickTitleMaxChars } from '../constants'; import { GlyphChars, quickPickTitleMaxChars } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
@ -8,6 +7,7 @@ import { GitReference, GitRevision } from '../git/models';
import { Messages } from '../messages'; import { Messages } from '../messages';
import { ReferencePicker, StashPicker } from '../quickpicks'; import { ReferencePicker, StashPicker } from '../quickpicks';
import { Strings } from '../system'; import { Strings } from '../system';
import { basename, normalizePath, relative } from '../system/path';
import { ActiveEditorCommand, command, Commands, executeCommand, getCommandUri } from './common'; import { ActiveEditorCommand, command, Commands, executeCommand, getCommandUri } from './common';
import { DiffWithCommandArgs } from './diffWith'; import { DiffWithCommandArgs } from './diffWith';
@ -42,7 +42,7 @@ export class DiffWithRevisionFromCommand extends ActiveEditorCommand {
let ref; let ref;
let sha; let sha;
if (args?.stash) { if (args?.stash) {
const fileName = Strings.normalizePath(relative(gitUri.repoPath, gitUri.fsPath));
const fileName = normalizePath(relative(gitUri.repoPath, gitUri.fsPath));
const title = `Open Changes with Stash${Strings.pad(GlyphChars.Dot, 2, 2)}`; const title = `Open Changes with Stash${Strings.pad(GlyphChars.Dot, 2, 2)}`;
const pick = await StashPicker.show( const pick = await StashPicker.show(
@ -83,7 +83,7 @@ export class DiffWithRevisionFromCommand extends ActiveEditorCommand {
// Check to see if this file has been renamed // Check to see if this file has been renamed
const files = await Container.instance.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filters: ['R', 'C'] }); const files = await Container.instance.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filters: ['R', 'C'] });
if (files != null) { if (files != null) {
const fileName = Strings.normalizePath(relative(gitUri.repoPath, gitUri.fsPath));
const fileName = normalizePath(relative(gitUri.repoPath, gitUri.fsPath));
const rename = files.find(s => s.fileName === fileName); const rename = files.find(s => s.fileName === fileName);
if (rename?.originalFileName != null) { if (rename?.originalFileName != null) {
renamedUri = GitUri.resolveToUri(rename.originalFileName, gitUri.repoPath); renamedUri = GitUri.resolveToUri(rename.originalFileName, gitUri.repoPath);

+ 2
- 2
src/commands/git/coauthors.ts View File

@ -2,7 +2,7 @@
import { commands } from 'vscode'; import { commands } from 'vscode';
import { Container } from '../../container'; import { Container } from '../../container';
import { GitContributor, Repository } from '../../git/models'; import { GitContributor, Repository } from '../../git/models';
import { Strings } from '../../system';
import { normalizePath } from '../../system/path';
import { ViewsWithRepositoryFolders } from '../../views/viewBase'; import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
PartialStepState, PartialStepState,
@ -104,7 +104,7 @@ export class CoAuthorsGitCommand extends QuickCommand {
if (scmRepositories.length) { if (scmRepositories.length) {
// Filter out any repo's that are not known to the built-in git // Filter out any repo's that are not known to the built-in git
context.repos = context.repos.filter(repo => context.repos = context.repos.filter(repo =>
scmRepositories.find(r => Strings.normalizePath(r.rootUri.fsPath) === repo.path),
scmRepositories.find(r => normalizePath(r.rootUri.fsPath) === repo.path),
); );
// Ensure that the active repo is known to the built-in git // Ensure that the active repo is known to the built-in git

+ 2
- 2
src/commands/openFileAtRevisionFrom.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { relative } from 'path';
import { TextDocumentShowOptions, TextEditor, Uri } from 'vscode'; import { TextDocumentShowOptions, TextEditor, Uri } from 'vscode';
import { FileAnnotationType } from '../configuration'; import { FileAnnotationType } from '../configuration';
import { GlyphChars, quickPickTitleMaxChars } from '../constants'; import { GlyphChars, quickPickTitleMaxChars } from '../constants';
@ -9,6 +8,7 @@ import { GitReference } from '../git/models';
import { Messages } from '../messages'; import { Messages } from '../messages';
import { ReferencePicker, StashPicker } from '../quickpicks'; import { ReferencePicker, StashPicker } from '../quickpicks';
import { Strings } from '../system'; import { Strings } from '../system';
import { normalizePath, relative } from '../system/path';
import { ActiveEditorCommand, command, Commands, getCommandUri } from './common'; import { ActiveEditorCommand, command, Commands, getCommandUri } from './common';
import { GitActions } from './gitCommands'; import { GitActions } from './gitCommands';
@ -44,7 +44,7 @@ export class OpenFileAtRevisionFromCommand extends ActiveEditorCommand {
if (args.reference == null) { if (args.reference == null) {
if (args?.stash) { if (args?.stash) {
const fileName = Strings.normalizePath(relative(gitUri.repoPath, gitUri.fsPath));
const fileName = normalizePath(relative(gitUri.repoPath, gitUri.fsPath));
const title = `Open Changes with Stash${Strings.pad(GlyphChars.Dot, 2, 2)}`; const title = `Open Changes with Stash${Strings.pad(GlyphChars.Dot, 2, 2)}`;
const pick = await StashPicker.show( const pick = await StashPicker.show(

+ 10
- 10
src/env/node/git/git.ts View File

@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
'use strict'; 'use strict';
import { dirname, isAbsolute, join as joinPaths } from 'path';
import { Uri, window, workspace } from 'vscode'; import { Uri, window, workspace } from 'vscode';
import { hrtime } from '@env/hrtime'; import { hrtime } from '@env/hrtime';
import { GlyphChars } from '../../../constants'; import { GlyphChars } from '../../../constants';
@ -9,7 +8,8 @@ import { GitCommandOptions, GitErrorHandling } from '../../../git/commandOptions
import { GitDiffFilter, GitRevision } from '../../../git/models'; import { GitDiffFilter, GitRevision } from '../../../git/models';
import { GitBranchParser, GitLogParser, GitReflogParser, GitStashParser, GitTagParser } from '../../../git/parsers'; import { GitBranchParser, GitLogParser, GitReflogParser, GitStashParser, GitTagParser } from '../../../git/parsers';
import { Logger } from '../../../logger'; import { Logger } from '../../../logger';
import { Paths, Strings, Versions } from '../../../system';
import { Strings, Versions } from '../../../system';
import { dirname, isAbsolute, isFolderGlob, joinPaths, normalizePath, splitPath } from '../../../system/path';
import { GitLocation } from './locator'; import { GitLocation } from './locator';
import { fsExists, run, RunError, RunOptions } from './shell'; import { fsExists, run, RunError, RunOptions } from './shell';
@ -231,7 +231,7 @@ export namespace Git {
ref?: string, ref?: string,
options: { args?: string[] | null; ignoreWhitespace?: boolean; startLine?: number; endLine?: number } = {}, options: { args?: string[] | null; ignoreWhitespace?: boolean; startLine?: number; endLine?: number } = {},
) { ) {
const [file, root] = Paths.splitPath(fileName, repoPath);
const [file, root] = splitPath(fileName, repoPath);
const params = ['blame', '--root', '--incremental']; const params = ['blame', '--root', '--incremental'];
@ -303,7 +303,7 @@ export namespace Git {
endLine?: number; endLine?: number;
} = {}, } = {},
) { ) {
const [file, root] = Paths.splitPath(fileName, repoPath);
const [file, root] = splitPath(fileName, repoPath);
const params = ['blame', '--root', '--incremental']; const params = ['blame', '--root', '--incremental'];
@ -401,7 +401,7 @@ export namespace Git {
params.push(ref, '--'); params.push(ref, '--');
if (fileName) { if (fileName) {
[fileName, repoPath] = Paths.splitPath(fileName, repoPath);
[fileName, repoPath] = splitPath(fileName, repoPath);
params.push(fileName); params.push(fileName);
} }
@ -804,7 +804,7 @@ export namespace Git {
endLine?: number; endLine?: number;
} = {}, } = {},
) { ) {
const [file, root] = Paths.splitPath(fileName, repoPath);
const [file, root] = splitPath(fileName, repoPath);
const params = [ const params = [
'log', 'log',
@ -852,7 +852,7 @@ export namespace Git {
if (format !== 'refs') { if (format !== 'refs') {
if (startLine == null) { if (startLine == null) {
// If this is the log of a folder, use `--name-status` to match non-file logs (for parsing) // If this is the log of a folder, use `--name-status` to match non-file logs (for parsing)
if (format === 'simple' || Paths.isFolderGlob(file)) {
if (format === 'simple' || isFolderGlob(file)) {
params.push('--name-status'); params.push('--name-status');
} else { } else {
params.push('--numstat', '--summary'); params.push('--numstat', '--summary');
@ -1250,7 +1250,7 @@ export namespace Git {
); );
// Make sure to normalize: https://github.com/git-for-windows/git/issues/2478 // Make sure to normalize: https://github.com/git-for-windows/git/issues/2478
// Keep trailing spaces which are part of the directory name // Keep trailing spaces which are part of the directory name
return data.length === 0 ? undefined : Strings.normalizePath(data.trimLeft().replace(/[\r|\n]+$/, ''));
return data.length === 0 ? undefined : normalizePath(data.trimLeft().replace(/[\r|\n]+$/, ''));
} catch (ex) { } catch (ex) {
const inDotGit = /this operation must be run in a work tree/.test(ex.stderr); const inDotGit = /this operation must be run in a work tree/.test(ex.stderr);
if (inDotGit || ex.code === 'ENOENT') { if (inDotGit || ex.code === 'ENOENT') {
@ -1298,7 +1298,7 @@ export namespace Git {
encoding?: 'binary' | 'ascii' | 'utf8' | 'utf16le' | 'ucs2' | 'base64' | 'latin1' | 'hex' | 'buffer'; encoding?: 'binary' | 'ascii' | 'utf8' | 'utf16le' | 'ucs2' | 'base64' | 'latin1' | 'hex' | 'buffer';
} = {}, } = {},
): Promise<TOut | undefined> { ): Promise<TOut | undefined> {
const [file, root] = Paths.splitPath(fileName, repoPath);
const [file, root] = splitPath(fileName, repoPath);
if (GitRevision.isUncommittedStaged(ref)) { if (GitRevision.isUncommittedStaged(ref)) {
ref = ':'; ref = ':';
@ -1482,7 +1482,7 @@ export namespace Git {
porcelainVersion: number = 1, porcelainVersion: number = 1,
{ similarityThreshold }: { similarityThreshold?: number | null } = {}, { similarityThreshold }: { similarityThreshold?: number | null } = {},
): Promise<string> { ): Promise<string> {
const [file, root] = Paths.splitPath(fileName, repoPath);
const [file, root] = splitPath(fileName, repoPath);
const params = ['status', porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain']; const params = ['status', porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain'];
if (await Git.isAtLeastVersion('2.18')) { if (await Git.isAtLeastVersion('2.18')) {

+ 26
- 29
src/env/node/git/localGitProvider.ts View File

@ -91,7 +91,8 @@ import { RemoteProvider, RichRemoteProvider } from '../../../git/remotes/provide
import { SearchPattern } from '../../../git/search'; import { SearchPattern } from '../../../git/search';
import { LogCorrelationContext, Logger } from '../../../logger'; import { LogCorrelationContext, Logger } from '../../../logger';
import { Messages } from '../../../messages'; import { Messages } from '../../../messages';
import { Arrays, debug, Functions, gate, Iterables, log, Paths, Promises, Strings, Versions } from '../../../system';
import { Arrays, debug, Functions, gate, Iterables, log, Promises, Strings, Versions } from '../../../system';
import { isFolderGlob, normalizePath, splitPath } from '../../../system/path';
import { PromiseOrValue } from '../../../system/promise'; import { PromiseOrValue } from '../../../system/promise';
import { import {
CachedBlame, CachedBlame,
@ -225,13 +226,13 @@ export class LocalGitProvider implements GitProvider, Disposable {
container.context.subscriptions.push( container.context.subscriptions.push(
gitApi.onDidCloseRepository(e => { gitApi.onDidCloseRepository(e => {
const repository = container.git.getCachedRepository(Strings.normalizePath(e.rootUri.fsPath));
const repository = container.git.getCachedRepository(normalizePath(e.rootUri.fsPath));
if (repository != null) { if (repository != null) {
repository.closed = true; repository.closed = true;
} }
}), }),
gitApi.onDidOpenRepository(e => { gitApi.onDidOpenRepository(e => {
const repository = container.git.getCachedRepository(Strings.normalizePath(e.rootUri.fsPath));
const repository = container.git.getCachedRepository(normalizePath(e.rootUri.fsPath));
if (repository != null) { if (repository != null) {
repository.closed = false; repository.closed = false;
} }
@ -395,10 +396,10 @@ export class LocalGitProvider implements GitProvider, Disposable {
for (let p of repoPaths) { for (let p of repoPaths) {
p = dirname(p); p = dirname(p);
// If we are the same as the root, skip it // If we are the same as the root, skip it
if (Strings.normalizePath(p) === rootPath) continue;
if (normalizePath(p) === rootPath) continue;
Logger.log(cc, `searching in '${p}'...`); Logger.log(cc, `searching in '${p}'...`);
Logger.debug(cc, `normalizedRepoPath=${Strings.normalizePath(p)}, rootPath=${rootPath}`);
Logger.debug(cc, `normalizedRepoPath=${normalizePath(p)}, rootPath=${rootPath}`);
const rp = await this.getRepoPath(p, true); const rp = await this.getRepoPath(p, true);
if (rp == null) continue; if (rp == null) continue;
@ -573,7 +574,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
@log<LocalGitProvider['excludeIgnoredUris']>({ args: { 1: uris => uris.length } }) @log<LocalGitProvider['excludeIgnoredUris']>({ args: { 1: uris => uris.length } })
async excludeIgnoredUris(repoPath: string, uris: Uri[]): Promise<Uri[]> { async excludeIgnoredUris(repoPath: string, uris: Uri[]): Promise<Uri[]> {
const paths = new Map<string, Uri>(uris.map(u => [Strings.normalizePath(u.fsPath), u]));
const paths = new Map<string, Uri>(uris.map(u => [normalizePath(u.fsPath), u]));
const data = await Git.check_ignore(repoPath, ...paths.keys()); const data = await Git.check_ignore(repoPath, ...paths.keys());
if (data == null) return uris; if (data == null) return uris;
@ -670,7 +671,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
return emptyPromise as Promise<GitBlame>; return emptyPromise as Promise<GitBlame>;
} }
const [file, root] = Paths.splitPath(uri.fsPath, uri.repoPath, false);
const [file, root] = splitPath(uri.fsPath, uri.repoPath, false);
try { try {
const data = await Git.blame(root, file, uri.sha, { const data = await Git.blame(root, file, uri.sha, {
@ -749,7 +750,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
return emptyPromise as Promise<GitBlame>; return emptyPromise as Promise<GitBlame>;
} }
const [file, root] = Paths.splitPath(uri.fsPath, uri.repoPath, false);
const [file, root] = splitPath(uri.fsPath, uri.repoPath, false);
try { try {
const data = await Git.blame__contents(root, file, contents, { const data = await Git.blame__contents(root, file, contents, {
@ -1420,7 +1421,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
key: string, key: string,
cc: LogCorrelationContext | undefined, cc: LogCorrelationContext | undefined,
): Promise<GitDiff | undefined> { ): Promise<GitDiff | undefined> {
const [file, root] = Paths.splitPath(fileName, repoPath, false);
const [file, root] = splitPath(fileName, repoPath, false);
try { try {
const data = await Git.diff(root, file, ref1, ref2, { const data = await Git.diff(root, file, ref1, ref2, {
@ -1509,7 +1510,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
key: string, key: string,
cc: LogCorrelationContext | undefined, cc: LogCorrelationContext | undefined,
): Promise<GitDiff | undefined> { ): Promise<GitDiff | undefined> {
const [file, root] = Paths.splitPath(fileName, repoPath, false);
const [file, root] = splitPath(fileName, repoPath, false);
try { try {
const data = await Git.diff__contents(root, file, ref, contents, { const data = await Git.diff__contents(root, file, ref, contents, {
@ -1931,7 +1932,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
skip?: number; skip?: number;
}, },
): Promise<GitLog | undefined> { ): Promise<GitLog | undefined> {
if (repoPath != null && repoPath === Strings.normalizePath(fileName)) {
if (repoPath != null && repoPath === normalizePath(fileName)) {
throw new Error(`File name cannot match the repository path; fileName=${fileName}`); throw new Error(`File name cannot match the repository path; fileName=${fileName}`);
} }
@ -2090,7 +2091,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
return emptyPromise as Promise<GitLog>; return emptyPromise as Promise<GitLog>;
} }
const [file, root] = Paths.splitPath(fileName, repoPath, false);
const [file, root] = splitPath(fileName, repoPath, false);
try { try {
if (range != null && range.start.line > range.end.line) { if (range != null && range.start.line > range.end.line) {
@ -2107,7 +2108,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
const log = GitLogParser.parse( const log = GitLogParser.parse(
data, data,
// If this is the log of a folder, parse it as a normal log rather than a file log // If this is the log of a folder, parse it as a normal log rather than a file log
Paths.isFolderGlob(file) ? GitCommitType.Log : GitCommitType.LogFile,
isFolderGlob(file) ? GitCommitType.Log : GitCommitType.LogFile,
root, root,
file, file,
ref, ref,
@ -3056,7 +3057,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
), ),
); );
if (networkPath != null) { if (networkPath != null) {
repoPath = Strings.normalizePath(
repoPath = normalizePath(
repoUri.fsPath.replace( repoUri.fsPath.replace(
networkPath, networkPath,
`${letter.toLowerCase()}:${networkPath.endsWith('\\') ? '\\' : ''}`, `${letter.toLowerCase()}:${networkPath.endsWith('\\') ? '\\' : ''}`,
@ -3067,7 +3068,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
} catch {} } catch {}
} }
repoPath = Strings.normalizePath(pathUri.fsPath);
repoPath = normalizePath(pathUri.fsPath);
} }
return repoPath; return repoPath;
@ -3089,7 +3090,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
return; return;
} }
const linkPath = Strings.normalizePath(resolvedPath, { stripTrailingSlash: true });
const linkPath = normalizePath(resolvedPath);
repoPath = repoPath!.replace(linkPath, path); repoPath = repoPath!.replace(linkPath, path);
Logger.debug( Logger.debug(
cc, cc,
@ -3434,16 +3435,14 @@ export class LocalGitProvider implements GitProvider, Disposable {
if (typeof filePathOrUri === 'string') { if (typeof filePathOrUri === 'string') {
if (ref === GitRevision.deletedOrMissing) return false; if (ref === GitRevision.deletedOrMissing) return false;
cacheKey = ref ? `${ref}:${Strings.normalizePath(filePathOrUri)}` : Strings.normalizePath(filePathOrUri);
[relativeFilePath, repoPath] = Paths.splitPath(filePathOrUri, repoPath);
cacheKey = ref ? `${ref}:${normalizePath(filePathOrUri)}` : normalizePath(filePathOrUri);
[relativeFilePath, repoPath] = splitPath(filePathOrUri, repoPath);
} else { } else {
if (!this.isTrackable(filePathOrUri)) return false; if (!this.isTrackable(filePathOrUri)) return false;
// Always use the ref of the GitUri // Always use the ref of the GitUri
ref = filePathOrUri.sha; ref = filePathOrUri.sha;
cacheKey = ref
? `${ref}:${Strings.normalizePath(filePathOrUri.fsPath)}`
: Strings.normalizePath(filePathOrUri.fsPath);
cacheKey = ref ? `${ref}:${normalizePath(filePathOrUri.fsPath)}` : normalizePath(filePathOrUri.fsPath);
relativeFilePath = filePathOrUri.fsPath; relativeFilePath = filePathOrUri.fsPath;
repoPath = filePathOrUri.repoPath; repoPath = filePathOrUri.repoPath;
} }
@ -3592,9 +3591,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
} }
const fileName = const fileName =
typeof fileNameOrUri === 'string'
? fileNameOrUri
: Strings.normalizePath(relative(repoPath, fileNameOrUri.fsPath));
typeof fileNameOrUri === 'string' ? fileNameOrUri : normalizePath(relative(repoPath, fileNameOrUri.fsPath));
const blob = await Git.rev_parse__verify(repoPath, ref, fileName); const blob = await Git.rev_parse__verify(repoPath, ref, fileName);
if (blob == null) return GitRevision.deletedOrMissing; if (blob == null) return GitRevision.deletedOrMissing;
@ -3632,7 +3629,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
async stageFile(repoPath: string, fileNameOrUri: string | Uri): Promise<void> { async stageFile(repoPath: string, fileNameOrUri: string | Uri): Promise<void> {
await Git.add( await Git.add(
repoPath, repoPath,
typeof fileNameOrUri === 'string' ? fileNameOrUri : Paths.splitPath(fileNameOrUri.fsPath, repoPath)[0],
typeof fileNameOrUri === 'string' ? fileNameOrUri : splitPath(fileNameOrUri.fsPath, repoPath)[0],
); );
} }
@ -3642,7 +3639,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
async stageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> { async stageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> {
await Git.add( await Git.add(
repoPath, repoPath,
typeof directoryOrUri === 'string' ? directoryOrUri : Paths.splitPath(directoryOrUri.fsPath, repoPath)[0],
typeof directoryOrUri === 'string' ? directoryOrUri : splitPath(directoryOrUri.fsPath, repoPath)[0],
); );
} }
@ -3652,7 +3649,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
async unStageFile(repoPath: string, fileNameOrUri: string | Uri): Promise<void> { async unStageFile(repoPath: string, fileNameOrUri: string | Uri): Promise<void> {
await Git.reset( await Git.reset(
repoPath, repoPath,
typeof fileNameOrUri === 'string' ? fileNameOrUri : Paths.splitPath(fileNameOrUri.fsPath, repoPath)[0],
typeof fileNameOrUri === 'string' ? fileNameOrUri : splitPath(fileNameOrUri.fsPath, repoPath)[0],
); );
} }
@ -3662,7 +3659,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
async unStageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> { async unStageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> {
await Git.reset( await Git.reset(
repoPath, repoPath,
typeof directoryOrUri === 'string' ? directoryOrUri : Paths.splitPath(directoryOrUri.fsPath, repoPath)[0],
typeof directoryOrUri === 'string' ? directoryOrUri : splitPath(directoryOrUri.fsPath, repoPath)[0],
); );
} }
@ -3723,7 +3720,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
' Please retry by stashing everything or install a more recent version of Git and try again.', ' Please retry by stashing everything or install a more recent version of Git and try again.',
); );
const pathspecs = uris.map(u => `./${Paths.splitPath(u.fsPath, repoPath)[0]}`);
const pathspecs = uris.map(u => `./${splitPath(u.fsPath, repoPath)[0]}`);
const stdinVersion = '2.30.0'; const stdinVersion = '2.30.0';
const stdin = await Git.isAtLeastVersion(stdinVersion); const stdin = await Git.isAtLeastVersion(stdinVersion);

+ 1
- 1
src/git/formatters/statusFormatter.ts View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
import { basename } from 'path';
import { GlyphChars } from '../../constants'; import { GlyphChars } from '../../constants';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { basename } from '../../system/path';
import { GitFile, GitFileWithCommit } from '../models/file'; import { GitFile, GitFileWithCommit } from '../models/file';
import { FormatOptions, Formatter } from './formatter'; import { FormatOptions, Formatter } from './formatter';

+ 3
- 3
src/git/fsProvider.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { relative } from 'path';
import { import {
Disposable, Disposable,
Event, Event,
@ -15,7 +14,8 @@ import {
import { DocumentSchemes } from '../constants'; import { DocumentSchemes } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
import { GitUri } from '../git/gitUri'; import { GitUri } from '../git/gitUri';
import { debug, Iterables, Strings, TernarySearchTree } from '../system';
import { debug, Iterables, TernarySearchTree } from '../system';
import { normalizePath, relative } from '../system/path';
import { GitRevision, GitTree } from './models'; import { GitRevision, GitTree } from './models';
const emptyArray = new Uint8Array(0); const emptyArray = new Uint8Array(0);
@ -70,7 +70,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable {
const items = [ const items = [
...Iterables.map<GitTree, [string, FileType]>(tree, t => [ ...Iterables.map<GitTree, [string, FileType]>(tree, t => [
path != null && path.length !== 0 ? Strings.normalizePath(relative(path, t.path)) : t.path,
path != null && path.length !== 0 ? normalizePath(relative(path, t.path)) : t.path,
typeToFileType(t.type), typeToFileType(t.type),
]), ]),
]; ];

+ 6
- 5
src/git/gitProviderService.ts View File

@ -28,7 +28,8 @@ import {
import type { Container } from '../container'; import type { Container } from '../container';
import { ProviderNotFoundError } from '../errors'; import { ProviderNotFoundError } from '../errors';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { Arrays, debug, gate, Iterables, log, Paths, Promises, Strings } from '../system';
import { Arrays, debug, gate, Iterables, log, Promises } from '../system';
import { isDescendent, normalizePath } from '../system/path';
import { PromiseOrValue } from '../system/promise'; import { PromiseOrValue } from '../system/promise';
import { vslsUriPrefixRegex } from '../vsls/vsls'; import { vslsUriPrefixRegex } from '../vsls/vsls';
import { GitProvider, GitProviderDescriptor, GitProviderId, PagedResult, ScmRepository } from './gitProvider'; import { GitProvider, GitProviderDescriptor, GitProviderId, PagedResult, ScmRepository } from './gitProvider';
@ -1473,14 +1474,14 @@ export class GitProviderService implements Disposable {
let filePath: string; let filePath: string;
if (typeof repoPathOrUri === 'string') { if (typeof repoPathOrUri === 'string') {
filePath = Strings.normalizePath(repoPathOrUri);
filePath = normalizePath(repoPathOrUri);
} else { } else {
if (GitUri.is(repoPathOrUri) && repoPathOrUri.repoPath) { if (GitUri.is(repoPathOrUri) && repoPathOrUri.repoPath) {
repo = this.getCachedRepository(repoPathOrUri.repoPath); repo = this.getCachedRepository(repoPathOrUri.repoPath);
if (repo != null) return repo; if (repo != null) return repo;
} }
filePath = Strings.normalizePath(repoPathOrUri.fsPath);
filePath = normalizePath(repoPathOrUri.fsPath);
isVslsScheme = repoPathOrUri.scheme === DocumentSchemes.Vsls; isVslsScheme = repoPathOrUri.scheme === DocumentSchemes.Vsls;
} }
@ -1556,7 +1557,7 @@ export class GitProviderService implements Disposable {
function findBySubPath(repositories: Map<string, Repository>, path: string) { function findBySubPath(repositories: Map<string, Repository>, path: string) {
const repos = [...repositories.values()].sort((a, b) => a.path.length - b.path.length); const repos = [...repositories.values()].sort((a, b) => a.path.length - b.path.length);
for (const repo of repos) { for (const repo of repos) {
if (Paths.isDescendent(path, repo.path)) return repo;
if (isDescendent(path, repo.path)) return repo;
} }
return undefined; return undefined;
@ -1566,7 +1567,7 @@ export class GitProviderService implements Disposable {
// If we can't find the repo and we are a guest, check if we are a "root" workspace // If we can't find the repo and we are a guest, check if we are a "root" workspace
if (repo == null && isVslsScheme !== false && this.container.vsls.isMaybeGuest) { if (repo == null && isVslsScheme !== false && this.container.vsls.isMaybeGuest) {
if (!vslsUriPrefixRegex.test(path)) { if (!vslsUriPrefixRegex.test(path)) {
path = Strings.normalizePath(path);
path = normalizePath(path);
const vslsPath = `/~0${path.startsWith(slash) ? path : `/${path}`}`; const vslsPath = `/~0${path.startsWith(slash) ? path : `/${path}`}`;
repo = findBySubPath(this._repositories, vslsPath); repo = findBySubPath(this._repositories, vslsPath);
} }

+ 16
- 11
src/git/gitUri.ts View File

@ -1,11 +1,12 @@
'use strict'; 'use strict';
import { basename, dirname, isAbsolute, join as joinPaths, relative } from 'path';
import { Uri } from 'vscode'; import { Uri } from 'vscode';
import { UriComparer } from '../comparers'; import { UriComparer } from '../comparers';
import { DocumentSchemes } from '../constants'; import { DocumentSchemes } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { debug, memoize, Strings } from '../system'; import { debug, memoize, Strings } from '../system';
import { basename, dirname, isAbsolute, joinPaths, normalizePath, relative } from '../system/path';
import { CharCode } from '../system/string';
import { GitCommit, GitFile, GitRevision } from './models'; import { GitCommit, GitFile, GitRevision } from './models';
const emptyStr = ''; const emptyStr = '';
@ -165,7 +166,7 @@ export class GitUri extends (Uri as any as UriEx) {
@memoize() @memoize()
get relativePath() { get relativePath() {
return Strings.normalizePath(this.relativeFsPath);
return normalizePath(this.relativeFsPath);
} }
@memoize() @memoize()
@ -308,7 +309,7 @@ export class GitUri extends (Uri as any as UriEx) {
remoteName: string; remoteName: string;
} = JSON.parse(uri.query); } = JSON.parse(uri.query);
let repoPath = Strings.normalizePath(uri.fsPath);
let repoPath = normalizePath(uri.fsPath);
if (repoPath.endsWith(data.fileName)) { if (repoPath.endsWith(data.fileName)) {
repoPath = repoPath.substr(0, repoPath.length - data.fileName.length - 1); repoPath = repoPath.substr(0, repoPath.length - data.fileName.length - 1);
} else { } else {
@ -329,7 +330,7 @@ export class GitUri extends (Uri as any as UriEx) {
static getDirectory(fileName: string, relativeTo?: string): string { static getDirectory(fileName: string, relativeTo?: string): string {
let directory: string | undefined = dirname(fileName); let directory: string | undefined = dirname(fileName);
directory = relativeTo != null ? GitUri.relativeTo(directory, relativeTo) : Strings.normalizePath(directory);
directory = relativeTo != null ? GitUri.relativeTo(directory, relativeTo) : normalizePath(directory);
return directory == null || directory.length === 0 || directory === '.' ? emptyStr : directory; return directory == null || directory.length === 0 || directory === '.' ? emptyStr : directory;
} }
@ -413,7 +414,7 @@ export class GitUri extends (Uri as any as UriEx) {
relativeTo == null || relativeTo.length === 0 || !isAbsolute(fileName) relativeTo == null || relativeTo.length === 0 || !isAbsolute(fileName)
? fileName ? fileName
: relative(relativeTo, fileName); : relative(relativeTo, fileName);
return Strings.normalizePath(relativePath);
return normalizePath(relativePath);
} }
static git(fileName: string, repoPath?: string) { static git(fileName: string, repoPath?: string) {
@ -431,15 +432,15 @@ export class GitUri extends (Uri as any as UriEx) {
} }
static resolve(fileName: string, repoPath?: string) { static resolve(fileName: string, repoPath?: string) {
const normalizedFileName = Strings.normalizePath(fileName);
const normalizedFileName = normalizePath(fileName);
if (repoPath === undefined) return normalizedFileName; if (repoPath === undefined) return normalizedFileName;
const normalizedRepoPath = Strings.normalizePath(repoPath);
const normalizedRepoPath = normalizePath(repoPath);
if (normalizedFileName == null || normalizedFileName.length === 0) return normalizedRepoPath; if (normalizedFileName == null || normalizedFileName.length === 0) return normalizedRepoPath;
if (normalizedFileName.startsWith(normalizedRepoPath)) return normalizedFileName; if (normalizedFileName.startsWith(normalizedRepoPath)) return normalizedFileName;
return Strings.normalizePath(joinPaths(normalizedRepoPath, normalizedFileName));
return normalizePath(joinPaths(normalizedRepoPath, normalizedFileName));
} }
static resolveToUri(fileName: string, repoPath?: string) { static resolveToUri(fileName: string, repoPath?: string) {
@ -450,7 +451,7 @@ export class GitUri extends (Uri as any as UriEx) {
static toKey(uri: Uri): string; static toKey(uri: Uri): string;
static toKey(fileNameOrUri: string | Uri): string; static toKey(fileNameOrUri: string | Uri): string;
static toKey(fileNameOrUri: string | Uri): string { static toKey(fileNameOrUri: string | Uri): string {
return Strings.normalizePath(typeof fileNameOrUri === 'string' ? fileNameOrUri : fileNameOrUri.fsPath);
return normalizePath(typeof fileNameOrUri === 'string' ? fileNameOrUri : fileNameOrUri.fsPath);
// return typeof fileNameOrUri === 'string' // return typeof fileNameOrUri === 'string'
// ? GitUri.file(fileNameOrUri).toString(true) // ? GitUri.file(fileNameOrUri).toString(true)
@ -493,11 +494,15 @@ export class GitUri extends (Uri as any as UriEx) {
return GitRevision.isUncommittedStaged(ref) ? GitUri.git(fileName, repoPath) : Uri.file(fileName); return GitRevision.isUncommittedStaged(ref) ? GitUri.git(fileName, repoPath) : Uri.file(fileName);
} }
const filePath = Strings.normalizePath(fileName, { addLeadingSlash: true });
let filePath = normalizePath(fileName);
if (filePath.charCodeAt(0) !== CharCode.Slash) {
filePath = `/${filePath}`;
}
const data: UriRevisionData = { const data: UriRevisionData = {
path: filePath, path: filePath,
ref: ref, ref: ref,
repoPath: Strings.normalizePath(repoPath!),
repoPath: normalizePath(repoPath!),
}; };
const uri = Uri.parse( const uri = Uri.parse(

+ 1
- 1
src/git/models/repository.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { basename, join as joinPaths, relative } from 'path';
import { import {
commands, commands,
ConfigurationChangeEvent, ConfigurationChangeEvent,
@ -21,6 +20,7 @@ import { Container } from '../../container';
import { Logger, LogLevel } from '../../logger'; import { Logger, LogLevel } from '../../logger';
import { Messages } from '../../messages'; import { Messages } from '../../messages';
import { Arrays, Dates, debug, Functions, gate, Iterables, log, logName } from '../../system'; import { Arrays, Dates, debug, Functions, gate, Iterables, log, logName } from '../../system';
import { basename, joinPaths, relative } from '../../system/path';
import { runGitCommandInTerminal } from '../../terminal'; import { runGitCommandInTerminal } from '../../terminal';
import { GitProviderDescriptor } from '../gitProvider'; import { GitProviderDescriptor } from '../gitProvider';
import { GitUri } from '../gitUri'; import { GitUri } from '../gitUri';

+ 3
- 3
src/git/parsers/blameParser.ts View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
import { relative } from 'path';
import { debug, Strings } from '../../system'; import { debug, Strings } from '../../system';
import { normalizePath, relative } from '../../system/path';
import { GitAuthor, GitBlame, GitBlameCommit, GitCommitLine, GitRevision, GitUser } from '../models'; import { GitAuthor, GitBlame, GitBlameCommit, GitCommitLine, GitRevision, GitUser } from '../models';
const emptyStr = ''; const emptyStr = '';
@ -125,13 +125,13 @@ export class GitBlameParser {
if (first && repoPath === undefined) { if (first && repoPath === undefined) {
// Try to get the repoPath from the most recent commit // Try to get the repoPath from the most recent commit
repoPath = Strings.normalizePath(
repoPath = normalizePath(
fileName.replace( fileName.replace(
fileName.startsWith(slash) ? `/${entry.fileName}` : entry.fileName, fileName.startsWith(slash) ? `/${entry.fileName}` : entry.fileName,
emptyStr, emptyStr,
), ),
); );
relativeFileName = Strings.normalizePath(relative(repoPath, fileName));
relativeFileName = normalizePath(relative(repoPath, fileName));
} else { } else {
relativeFileName = entry.fileName; relativeFileName = entry.fileName;
} }

+ 4
- 4
src/git/parsers/logParser.ts View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
import { relative } from 'path';
import { Range } from 'vscode'; import { Range } from 'vscode';
import { Arrays, debug, Strings } from '../../system'; import { Arrays, debug, Strings } from '../../system';
import { normalizePath, relative } from '../../system/path';
import { import {
GitAuthor, GitAuthor,
GitCommitType, GitCommitType,
@ -112,7 +112,7 @@ export class GitLogParser {
if (next.done) return undefined; if (next.done) return undefined;
if (repoPath !== undefined) { if (repoPath !== undefined) {
repoPath = Strings.normalizePath(repoPath);
repoPath = normalizePath(repoPath);
} }
const authors = new Map<string, GitAuthor>(); const authors = new Map<string, GitAuthor>();
@ -340,13 +340,13 @@ export class GitLogParser {
if (first && repoPath === undefined && type === GitCommitType.LogFile && fileName !== undefined) { if (first && repoPath === undefined && type === GitCommitType.LogFile && fileName !== undefined) {
// Try to get the repoPath from the most recent commit // Try to get the repoPath from the most recent commit
repoPath = Strings.normalizePath(
repoPath = normalizePath(
fileName.replace( fileName.replace(
fileName.startsWith(slash) ? `/${entry.fileName}` : entry.fileName!, fileName.startsWith(slash) ? `/${entry.fileName}` : entry.fileName!,
emptyStr, emptyStr,
), ),
); );
relativeFileName = Strings.normalizePath(relative(repoPath, fileName));
relativeFileName = normalizePath(relative(repoPath, fileName));
} else { } else {
relativeFileName = entry.fileName!; relativeFileName = entry.fileName!;
} }

+ 2
- 1
src/git/parsers/stashParser.ts View File

@ -1,5 +1,6 @@
'use strict'; 'use strict';
import { Arrays, debug, Strings } from '../../system'; import { Arrays, debug, Strings } from '../../system';
import { normalizePath } from '../../system/path';
import { GitCommitType, GitFile, GitFileIndexStatus, GitStash, GitStashCommit } from '../models'; import { GitCommitType, GitFile, GitFileIndexStatus, GitStash, GitStashCommit } from '../models';
import { fileStatusRegex } from './logParser'; import { fileStatusRegex } from './logParser';
// import { Logger } from './logger'; // import { Logger } from './logger';
@ -46,7 +47,7 @@ export class GitStashParser {
if (next.done) return undefined; if (next.done) return undefined;
if (repoPath !== undefined) { if (repoPath !== undefined) {
repoPath = Strings.normalizePath(repoPath);
repoPath = normalizePath(repoPath);
} }
const commits = new Map<string, GitStashCommit>(); const commits = new Map<string, GitStashCommit>();

+ 4
- 10
src/git/parsers/statusParser.ts View File

@ -1,5 +1,6 @@
'use strict'; 'use strict';
import { debug, Strings } from '../../system';
import { debug } from '../../system';
import { normalizePath } from '../../system/path';
import { GitStatus, GitStatusFile } from '../models'; import { GitStatus, GitStatusFile } from '../models';
const emptyStr = ''; const emptyStr = '';
@ -58,7 +59,7 @@ export class GitStatusParser {
} }
} }
return new GitStatus(Strings.normalizePath(repoPath), branch ?? emptyStr, emptyStr, files, state, upstream);
return new GitStatus(normalizePath(repoPath), branch ?? emptyStr, emptyStr, files, state, upstream);
} }
@debug({ args: false, singleLine: true }) @debug({ args: false, singleLine: true })
@ -115,14 +116,7 @@ export class GitStatusParser {
} }
} }
return new GitStatus(
Strings.normalizePath(repoPath),
branch ?? emptyStr,
sha ?? emptyStr,
files,
state,
upstream,
);
return new GitStatus(normalizePath(repoPath), branch ?? emptyStr, sha ?? emptyStr, files, state, upstream);
} }
static parseStatusFile( static parseStatusFile(

+ 1
- 1
src/quickpicks/commitQuickPickItems.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { basename } from 'path';
import { QuickPickItem, window } from 'vscode'; import { QuickPickItem, window } from 'vscode';
import { Commands, GitActions, OpenChangedFilesCommandArgs } from '../commands'; import { Commands, GitActions, OpenChangedFilesCommandArgs } from '../commands';
import { GlyphChars } from '../constants'; import { GlyphChars } from '../constants';
@ -8,6 +7,7 @@ import { CommitFormatter } from '../git/formatters';
import { GitFile, GitLogCommit, GitStatusFile } from '../git/models'; import { GitFile, GitLogCommit, GitStatusFile } from '../git/models';
import { Keys } from '../keyboard'; import { Keys } from '../keyboard';
import { Strings } from '../system'; import { Strings } from '../system';
import { basename } from '../system/path';
import { CommandQuickPickItem } from './quickPicksItems'; import { CommandQuickPickItem } from './quickPicksItems';
export class CommitFilesQuickPickItem extends CommandQuickPickItem { export class CommitFilesQuickPickItem extends CommandQuickPickItem {

+ 0
- 1
src/system.ts View File

@ -29,7 +29,6 @@ export * as Encoding from './system/encoding';
export * as Functions from './system/function'; export * as Functions from './system/function';
export * as Iterables from './system/iterable'; export * as Iterables from './system/iterable';
export * as Objects from './system/object'; export * as Objects from './system/object';
export * as Paths from './system/path';
export * as Promises from './system/promise'; export * as Promises from './system/promise';
export * from './system/searchTree'; export * from './system/searchTree';
export * from './system/stopwatch'; export * from './system/stopwatch';

+ 32
- 10
src/system/path.ts View File

@ -1,17 +1,20 @@
'use strict'; 'use strict';
import { basename, dirname } from 'path'; import { basename, dirname } from 'path';
import { Uri } from 'vscode'; import { Uri } from 'vscode';
import { Strings } from '../system';
import { normalizePath } from './string';
import { isWindows } from '@env/platform';
import { CharCode } from './string';
const slash = '/';
export { basename, dirname, extname, isAbsolute, join as joinPaths, relative } from 'path';
const driveLetterNormalizeRegex = /(?<=^\/?)([A-Z])(?=:\/)/;
const pathNormalizeRegex = /\\/g;
export function isChild(uri: Uri, baseUri: Uri): boolean; export function isChild(uri: Uri, baseUri: Uri): boolean;
export function isChild(uri: Uri, basePath: string): boolean; export function isChild(uri: Uri, basePath: string): boolean;
export function isChild(path: string, basePath: string): boolean; export function isChild(path: string, basePath: string): boolean;
export function isChild(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean { export function isChild(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean {
if (typeof baseUriOrPath === 'string') { if (typeof baseUriOrPath === 'string') {
if (!baseUriOrPath.startsWith('/')) {
if (baseUriOrPath.charCodeAt(0) !== CharCode.Slash) {
baseUriOrPath = `/${baseUriOrPath}`; baseUriOrPath = `/${baseUriOrPath}`;
} }
@ -37,15 +40,15 @@ export function isDescendent(path: string, basePath: string): boolean;
export function isDescendent(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean; export function isDescendent(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean;
export function isDescendent(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean { export function isDescendent(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean {
if (typeof baseUriOrPath === 'string') { if (typeof baseUriOrPath === 'string') {
baseUriOrPath = Strings.normalizePath(baseUriOrPath);
if (!baseUriOrPath.startsWith('/')) {
baseUriOrPath = normalizePath(baseUriOrPath);
if (baseUriOrPath.charCodeAt(0) !== CharCode.Slash) {
baseUriOrPath = `/${baseUriOrPath}`; baseUriOrPath = `/${baseUriOrPath}`;
} }
} }
if (typeof uriOrPath === 'string') { if (typeof uriOrPath === 'string') {
uriOrPath = Strings.normalizePath(uriOrPath);
if (!uriOrPath.startsWith('/')) {
uriOrPath = normalizePath(uriOrPath);
if (uriOrPath.charCodeAt(0) !== CharCode.Slash) {
uriOrPath = `/${uriOrPath}`; uriOrPath = `/${uriOrPath}`;
} }
} }
@ -74,16 +77,35 @@ export function isDescendent(uriOrPath: Uri | string, baseUriOrPath: Uri | strin
); );
} }
export function isFolderGlob(path: string) {
export function isFolderGlob(path: string): boolean {
return basename(path) === '*'; return basename(path) === '*';
} }
export function normalizePath(fileName: string): string {
if (fileName == null || fileName.length === 0) return fileName;
let normalized = fileName.replace(pathNormalizeRegex, '/');
if (normalized.charCodeAt(normalized.length - 1) === CharCode.Slash) {
normalized = normalized.slice(0, -1);
}
if (isWindows) {
// Ensure that drive casing is normalized (lower case)
normalized = normalized.replace(driveLetterNormalizeRegex, drive => drive.toLowerCase());
}
return normalized;
}
export function splitPath(filePath: string, repoPath: string | undefined, extract: boolean = true): [string, string] { export function splitPath(filePath: string, repoPath: string | undefined, extract: boolean = true): [string, string] {
if (repoPath) { if (repoPath) {
filePath = normalizePath(filePath); filePath = normalizePath(filePath);
repoPath = normalizePath(repoPath); repoPath = normalizePath(repoPath);
const normalizedRepoPath = (repoPath.endsWith(slash) ? repoPath : `${repoPath}/`).toLowerCase();
const normalizedRepoPath = (
repoPath.charCodeAt(repoPath.length - 1) === CharCode.Slash ? repoPath : `${repoPath}/`
).toLowerCase();
if (filePath.toLowerCase().startsWith(normalizedRepoPath)) { if (filePath.toLowerCase().startsWith(normalizedRepoPath)) {
filePath = filePath.substring(normalizedRepoPath.length); filePath = filePath.substring(normalizedRepoPath.length);
} }

+ 0
- 25
src/system/string.ts View File

@ -1,7 +1,6 @@
'use strict'; 'use strict';
import ansiRegex from 'ansi-regex'; import ansiRegex from 'ansi-regex';
import { md5 as _md5 } from '@env/crypto'; import { md5 as _md5 } from '@env/crypto';
import { isWindows } from '@env/platform';
export { fromBase64, base64 } from '@env/base64'; export { fromBase64, base64 } from '@env/base64';
@ -159,9 +158,6 @@ export function getSuperscript(num: number) {
return superscripts[num - 1] ?? ''; return superscripts[num - 1] ?? '';
} }
const driveLetterNormalizeRegex = /(?<=^\/?)([A-Z])(?=:\/)/;
const pathNormalizeRegex = /\\/g;
const pathStripTrailingSlashRegex = /\/$/g;
const tokenRegex = /\$\{('.*?[^\\]'|\W*)?([^|]*?)(?:\|(\d+)(-|\?)?)?('.*?[^\\]'|\W*)?\}/g; const tokenRegex = /\$\{('.*?[^\\]'|\W*)?([^|]*?)(?:\|(\d+)(-|\?)?)?('.*?[^\\]'|\W*)?\}/g;
const tokenSanitizeRegex = /\$\{(?:'.*?[^\\]'|\W*)?(\w*?)(?:'.*?[^\\]'|[\W\d]*)\}/g; const tokenSanitizeRegex = /\$\{(?:'.*?[^\\]'|\W*)?(\w*?)(?:'.*?[^\\]'|[\W\d]*)\}/g;
const tokenGroupCharacter = "'"; const tokenGroupCharacter = "'";
@ -285,27 +281,6 @@ export function md5(s: string, encoding: 'base64' | 'hex' = 'base64'): string {
return _md5(s, encoding); return _md5(s, encoding);
} }
export function normalizePath(fileName: string, options?: { addLeadingSlash?: boolean; stripTrailingSlash?: boolean }) {
if (fileName == null || fileName.length === 0) return fileName;
let normalized = fileName.replace(pathNormalizeRegex, '/');
if (options?.stripTrailingSlash ?? true) {
normalized = normalized.replace(pathStripTrailingSlashRegex, emptyStr);
}
if ((options?.addLeadingSlash ?? false) && normalized.charCodeAt(0) !== CharCode.Slash) {
normalized = `/${normalized}`;
}
if (isWindows) {
// Ensure that drive casing is normalized (lower case)
normalized = normalized.replace(driveLetterNormalizeRegex, drive => drive.toLowerCase());
}
return normalized;
}
export function pad(s: string, before: number = 0, after: number = 0, padding: string = '\u00a0') { export function pad(s: string, before: number = 0, after: number = 0, padding: string = '\u00a0') {
if (before === 0 && after === 0) return s; if (before === 0 && after === 0) return s;

+ 2
- 2
src/views/nodes/branchTrackingStatusFilesNode.ts View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ViewFilesLayout } from '../../configuration'; import { ViewFilesLayout } from '../../configuration';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitBranch, GitFileWithCommit, GitRevision } from '../../git/models'; import { GitBranch, GitFileWithCommit, GitRevision } from '../../git/models';
import { Arrays, Iterables, Strings } from '../../system'; import { Arrays, Iterables, Strings } from '../../system';
import { joinPaths, normalizePath } from '../../system/path';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';
import { BranchNode } from './branchNode'; import { BranchNode } from './branchNode';
import { BranchTrackingStatus } from './branchTrackingStatusNode'; import { BranchTrackingStatus } from './branchTrackingStatusNode';
@ -84,7 +84,7 @@ export class BranchTrackingStatusFilesNode extends ViewNode {
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children, children,
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );

+ 1
- 1
src/views/nodes/commitFileNode.ts View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
import { dirname, join as joinPaths } from 'path';
import { Command, Selection, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode'; import { Command, Selection, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode';
import { Commands, DiffWithPreviousCommandArgs } from '../../commands'; import { Commands, DiffWithPreviousCommandArgs } from '../../commands';
import { StatusFileFormatter } from '../../git/formatters'; import { StatusFileFormatter } from '../../git/formatters';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitBranch, GitFile, GitLogCommit, GitRevisionReference } from '../../git/models'; import { GitBranch, GitFile, GitLogCommit, GitRevisionReference } from '../../git/models';
import { dirname, joinPaths } from '../../system/path';
import { FileHistoryView } from '../fileHistoryView'; import { FileHistoryView } from '../fileHistoryView';
import { View, ViewsWithCommits } from '../viewBase'; import { View, ViewsWithCommits } from '../viewBase';
import { ContextValues, ViewNode, ViewRefFileNode } from './viewNode'; import { ContextValues, ViewNode, ViewRefFileNode } from './viewNode';

+ 2
- 2
src/views/nodes/commitNode.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { Command, MarkdownString, ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Command, MarkdownString, ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Commands, DiffWithPreviousCommandArgs } from '../../commands'; import { Commands, DiffWithPreviousCommandArgs } from '../../commands';
import { ViewFilesLayout } from '../../configuration'; import { ViewFilesLayout } from '../../configuration';
@ -7,6 +6,7 @@ import { Colors, GlyphChars } from '../../constants';
import { CommitFormatter } from '../../git/formatters'; import { CommitFormatter } from '../../git/formatters';
import { GitBranch, GitLogCommit, GitRevisionReference } from '../../git/models'; import { GitBranch, GitLogCommit, GitRevisionReference } from '../../git/models';
import { Arrays, Strings } from '../../system'; import { Arrays, Strings } from '../../system';
import { joinPaths, normalizePath } from '../../system/path';
import { FileHistoryView } from '../fileHistoryView'; import { FileHistoryView } from '../fileHistoryView';
import { TagsView } from '../tagsView'; import { TagsView } from '../tagsView';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';
@ -57,7 +57,7 @@ export class CommitNode extends ViewRefNode
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children as FileNode[], children as FileNode[],
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );

+ 1
- 1
src/views/nodes/fileHistoryNode.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { basename, join as joinPaths } from 'path';
import { Disposable, TreeItem, TreeItemCollapsibleState, window } from 'vscode'; import { Disposable, TreeItem, TreeItemCollapsibleState, window } from 'vscode';
import { configuration } from '../../configuration'; import { configuration } from '../../configuration';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
@ -14,6 +13,7 @@ import {
} from '../../git/models'; } from '../../git/models';
import { Logger } from '../../logger'; import { Logger } from '../../logger';
import { Arrays, debug, gate, Iterables, memoize } from '../../system'; import { Arrays, debug, gate, Iterables, memoize } from '../../system';
import { basename, joinPaths } from '../../system/path';
import { FileHistoryView } from '../fileHistoryView'; import { FileHistoryView } from '../fileHistoryView';
import { CommitNode } from './commitNode'; import { CommitNode } from './commitNode';
import { LoadMoreNode, MessageNode } from './common'; import { LoadMoreNode, MessageNode } from './common';

+ 1
- 1
src/views/nodes/fileRevisionAsCommitNode.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { import {
Command, Command,
MarkdownString, MarkdownString,
@ -15,6 +14,7 @@ import { Colors, GlyphChars } from '../../constants';
import { CommitFormatter, StatusFileFormatter } from '../../git/formatters'; import { CommitFormatter, StatusFileFormatter } from '../../git/formatters';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitBranch, GitFile, GitLogCommit, GitRevisionReference } from '../../git/models'; import { GitBranch, GitFile, GitLogCommit, GitRevisionReference } from '../../git/models';
import { joinPaths } from '../../system/path';
import { FileHistoryView } from '../fileHistoryView'; import { FileHistoryView } from '../fileHistoryView';
import { LineHistoryView } from '../lineHistoryView'; import { LineHistoryView } from '../lineHistoryView';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';

+ 1
- 1
src/views/nodes/mergeConflictFileNode.ts View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
import { dirname } from 'path';
import { Command, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode'; import { Command, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode';
import { BuiltInCommands } from '../../constants'; import { BuiltInCommands } from '../../constants';
import { StatusFileFormatter } from '../../git/formatters'; import { StatusFileFormatter } from '../../git/formatters';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitFile, GitMergeStatus, GitRebaseStatus } from '../../git/models'; import { GitFile, GitMergeStatus, GitRebaseStatus } from '../../git/models';
import { dirname } from '../../system/path';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';
import { FileNode } from './folderNode'; import { FileNode } from './folderNode';
import { MergeConflictCurrentChangesNode } from './mergeConflictCurrentChangesNode'; import { MergeConflictCurrentChangesNode } from './mergeConflictCurrentChangesNode';

+ 2
- 2
src/views/nodes/mergeStatusNode.ts View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { MarkdownString, ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { MarkdownString, ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ViewFilesLayout } from '../../configuration'; import { ViewFilesLayout } from '../../configuration';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitBranch, GitMergeStatus, GitReference, GitStatus } from '../../git/models'; import { GitBranch, GitMergeStatus, GitReference, GitStatus } from '../../git/models';
import { Arrays, Strings } from '../../system'; import { Arrays, Strings } from '../../system';
import { joinPaths, normalizePath } from '../../system/path';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';
import { BranchNode } from './branchNode'; import { BranchNode } from './branchNode';
import { FileNode, FolderNode } from './folderNode'; import { FileNode, FolderNode } from './folderNode';
@ -48,7 +48,7 @@ export class MergeStatusNode extends ViewNode {
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children, children,
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );

+ 3
- 3
src/views/nodes/rebaseStatusNode.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { import {
Command, Command,
commands, commands,
@ -24,6 +23,7 @@ import {
GitStatus, GitStatus,
} from '../../git/models'; } from '../../git/models';
import { Arrays, Strings } from '../../system'; import { Arrays, Strings } from '../../system';
import { joinPaths, normalizePath } from '../../system/path';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';
import { BranchNode } from './branchNode'; import { BranchNode } from './branchNode';
import { CommitFileNode } from './commitFileNode'; import { CommitFileNode } from './commitFileNode';
@ -65,7 +65,7 @@ export class RebaseStatusNode extends ViewNode {
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children, children,
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );
@ -182,7 +182,7 @@ export class RebaseCommitNode extends ViewRefNode
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children, children,
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );

+ 1
- 1
src/views/nodes/resultsFileNode.ts View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
import { dirname, join as joinPaths } from 'path';
import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Commands, DiffWithCommandArgs } from '../../commands'; import { Commands, DiffWithCommandArgs } from '../../commands';
import { StatusFileFormatter } from '../../git/formatters'; import { StatusFileFormatter } from '../../git/formatters';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitFile, GitReference, GitRevisionReference } from '../../git/models'; import { GitFile, GitReference, GitRevisionReference } from '../../git/models';
import { dirname, joinPaths } from '../../system/path';
import { View } from '../viewBase'; import { View } from '../viewBase';
import { FileNode } from './folderNode'; import { FileNode } from './folderNode';
import { ContextValues, ViewNode, ViewRefFileNode } from './viewNode'; import { ContextValues, ViewNode, ViewRefFileNode } from './viewNode';

+ 2
- 2
src/views/nodes/resultsFilesNode.ts View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ViewFilesLayout } from '../../configuration'; import { ViewFilesLayout } from '../../configuration';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitFile } from '../../git/models'; import { GitFile } from '../../git/models';
import { Arrays, debug, gate, Iterables, Promises, Strings } from '../../system'; import { Arrays, debug, gate, Iterables, Promises, Strings } from '../../system';
import { joinPaths, normalizePath } from '../../system/path';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';
import { FileNode, FolderNode } from './folderNode'; import { FileNode, FolderNode } from './folderNode';
import { ResultsFileNode } from './resultsFileNode'; import { ResultsFileNode } from './resultsFileNode';
@ -78,7 +78,7 @@ export class ResultsFilesNode extends ViewNode {
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children, children,
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );

+ 2
- 2
src/views/nodes/stashNode.ts View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ViewFilesLayout } from '../../config'; import { ViewFilesLayout } from '../../config';
import { CommitFormatter } from '../../git/formatters'; import { CommitFormatter } from '../../git/formatters';
import { GitStashCommit, GitStashReference } from '../../git/models'; import { GitStashCommit, GitStashReference } from '../../git/models';
import { Arrays, Strings } from '../../system'; import { Arrays, Strings } from '../../system';
import { joinPaths, normalizePath } from '../../system/path';
import { ContextValues, FileNode, FolderNode, RepositoryNode, StashFileNode, ViewNode, ViewRefNode } from '../nodes'; import { ContextValues, FileNode, FolderNode, RepositoryNode, StashFileNode, ViewNode, ViewRefNode } from '../nodes';
import { RepositoriesView } from '../repositoriesView'; import { RepositoriesView } from '../repositoriesView';
import { StashesView } from '../stashesView'; import { StashesView } from '../stashesView';
@ -43,7 +43,7 @@ export class StashNode extends ViewRefNode
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children, children,
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );

+ 1
- 1
src/views/nodes/statusFileNode.ts View File

@ -1,11 +1,11 @@
'use strict'; 'use strict';
import { dirname, join as joinPaths } from 'path';
import { Command, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Command, ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Commands, DiffWithCommandArgs, DiffWithPreviousCommandArgs } from '../../commands'; import { Commands, DiffWithCommandArgs, DiffWithPreviousCommandArgs } from '../../commands';
import { StatusFileFormatter } from '../../git/formatters/statusFormatter'; import { StatusFileFormatter } from '../../git/formatters/statusFormatter';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { GitFile, GitLogCommit } from '../../git/models'; import { GitFile, GitLogCommit } from '../../git/models';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { dirname, joinPaths } from '../../system/path';
import { ViewsWithCommits } from '../viewBase'; import { ViewsWithCommits } from '../viewBase';
import { FileRevisionAsCommitNode } from './fileRevisionAsCommitNode'; import { FileRevisionAsCommitNode } from './fileRevisionAsCommitNode';
import { FileNode } from './folderNode'; import { FileNode } from './folderNode';

+ 2
- 2
src/views/nodes/statusFilesNode.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { join as joinPaths } from 'path';
import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ViewFilesLayout } from '../../configuration'; import { ViewFilesLayout } from '../../configuration';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
@ -14,6 +13,7 @@ import {
GitTrackingState, GitTrackingState,
} from '../../git/models'; } from '../../git/models';
import { Arrays, Iterables, Strings } from '../../system'; import { Arrays, Iterables, Strings } from '../../system';
import { joinPaths, normalizePath } from '../../system/path';
import { RepositoriesView } from '../repositoriesView'; import { RepositoriesView } from '../repositoriesView';
import { FileNode, FolderNode } from './folderNode'; import { FileNode, FolderNode } from './folderNode';
import { RepositoryNode } from './repositoryNode'; import { RepositoryNode } from './repositoryNode';
@ -111,7 +111,7 @@ export class StatusFilesNode extends ViewNode {
const hierarchy = Arrays.makeHierarchical( const hierarchy = Arrays.makeHierarchical(
children, children,
n => n.uri.relativePath.split('/'), n => n.uri.relativePath.split('/'),
(...parts: string[]) => Strings.normalizePath(joinPaths(...parts)),
(...parts: string[]) => normalizePath(joinPaths(...parts)),
this.view.config.files.compact, this.view.config.files.compact,
); );

+ 7
- 6
src/vsls/host.ts View File

@ -5,7 +5,8 @@ import type { LiveShare, SharedService } from '../@types/vsls';
import { Container } from '../container'; import { Container } from '../container';
import { GitUri } from '../git/gitUri'; import { GitUri } from '../git/gitUri';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { debug, Iterables, log, Strings } from '../system';
import { debug, Iterables, log } from '../system';
import { normalizePath } from '../system/path';
import { import {
GitCommandRequest, GitCommandRequest,
GitCommandRequestType, GitCommandRequestType,
@ -111,8 +112,8 @@ export class VslsHostService implements Disposable {
let localPath; let localPath;
let sharedPath; let sharedPath;
for (const f of workspace.workspaceFolders) { for (const f of workspace.workspaceFolders) {
localPath = Strings.normalizePath(f.uri.fsPath);
sharedPath = Strings.normalizePath(this.convertLocalUriToShared(f.uri).fsPath);
localPath = normalizePath(f.uri.fsPath);
sharedPath = normalizePath(this.convertLocalUriToShared(f.uri).fsPath);
Logger.debug(cc, `shared='${sharedPath}' \u2194 local='${localPath}'`); Logger.debug(cc, `shared='${sharedPath}' \u2194 local='${localPath}'`);
this._localToSharedPaths.set(localPath, sharedPath); this._localToSharedPaths.set(localPath, sharedPath);
@ -142,7 +143,7 @@ export class VslsHostService implements Disposable {
if (options.cwd !== undefined && options.cwd.length > 0 && this._sharedToLocalPaths !== undefined) { if (options.cwd !== undefined && options.cwd.length > 0 && this._sharedToLocalPaths !== undefined) {
// This is all so ugly, but basically we are converting shared paths to local paths // This is all so ugly, but basically we are converting shared paths to local paths
if (this._sharedPathsRegex?.test(options.cwd)) { if (this._sharedPathsRegex?.test(options.cwd)) {
options.cwd = Strings.normalizePath(options.cwd).replace(this._sharedPathsRegex, (match, shared) => {
options.cwd = normalizePath(options.cwd).replace(this._sharedPathsRegex, (match, shared) => {
if (!isRootWorkspace) { if (!isRootWorkspace) {
isRootWorkspace = shared === '/~0'; isRootWorkspace = shared === '/~0';
} }
@ -180,7 +181,7 @@ export class VslsHostService implements Disposable {
args.splice( args.splice(
i, i,
1, 1,
Strings.normalizePath(arg).replace(this._sharedPathsRegex, (match, shared) => {
normalizePath(arg).replace(this._sharedPathsRegex, (match, shared) => {
const local = this._sharedToLocalPaths.get(shared); const local = this._sharedToLocalPaths.get(shared);
return local != null ? local : shared; return local != null ? local : shared;
}), }),
@ -212,7 +213,7 @@ export class VslsHostService implements Disposable {
_cancellation: CancellationToken, _cancellation: CancellationToken,
): Promise<RepositoriesInFolderResponse> { ): Promise<RepositoriesInFolderResponse> {
const uri = this.convertSharedUriToLocal(Uri.parse(request.folderUri)); const uri = this.convertSharedUriToLocal(Uri.parse(request.folderUri));
const normalized = Strings.normalizePath(uri.fsPath, { stripTrailingSlash: true }).toLowerCase();
const normalized = normalizePath(uri.fsPath).toLowerCase();
const repos = [ const repos = [
...Iterables.filterMap(this.container.git.repositories, r => { ...Iterables.filterMap(this.container.git.repositories, r => {

+ 3
- 2
src/webviews/rebaseEditor.ts View File

@ -22,7 +22,8 @@ import { Container } from '../container';
import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { Messages } from '../messages'; import { Messages } from '../messages';
import { debug, gate, Iterables, Strings } from '../system';
import { debug, gate, Iterables } from '../system';
import { normalizePath } from '../system/path';
import { import {
Author, Author,
Commit, Commit,
@ -164,7 +165,7 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl
@debug({ args: false }) @debug({ args: false })
async resolveCustomTextEditor(document: TextDocument, panel: WebviewPanel, _token: CancellationToken) { async resolveCustomTextEditor(document: TextDocument, panel: WebviewPanel, _token: CancellationToken) {
const repoPath = Strings.normalizePath(Uri.joinPath(document.uri, '..', '..', '..').fsPath);
const repoPath = normalizePath(Uri.joinPath(document.uri, '..', '..', '..').fsPath);
const repo = await this.container.git.getRepository(repoPath); const repo = await this.container.git.getRepository(repoPath);
const subscriptions: Disposable[] = []; const subscriptions: Disposable[] = [];

Loading…
Cancel
Save