Skip to content

Commit 1a4dafe

Browse files
committed
Closes #1267 - notifies on improper folder casing
1 parent 66de915 commit 1a4dafe

File tree

5 files changed

+55
-5
lines changed

5 files changed

+55
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
4444

4545
### Fixed
4646

47+
- Fixes [#1267](https://github.com/eamodio/vscode-gitlens/issues/1267) - File history fails on Git for Windows 2.27 ("There are no editors open that can provide file history information.")
4748
- Fixes [#1006](https://github.com/eamodio/vscode-gitlens/issues/1006) - "GitLens: Open File on Remote" opens wrong Bitbucket URL
4849
- Fixes [#901](https://github.com/eamodio/vscode-gitlens/issues/901) - Bitbucket Server fails when url = https://DOMAIN/stash/scm/PROJECT/REPO.git
4950
- Fixes [#1354](https://github.com/eamodio/vscode-gitlens/issues/1354) - Stuck after merge a branch with a single quote in the name

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,6 +2496,7 @@
24962496
"suppressFileNotUnderSourceControlWarning": false,
24972497
"suppressGitDisabledWarning": false,
24982498
"suppressGitVersionWarning": false,
2499+
"suppressImproperWorkspaceCasingWarning": false,
24992500
"suppressLineUncommittedWarning": false,
25002501
"suppressNoRepositoryWarning": false,
25012502
"suppressRebaseSwitchToTextWarning": false
@@ -2525,6 +2526,10 @@
25252526
"type": "boolean",
25262527
"default": false
25272528
},
2529+
"suppressImproperWorkspaceCasingWarning": {
2530+
"type": "boolean",
2531+
"default": false
2532+
},
25282533
"suppressLineUncommittedWarning": {
25292534
"type": "boolean",
25302535
"default": false

src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ export interface AdvancedConfig {
307307
suppressFileNotUnderSourceControlWarning: boolean;
308308
suppressGitDisabledWarning: boolean;
309309
suppressGitVersionWarning: boolean;
310+
suppressImproperWorkspaceCasingWarning: boolean;
310311
suppressLineUncommittedWarning: boolean;
311312
suppressNoRepositoryWarning: boolean;
312313
suppressRebaseSwitchToTextWarning: boolean;

src/git/gitService.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3279,10 +3279,11 @@ export class GitService implements Disposable {
32793279
private async getRepoPathCore(filePath: string, isDirectory: boolean): Promise<string | undefined> {
32803280
const cc = Logger.getCorrelationContext();
32813281

3282+
let repoPath: string | undefined;
32823283
try {
32833284
const path = isDirectory ? filePath : paths.dirname(filePath);
32843285

3285-
let repoPath = await Git.rev_parse__show_toplevel(path);
3286+
repoPath = await Git.rev_parse__show_toplevel(path);
32863287
if (repoPath == null) return repoPath;
32873288

32883289
if (isWindows) {
@@ -3303,25 +3304,26 @@ export class GitService implements Disposable {
33033304
),
33043305
);
33053306
if (networkPath != null) {
3306-
return Strings.normalizePath(
3307+
repoPath = Strings.normalizePath(
33073308
repoUri.fsPath.replace(
33083309
networkPath,
33093310
`${letter.toLowerCase()}:${networkPath.endsWith('\\') ? '\\' : ''}`,
33103311
),
33113312
);
3313+
return repoPath;
33123314
}
33133315
} catch {}
33143316
}
33153317

3316-
return Strings.normalizePath(pathUri.fsPath);
3318+
repoPath = Strings.normalizePath(pathUri.fsPath);
33173319
}
33183320

33193321
return repoPath;
33203322
}
33213323

33223324
// If we are not on Windows (symlinks don't seem to have the same issue on Windows), check if we are a symlink and if so, use the symlink path (not its resolved path)
33233325
// This is because VS Code will provide document Uris using the symlinked path
3324-
return await new Promise<string | undefined>(resolve => {
3326+
repoPath = await new Promise<string | undefined>(resolve => {
33253327
fs.realpath(path, { encoding: 'utf8' }, (err, resolvedPath) => {
33263328
if (err != null) {
33273329
Logger.debug(cc, `fs.realpath failed; repoPath=${repoPath}`);
@@ -3344,9 +3346,41 @@ export class GitService implements Disposable {
33443346
resolve(repoPath);
33453347
});
33463348
});
3349+
3350+
return repoPath;
33473351
} catch (ex) {
33483352
Logger.error(ex, cc);
3349-
return undefined;
3353+
repoPath = undefined;
3354+
return repoPath;
3355+
} finally {
3356+
if (repoPath) {
3357+
void this.ensureProperWorkspaceCasing(repoPath, filePath);
3358+
}
3359+
}
3360+
}
3361+
3362+
@gate(() => '')
3363+
private async ensureProperWorkspaceCasing(repoPath: string, filePath: string) {
3364+
if (Container.config.advanced.messages.suppressImproperWorkspaceCasingWarning) return;
3365+
3366+
filePath = filePath.replace(/\\/g, '/');
3367+
3368+
let regexPath;
3369+
let testPath;
3370+
if (filePath > repoPath) {
3371+
regexPath = filePath;
3372+
testPath = repoPath;
3373+
} else {
3374+
testPath = filePath;
3375+
regexPath = repoPath;
3376+
}
3377+
3378+
let pathRegex = new RegExp(`^${regexPath}`);
3379+
if (!pathRegex.test(testPath)) {
3380+
pathRegex = new RegExp(pathRegex, 'i');
3381+
if (pathRegex.test(testPath)) {
3382+
await Messages.showIncorrectWorkspaceCasingWarningMessage();
3383+
}
33503384
}
33513385
}
33523386

src/messages.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export enum SuppressedMessages {
1111
FileNotUnderSourceControlWarning = 'suppressFileNotUnderSourceControlWarning',
1212
GitDisabledWarning = 'suppressGitDisabledWarning',
1313
GitVersionWarning = 'suppressGitVersionWarning',
14+
IncorrectWorkspaceCasingWarning = 'suppressImproperWorkspaceCasingWarning',
1415
LineUncommittedWarning = 'suppressLineUncommittedWarning',
1516
NoRepositoryWarning = 'suppressNoRepositoryWarning',
1617
RebaseSwitchToTextWarning = 'suppressRebaseSwitchToTextWarning',
@@ -92,6 +93,14 @@ export class Messages {
9293
);
9394
}
9495

96+
static async showIncorrectWorkspaceCasingWarningMessage(): Promise<void> {
97+
void (await Messages.showMessage(
98+
'warn',
99+
'This workspace was opened with a different casing than what exists on disk. Please re-open this workspace with the exact casing as it exists on disk, otherwise you may experience issues with certain Git features, such as missing blame or history.',
100+
SuppressedMessages.IncorrectWorkspaceCasingWarning,
101+
));
102+
}
103+
95104
static showInsidersErrorMessage() {
96105
return Messages.showMessage(
97106
'error',

0 commit comments

Comments
 (0)