Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: throw error if issue with git #16618

Merged
merged 14 commits into from
Jul 18, 2022
169 changes: 141 additions & 28 deletions lib/util/git/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ async function getDefaultBranch(git: SimpleGit): Promise<string> {
}
return res.replace('origin/', '').trim();
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
const errChecked = checkForPlatformFailure(err);
if (errChecked) {
throw errChecked;
Expand Down Expand Up @@ -207,6 +210,9 @@ async function fetchBranchCommits(): Promise<void> {
config.branchCommits[ref.replace('refs/heads/', '')] = sha;
});
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
const errChecked = checkForPlatformFailure(err);
if (errChecked) {
throw errChecked;
Expand All @@ -231,32 +237,60 @@ export async function initRepo(args: StorageConfig): Promise<void> {
}

async function resetToBranch(branchName: string): Promise<void> {
logger.debug(`resetToBranch(${branchName})`);
await git.raw(['reset', '--hard']);
await gitRetry(() => git.checkout(branchName));
await git.raw(['reset', '--hard', 'origin/' + branchName]);
await git.raw(['clean', '-fd']);
try {
logger.debug(`resetToBranch(${branchName})`);
await git.raw(['reset', '--hard']);
await gitRetry(() => git.checkout(branchName));
await git.raw(['reset', '--hard', 'origin/' + branchName]);
await git.raw(['clean', '-fd']);
} catch (err) {
/* istanbul ignore next*/
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
}
}

// istanbul ignore next
export async function resetToCommit(commit: string): Promise<void> {
logger.debug(`resetToCommit(${commit})`);
await git.raw(['reset', '--hard', commit]);
try {
logger.debug(`resetToCommit(${commit})`);
await git.raw(['reset', '--hard', commit]);
} catch (err) {
/*istanbul ignore next*/
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
}
}

async function deleteLocalBranch(branchName: string): Promise<void> {
await git.branch(['-D', branchName]);
try {
await git.branch(['-D', branchName]);
} catch (err) {
/*istanbul ignore next*/
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
}
}

async function cleanLocalBranches(): Promise<void> {
const existingBranches = (await git.raw(['branch']))
.split(newlineRegex)
.map((branch) => branch.trim())
.filter((branch) => branch.length)
.filter((branch) => !branch.startsWith('* '));
logger.debug({ existingBranches });
for (const branchName of existingBranches) {
await deleteLocalBranch(branchName);
try {
const existingBranches = (await git.raw(['branch']))
.split(newlineRegex)
.map((branch) => branch.trim())
.filter((branch) => branch.length)
.filter((branch) => !branch.startsWith('* '));
logger.debug({ existingBranches });
for (const branchName of existingBranches) {
await deleteLocalBranch(branchName);
}
} catch (err) {
/*istanbul ignore next*/
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
}
}

Expand Down Expand Up @@ -327,6 +361,9 @@ export async function getSubmodules(): Promise<string[]> {
.split(regEx(/[\n\s]/))
.filter((_e: string, i: number) => i % 2);
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
logger.warn({ err }, 'Error getting submodules');
return [];
}
Expand Down Expand Up @@ -397,7 +434,14 @@ export async function syncGit(): Promise<void> {
const durationMs = Math.round(Date.now() - cloneStart);
logger.debug({ durationMs }, 'git clone completed');
}
config.currentBranchSha = (await git.raw(['rev-parse', 'HEAD'])).trim();
try {
config.currentBranchSha = (await git.raw(['rev-parse', 'HEAD'])).trim();
} catch (err) {
/*istanbul ignore next*/
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
}
if (config.cloneSubmodules) {
const submodules = await getSubmodules();
for (const submodule of submodules) {
Expand All @@ -416,6 +460,10 @@ export async function syncGit(): Promise<void> {
const latestCommit = (await git.log({ n: 1 })).latest;
logger.debug({ latestCommit }, 'latest repository commit');
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}

const errChecked = checkForPlatformFailure(err);
if (errChecked) {
throw errChecked;
Expand Down Expand Up @@ -443,7 +491,15 @@ export async function getRepoStatus(path?: string): Promise<StatusResult> {
}

await syncGit();
return git.status(path ? [path] : []);
let status: any;
try {
status = git.status(path ? [path] : []);
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
}
return status;
}

export function branchExists(branchName: string): boolean {
Expand All @@ -464,6 +520,10 @@ export async function getBranchParentSha(
const parentSha = await git.revparse([`${branchSha}^`]);
return parentSha;
} catch (err) {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}

logger.debug({ err }, 'Error getting branch parent sha');
return null;
}
Expand Down Expand Up @@ -495,6 +555,9 @@ export async function checkoutBranch(branchName: string): Promise<CommitSha> {
await git.reset(ResetMode.HARD);
return config.currentBranchSha;
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
const errChecked = checkForPlatformFailure(err);
if (errChecked) {
throw errChecked;
Expand All @@ -515,6 +578,9 @@ export async function getFileList(): Promise<string[]> {
try {
files = await git.raw(['ls-tree', '-r', branch]);
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
if (err.message?.includes('fatal: Not a valid object name')) {
logger.debug(
{ err },
Expand Down Expand Up @@ -559,6 +625,9 @@ export async function isBranchBehindBase(branchName: string): Promise<boolean> {
);
return isBehind;
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
const errChecked = checkForPlatformFailure(err);
if (errChecked) {
throw errChecked;
Expand Down Expand Up @@ -608,6 +677,12 @@ export async function isBranchModified(branchName: string): Promise<boolean> {
'Remote branch not found when checking last commit author - aborting run'
);
throw new Error(REPOSITORY_CHANGED);
} else if (
err.message?.includes(
'fatal: not a git repository (or any parent up to mount point /mnt)'
)
) {
throw new Error(REPOSITORY_CHANGED);
}
logger.warn({ err }, 'Error checking last author for isBranchModified');
}
Expand Down Expand Up @@ -675,9 +750,11 @@ export async function isBranchConflicted(
await git.checkout(baseBranch);
}
await git.merge(['--no-commit', '--no-ff', `origin/${branch}`]);
} catch (err) {
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
result = true;
// istanbul ignore if: not easily testable
if (!err?.git?.conflicts?.length) {
logger.debug(
{ baseBranch, branch, err },
Expand Down Expand Up @@ -708,6 +785,9 @@ export async function deleteBranch(branchName: string): Promise<void> {
await gitRetry(() => git.raw(['push', '--delete', 'origin', branchName]));
logger.debug({ branchName }, 'Deleted remote branch');
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
const errChecked = checkForPlatformFailure(err);
if (errChecked) {
throw errChecked;
Expand Down Expand Up @@ -748,7 +828,10 @@ export async function mergeBranch(branchName: string): Promise<void> {
await gitRetry(() => git.merge(['--ff-only', branchName]));
await gitRetry(() => git.push('origin', config.currentBranch));
incLimitedValue(Limit.Commits);
} catch (err) {
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
logger.debug(
{
baseBranch: config.currentBranch,
Expand All @@ -771,7 +854,10 @@ export async function getBranchLastCommitTime(
try {
const time = await git.show(['-s', '--format=%ai', 'origin/' + branchName]);
return new Date(Date.parse(time));
} catch (err) {
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
const errChecked = checkForPlatformFailure(err);
// istanbul ignore if
if (errChecked) {
Expand All @@ -791,6 +877,9 @@ export async function getBranchFiles(
);
return diff.files.map((file) => file.file);
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
logger.warn({ err }, 'getBranchFiles error');
const errChecked = checkForPlatformFailure(err);
if (errChecked) {
Expand All @@ -810,7 +899,10 @@ export async function getFile(
'origin/' + (branchName ?? config.currentBranch) + ':' + filePath,
]);
return content;
} catch (err) {
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
const errChecked = checkForPlatformFailure(err);
// istanbul ignore if
if (errChecked) {
Expand All @@ -824,7 +916,10 @@ export async function hasDiff(branchName: string): Promise<boolean> {
await syncGit();
try {
return (await gitRetry(() => git.diff(['HEAD', branchName]))) !== '';
} catch (err) {
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
return true;
}
}
Expand Down Expand Up @@ -972,6 +1067,9 @@ export async function prepareCommit({

return result;
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
return handleCommitError(files, branchName, err);
}
}
Expand Down Expand Up @@ -1000,6 +1098,9 @@ export async function pushCommit({
incLimitedValue(Limit.Commits);
result = true;
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
handleCommitError(files, branchName, err);
}
return result;
Expand All @@ -1019,6 +1120,9 @@ export async function fetchCommit({
config.branchIsModified[branchName] = false;
return commit;
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
return handleCommitError(files, branchName, err);
}
}
Expand Down Expand Up @@ -1087,10 +1191,16 @@ export async function pushCommitToRenovateRef(
refName: string,
section = 'branches'
): Promise<void> {
const fullRefName = `refs/renovate/${section}/${refName}`;
await git.raw(['update-ref', fullRefName, commitSha]);
await git.push(['--force', 'origin', fullRefName]);
remoteRefsExist = true;
try {
const fullRefName = `refs/renovate/${section}/${refName}`;
await git.raw(['update-ref', fullRefName, commitSha]);
await git.push(['--force', 'origin', fullRefName]);
remoteRefsExist = true;
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
}
}

/**
Expand Down Expand Up @@ -1128,6 +1238,9 @@ export async function clearRenovateRefs(): Promise<void> {
.filter((line) => line.startsWith('refs/renovate/'));
renovateRefs.push(...refs);
} catch (err) /* istanbul ignore next */ {
if (err.message?.includes('fatal: not a git repository')) {
throw new Error(REPOSITORY_CHANGED);
}
logger.warn({ err }, `Renovate refs cleanup error`);
}

Expand Down