Browse Source

Adds better ref validation/resolve

main
Eric Amodio 4 years ago
parent
commit
1bf27de9fd
2 changed files with 37 additions and 49 deletions
  1. +25
    -37
      src/git/git.ts
  2. +12
    -12
      src/git/gitService.ts

+ 25
- 37
src/git/git.ts View File

@ -448,38 +448,6 @@ export namespace Git {
return git<string>({ cwd: repoPath, configs: ['-c', 'color.branch=false'] }, ...params, ref);
}
export async function cat_file__resolve(repoPath: string, fileName: string, ref: string) {
if (GitRevision.isUncommitted(ref)) return ref;
try {
void (await git<string>(
{ cwd: repoPath, errors: GitErrorHandling.Throw },
'cat-file',
'-e',
`${ref}:./${fileName}`,
));
return ref;
} catch (ex) {
const msg: string = ex?.toString();
if (GitErrors.notAValidObjectName.test(msg)) {
return GitRevision.deletedOrMissing;
}
return undefined;
}
}
export async function cat_file__validate(repoPath: string, ref: string) {
if (GitRevision.isUncommitted(ref)) return true;
try {
void (await git<string>({ cwd: repoPath, errors: GitErrorHandling.Throw }, 'cat-file', '-t', ref));
return true;
} catch (ex) {
return false;
}
}
export function check_ignore(repoPath: string, ...files: string[]) {
return git<string>(
{ cwd: repoPath, errors: GitErrorHandling.Ignore, stdin: files.join('\0') },
@ -922,6 +890,17 @@ export namespace Git {
return data.length === 0 ? undefined : data.trim();
}
export async function log__find_object(repoPath: string, objectId: string) {
const data = await git<string>(
{ cwd: repoPath, errors: GitErrorHandling.Ignore },
'log',
'-n1',
'--format=%H',
`--find-object=${objectId}`,
);
return data.length === 0 ? undefined : data.trim();
}
export async function log__recent(repoPath: string) {
const data = await git<string>(
{ cwd: repoPath, errors: GitErrorHandling.Ignore },
@ -1072,11 +1051,6 @@ export namespace Git {
return data.length === 0 ? undefined : Number(data.trim()) || undefined;
}
export async function rev_parse(repoPath: string, ref: string): Promise<string | undefined> {
const data = await git<string>({ cwd: repoPath, errors: GitErrorHandling.Ignore }, 'rev-parse', ref);
return data.length === 0 ? undefined : data.trim();
}
export async function rev_parse__currentBranch(
repoPath: string,
): Promise<[string, string | undefined] | undefined> {
@ -1139,6 +1113,20 @@ export namespace Git {
}
}
export async function rev_parse__verify(
repoPath: string,
ref: string,
filename?: string,
): Promise<string | undefined> {
const data = await git<string>(
{ cwd: repoPath, errors: GitErrorHandling.Ignore },
'rev-parse',
'--verify',
filename ? `${ref}:./${filename}` : `${ref}^{commit}`,
);
return data.length === 0 ? undefined : data.trim();
}
export function shortlog(repoPath: string) {
return git<string>({ cwd: repoPath }, 'shortlog', '-sne', '--all', '--no-merges');
}

+ 12
- 12
src/git/gitService.ts View File

@ -3144,12 +3144,14 @@ export class GitService implements Disposable {
async resolveReference(repoPath: string, ref: string, uri?: Uri): Promise<string>;
@log()
async resolveReference(repoPath: string, ref: string, fileNameOrUri?: string | Uri) {
if (ref == null || ref.length === 0 || ref === GitRevision.deletedOrMissing) return ref;
if (ref == null || ref.length === 0 || ref === GitRevision.deletedOrMissing || GitRevision.isUncommitted(ref)) {
return ref;
}
if (fileNameOrUri == null) {
if (GitRevision.isSha(ref) || !GitRevision.isShaLike(ref) || ref.endsWith('^3')) return ref;
return (await Git.rev_parse(repoPath, ref)) ?? ref;
return (await Git.rev_parse__verify(repoPath, ref)) ?? ref;
}
const fileName =
@ -3157,15 +3159,10 @@ export class GitService implements Disposable {
? fileNameOrUri
: Strings.normalizePath(paths.relative(repoPath, fileNameOrUri.fsPath));
if (GitRevision.isShaParent(ref)) {
const parentRef = await Git.log__file_recent(repoPath, fileName, { ref: ref });
if (parentRef != null) return parentRef;
}
const ensuredRef = await Git.cat_file__resolve(repoPath, fileName, ref);
if (ensuredRef == null) return ref;
const blob = await Git.rev_parse__verify(repoPath, ref, fileName);
if (blob == null) return ref;
return ensuredRef;
return (await Git.log__find_object(repoPath, blob)) ?? ref;
}
@log()
@ -3174,8 +3171,11 @@ export class GitService implements Disposable {
}
@log()
validateReference(repoPath: string, ref: string) {
return Git.cat_file__validate(repoPath, ref);
async validateReference(repoPath: string, ref: string) {
if (ref == null || ref.length === 0) return false;
if (ref === GitRevision.deletedOrMissing || GitRevision.isUncommitted(ref)) return true;
return (await Git.rev_parse__verify(repoPath, ref)) != null;
}
stageFile(repoPath: string, fileName: string): Promise<string>;

Loading…
Cancel
Save