Skip to content

Commit 5d697c3

Browse files
committed
Adds rename detection back to status methods
1 parent fe9f732 commit 5d697c3

File tree

4 files changed

+71
-14
lines changed

4 files changed

+71
-14
lines changed

src/commands/diffWithWorking.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
8585

8686
// If we are a fake "staged" sha, check the status
8787
if (gitUri.isUncommittedStaged) {
88-
const status = await this.container.git.status(gitUri.repoPath!).getStatusForFile?.(gitUri);
88+
const status = await this.container.git
89+
.status(gitUri.repoPath!)
90+
.getStatusForFile?.(gitUri, { renames: false });
8991
if (status?.indexStatus != null) {
9092
void (await executeCommand<DiffWithCommandArgs>('gitlens.diffWith', {
9193
repoPath: gitUri.repoPath,

src/env/node/git/sub-providers/commits.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,6 @@ export class CommitsGitSubProvider implements GitCommitsSubProvider {
501501

502502
// If we didn't find any history from the working tree, check to see if the file was renamed
503503
if (rev == null && pathspec && !commits.size) {
504-
// TODO@eamodio this currently won't work because getStatusForFile won't return the original path
505504
const status = await this.provider.status?.getStatusForFile(repoPath, pathspec);
506505
if (status?.originalPath != null) {
507506
pathspec = status.originalPath;

src/env/node/git/sub-providers/status.ts

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -523,30 +523,53 @@ export class StatusGitSubProvider implements GitStatusSubProvider {
523523
return status;
524524
}
525525

526-
@gate()
527526
@log()
528-
async getStatusForFile(repoPath: string, pathOrUri: string | Uri): Promise<GitStatusFile | undefined> {
529-
const files = await this.getStatusForPath(repoPath, pathOrUri);
527+
async getStatusForFile(
528+
repoPath: string,
529+
pathOrUri: string | Uri,
530+
options?: { renames?: boolean },
531+
): Promise<GitStatusFile | undefined> {
532+
const files = await this.getStatusForPathCore(repoPath, pathOrUri, { ...options, exact: true });
530533
return files?.[0];
531534
}
532535

533-
@gate()
534536
@log()
535-
async getStatusForPath(repoPath: string, pathOrGlob: string | Uri): Promise<GitStatusFile[] | undefined> {
537+
async getStatusForPath(
538+
repoPath: string,
539+
pathOrGlob: string | Uri,
540+
options?: { renames?: boolean },
541+
): Promise<GitStatusFile[] | undefined> {
542+
return this.getStatusForPathCore(repoPath, pathOrGlob, { ...options, exact: false });
543+
}
544+
545+
@gate()
546+
private async getStatusForPathCore(
547+
repoPath: string,
548+
pathOrGlob: string | Uri,
549+
options: { exact: boolean; renames?: boolean },
550+
): Promise<GitStatusFile[] | undefined> {
536551
const [relativePath] = splitPath(pathOrGlob, repoPath);
537552

538553
const porcelainVersion = (await this.git.supports('git:status:porcelain-v2')) ? 2 : 1;
554+
const renames = options.renames !== false;
539555

540556
const result = await this.git.status(
541557
repoPath,
542558
porcelainVersion,
543-
{
544-
similarityThreshold: configuration.get('advanced.similarityThreshold') ?? undefined,
545-
},
546-
relativePath,
559+
{ similarityThreshold: configuration.get('advanced.similarityThreshold') ?? undefined },
560+
// If we want renames, don't include the path as Git won't do rename detection
561+
...(renames ? [] : [relativePath]),
547562
);
548563

549564
const status = parseGitStatus(this.container, result.stdout, repoPath, porcelainVersion);
550-
return status?.files;
565+
if (!renames) return status?.files;
566+
567+
if (options.exact) {
568+
const file = status?.files.find(f => f.path === relativePath);
569+
return file ? [file] : undefined;
570+
}
571+
572+
const files = status?.files.filter(f => f.path.startsWith(relativePath));
573+
return files;
551574
}
552575
}

src/git/gitProvider.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,42 @@ export interface GitStashSubProvider {
587587
}
588588

589589
export interface GitStatusSubProvider {
590+
/**
591+
* Get the status of the repository
592+
* @param repoPath Repository path
593+
* @returns A promise of the status
594+
*/
590595
getStatus(repoPath: string | undefined): Promise<GitStatus | undefined>;
591-
getStatusForFile?(repoPath: string, uri: Uri): Promise<GitStatusFile | undefined>;
592-
getStatusForPath?(repoPath: string, pathOrGlob: Uri): Promise<GitStatusFile[] | undefined>;
596+
/**
597+
* Get the status of a file
598+
* @param repoPath Repository path
599+
* @param uri Uri of the file to get the status for
600+
* @param options Options to control how the status is retrieved
601+
* @returns A promise of the file's status
602+
*/
603+
getStatusForFile?(
604+
repoPath: string,
605+
uri: Uri,
606+
options?: {
607+
/** If false, will avoid rename detection (faster) */
608+
renames?: boolean;
609+
},
610+
): Promise<GitStatusFile | undefined>;
611+
/**
612+
* Get the status of a path or glob
613+
* @param repoPath Repository path
614+
* @param pathOrGlob Path or "glob" (globs can only end with `/*`) to get the status for
615+
* @param options Options to control how the status is retrieved
616+
* @returns A promise of the path's status
617+
*/
618+
getStatusForPath?(
619+
repoPath: string,
620+
pathOrGlob: Uri,
621+
options?: {
622+
/** If false, will avoid rename detection (faster) */
623+
renames?: boolean;
624+
},
625+
): Promise<GitStatusFile[] | undefined>;
593626

594627
getPausedOperationStatus?(repoPath: string): Promise<GitPausedOperationStatus | undefined>;
595628
abortPausedOperation?(repoPath: string, options?: { quit?: boolean }): Promise<void>;

0 commit comments

Comments
 (0)