mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-02 14:31:31 +01:00
Git - Attempt to parse HEAD file before invoking git.exe (#162572)
* Attempt to parse HEAD file before invoking git.exe * Pull request feedback * Pull request feedback * More pull request feedback
This commit is contained in:
@@ -18,6 +18,7 @@ import { detectEncoding } from './encoding';
|
||||
import { Ref, RefType, Branch, Remote, ForcePushMode, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git';
|
||||
import * as byline from 'byline';
|
||||
import { StringDecoder } from 'string_decoder';
|
||||
import { OutputChannelLogger } from './log';
|
||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/65693
|
||||
@@ -400,8 +401,8 @@ export class Git {
|
||||
return Versions.compare(Versions.fromString(this.version), Versions.fromString(version));
|
||||
}
|
||||
|
||||
open(repository: string, dotGit: { path: string; commonPath?: string }): Repository {
|
||||
return new Repository(this, repository, dotGit);
|
||||
open(repository: string, dotGit: { path: string; commonPath?: string }, outputChannelLogger: OutputChannelLogger): Repository {
|
||||
return new Repository(this, repository, dotGit, outputChannelLogger);
|
||||
}
|
||||
|
||||
async init(repository: string): Promise<void> {
|
||||
@@ -913,7 +914,8 @@ export class Repository {
|
||||
constructor(
|
||||
private _git: Git,
|
||||
private repositoryRoot: string,
|
||||
readonly dotGit: { path: string; commonPath?: string }
|
||||
readonly dotGit: { path: string; commonPath?: string },
|
||||
private outputChannelLogger: OutputChannelLogger
|
||||
) { }
|
||||
|
||||
get git(): Git {
|
||||
@@ -1996,6 +1998,16 @@ export class Repository {
|
||||
|
||||
async getHEAD(): Promise<Ref> {
|
||||
try {
|
||||
// Attempt to parse the HEAD file
|
||||
const result = await this.getHEADFS();
|
||||
return result;
|
||||
}
|
||||
catch (err) {
|
||||
this.outputChannelLogger.logWarning(err.message);
|
||||
}
|
||||
|
||||
try {
|
||||
// Fallback to using git to determine HEAD
|
||||
const result = await this.exec(['symbolic-ref', '--short', 'HEAD']);
|
||||
|
||||
if (!result.stdout) {
|
||||
@@ -2003,15 +2015,35 @@ export class Repository {
|
||||
}
|
||||
|
||||
return { name: result.stdout.trim(), commit: undefined, type: RefType.Head };
|
||||
} catch (err) {
|
||||
const result = await this.exec(['rev-parse', 'HEAD']);
|
||||
|
||||
if (!result.stdout) {
|
||||
throw new Error('Error parsing HEAD');
|
||||
}
|
||||
|
||||
return { name: undefined, commit: result.stdout.trim(), type: RefType.Head };
|
||||
}
|
||||
catch (err) { }
|
||||
|
||||
// Detached HEAD
|
||||
const result = await this.exec(['rev-parse', 'HEAD']);
|
||||
|
||||
if (!result.stdout) {
|
||||
throw new Error('Error parsing HEAD');
|
||||
}
|
||||
|
||||
return { name: undefined, commit: result.stdout.trim(), type: RefType.Head };
|
||||
}
|
||||
|
||||
async getHEADFS(): Promise<Ref> {
|
||||
const raw = await fs.readFile(path.join(this.dotGit.commonPath ?? this.dotGit.path, 'HEAD'), 'utf8');
|
||||
|
||||
// Branch
|
||||
const branchMatch = raw.match(/^ref: refs\/heads\/(?<name>.*)$/m);
|
||||
if (branchMatch?.groups?.name) {
|
||||
return { name: branchMatch.groups.name, commit: undefined, type: RefType.Head };
|
||||
}
|
||||
|
||||
// Detached
|
||||
const commitMatch = raw.match(/^(?<commit>[0-9a-f]{40})$/m);
|
||||
if (commitMatch?.groups?.commit) {
|
||||
return { name: undefined, commit: commitMatch.groups.commit, type: RefType.Head };
|
||||
}
|
||||
|
||||
throw new Error(`Unable to parse HEAD file. HEAD file contents: ${raw}.`);
|
||||
}
|
||||
|
||||
async findTrackingBranches(upstreamBranch: string): Promise<Branch[]> {
|
||||
|
||||
Reference in New Issue
Block a user