mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 23:16:26 +00:00
refactor(git): lazy sync git (#6984)
Co-authored-by: Jamie Magee <JamieMagee@users.noreply.github.com>
This commit is contained in:
parent
b45502cd28
commit
062045168a
8 changed files with 53 additions and 29 deletions
|
@ -150,7 +150,7 @@ export async function initRepo({
|
|||
const url =
|
||||
defaults.endpoint +
|
||||
`${encodeURIComponent(projectName)}/_git/${encodeURIComponent(repoName)}`;
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
...config,
|
||||
localDir,
|
||||
url,
|
||||
|
|
|
@ -179,7 +179,7 @@ export async function initRepo({
|
|||
repository,
|
||||
});
|
||||
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
...config,
|
||||
localDir,
|
||||
url: gitUrl,
|
||||
|
|
|
@ -153,7 +153,7 @@ export async function initRepo({
|
|||
repository,
|
||||
});
|
||||
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
...config,
|
||||
localDir,
|
||||
url,
|
||||
|
|
|
@ -306,7 +306,7 @@ const platform: Platform = {
|
|||
gitEndpoint.auth = opts.token;
|
||||
|
||||
// Initialize Git storage
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
...config,
|
||||
url: URL.format(gitEndpoint),
|
||||
gitAuthorName: global.gitAuthor?.name,
|
||||
|
|
|
@ -413,7 +413,7 @@ export async function initRepo({
|
|||
);
|
||||
parsedEndpoint.pathname = config.repository + '.git';
|
||||
const url = URL.format(parsedEndpoint);
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
...config,
|
||||
url,
|
||||
gitAuthorName: global.gitAuthor?.name,
|
||||
|
|
|
@ -224,7 +224,7 @@ export async function initRepo({
|
|||
repoUrl.auth = 'oauth2:' + opts.token;
|
||||
url = URL.format(repoUrl);
|
||||
}
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
...config,
|
||||
url,
|
||||
gitAuthorName: global.gitAuthor?.name,
|
||||
|
|
|
@ -60,7 +60,7 @@ describe('platform/git', () => {
|
|||
const repo = Git(origin.path);
|
||||
await repo.clone(base.path, '.', ['--bare']);
|
||||
tmpDir = await tmp.dir({ unsafeCleanup: true });
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
localDir: tmpDir.path,
|
||||
url: origin.path,
|
||||
extraCloneOpts: {
|
||||
|
@ -100,10 +100,11 @@ describe('platform/git', () => {
|
|||
const repo = Git(base.path).silent(true);
|
||||
await repo.submoduleAdd(base.path, 'submodule');
|
||||
await repo.commit('Add submodule');
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
localDir: tmpDir.path,
|
||||
url: base.path,
|
||||
});
|
||||
await git.syncGit();
|
||||
expect(await fs.exists(tmpDir.path + '/.gitmodules')).toBeTruthy();
|
||||
expect(await git.getFileList()).toMatchSnapshot();
|
||||
await repo.reset(['--hard', 'HEAD^']);
|
||||
|
@ -129,6 +130,7 @@ describe('platform/git', () => {
|
|||
});
|
||||
describe('isBranchStale()', () => {
|
||||
beforeEach(async () => {
|
||||
await git.syncGit();
|
||||
await git.setBranch('master');
|
||||
});
|
||||
it('should return false if same SHA as master', async () => {
|
||||
|
@ -369,7 +371,7 @@ describe('platform/git', () => {
|
|||
|
||||
await git.setBranch('develop');
|
||||
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
localDir: tmpDir.path,
|
||||
url: base.path,
|
||||
});
|
||||
|
@ -391,7 +393,7 @@ describe('platform/git', () => {
|
|||
await repo.commit('past message2');
|
||||
await repo.checkout('master');
|
||||
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
localDir: tmpDir.path,
|
||||
url: base.path,
|
||||
});
|
||||
|
@ -400,7 +402,7 @@ describe('platform/git', () => {
|
|||
expect(await git.branchExists('renovate/test')).toBe(true);
|
||||
const cid = await git.getBranchCommit('renovate/test');
|
||||
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
localDir: tmpDir.path,
|
||||
url: base.path,
|
||||
});
|
||||
|
@ -429,10 +431,11 @@ describe('platform/git', () => {
|
|||
'test',
|
||||
]);
|
||||
await repo.commit('Add submodule');
|
||||
await git.initRepo({
|
||||
git.initRepo({
|
||||
localDir: tmpDir.path,
|
||||
url: base.path,
|
||||
});
|
||||
await git.syncGit();
|
||||
expect(await fs.exists(tmpDir.path + '/.gitmodules')).toBeTruthy();
|
||||
await repo.reset(['--hard', 'HEAD^']);
|
||||
});
|
||||
|
|
|
@ -114,6 +114,13 @@ let git: SimpleGit | undefined;
|
|||
|
||||
let privateKeySet = false;
|
||||
|
||||
export function initRepo(args: StorageConfig): void {
|
||||
config = { ...args } as any;
|
||||
config.branchExists = {};
|
||||
config.branchIsModified = {};
|
||||
git = undefined;
|
||||
}
|
||||
|
||||
async function resetToBranch(branchName: string): Promise<void> {
|
||||
logger.debug(`resetToBranch(${branchName})`);
|
||||
await git.raw(['reset', '--hard']);
|
||||
|
@ -143,8 +150,10 @@ async function cleanLocalBranches(): Promise<void> {
|
|||
* By calling this function once the repo's branchPrefix is known, we can fetch all of Renovate's branches in one command.
|
||||
*/
|
||||
export async function setBranchPrefix(branchPrefix: string): Promise<void> {
|
||||
logger.debug('Setting branchPrefix: ' + branchPrefix);
|
||||
config.branchPrefix = branchPrefix;
|
||||
// If the repo is already cloned then set branchPrefix now, otherwise it will be called again during syncGit()
|
||||
if (git) {
|
||||
logger.debug('Setting branchPrefix: ' + branchPrefix);
|
||||
const ref = `refs/heads/${branchPrefix}*:refs/remotes/origin/${branchPrefix}*`;
|
||||
try {
|
||||
await git.fetch(['origin', ref, '--depth=2', '--force']);
|
||||
|
@ -152,6 +161,7 @@ export async function setBranchPrefix(branchPrefix: string): Promise<void> {
|
|||
checkForPlatformFailure(err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSubmodules(): Promise<string[]> {
|
||||
|
@ -258,20 +268,15 @@ export async function syncGit(): Promise<void> {
|
|||
logger.debug({ err }, 'Error setting git author config');
|
||||
throw new Error(REPOSITORY_TEMPORARY_ERROR);
|
||||
}
|
||||
|
||||
config.currentBranch = config.currentBranch || (await getDefaultBranch(git));
|
||||
}
|
||||
|
||||
export async function initRepo(args: StorageConfig): Promise<void> {
|
||||
config = { ...args } as any;
|
||||
config.branchExists = {};
|
||||
config.branchIsModified = {};
|
||||
git = undefined;
|
||||
await syncGit();
|
||||
if (config.branchPrefix) {
|
||||
await setBranchPrefix(config.branchPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getRepoStatus(): Promise<StatusResult> {
|
||||
export async function getRepoStatus(): Promise<StatusResult> {
|
||||
await syncGit();
|
||||
return git.status();
|
||||
}
|
||||
|
||||
|
@ -279,6 +284,7 @@ export async function createBranch(
|
|||
branchName: string,
|
||||
sha: string
|
||||
): Promise<void> {
|
||||
await syncGit();
|
||||
logger.debug(`createBranch(${branchName})`);
|
||||
await git.reset(ResetMode.HARD);
|
||||
await git.raw(['clean', '-fd']);
|
||||
|
@ -289,6 +295,7 @@ export async function createBranch(
|
|||
}
|
||||
|
||||
export async function branchExists(branchName: string): Promise<boolean> {
|
||||
await syncGit();
|
||||
// First check cache
|
||||
if (config.branchExists[branchName] !== undefined) {
|
||||
return config.branchExists[branchName];
|
||||
|
@ -315,6 +322,7 @@ export async function branchExists(branchName: string): Promise<boolean> {
|
|||
|
||||
// Return the commit SHA for a branch
|
||||
export async function getBranchCommit(branchName: string): Promise<string> {
|
||||
await syncGit();
|
||||
if (!(await branchExists(branchName))) {
|
||||
throw Error(
|
||||
'Cannot fetch commit for branch that does not exist: ' + branchName
|
||||
|
@ -325,6 +333,7 @@ export async function getBranchCommit(branchName: string): Promise<string> {
|
|||
}
|
||||
|
||||
export async function getCommitMessages(): Promise<string[]> {
|
||||
await syncGit();
|
||||
logger.debug('getCommitMessages');
|
||||
const res = await git.log({
|
||||
n: 10,
|
||||
|
@ -334,6 +343,7 @@ export async function getCommitMessages(): Promise<string[]> {
|
|||
}
|
||||
|
||||
export async function setBranch(branchName: string): Promise<string> {
|
||||
await syncGit();
|
||||
if (!(await branchExists(branchName))) {
|
||||
throwBranchValidationError(branchName);
|
||||
}
|
||||
|
@ -365,6 +375,7 @@ export async function setBranch(branchName: string): Promise<string> {
|
|||
}
|
||||
|
||||
export async function getFileList(): Promise<string[]> {
|
||||
await syncGit();
|
||||
const branch = config.currentBranch;
|
||||
const submodules = await getSubmodules();
|
||||
const files: string = await git.raw(['ls-tree', '-r', branch]);
|
||||
|
@ -385,6 +396,7 @@ export async function getFileList(): Promise<string[]> {
|
|||
export async function getAllRenovateBranches(
|
||||
branchPrefix: string
|
||||
): Promise<string[]> {
|
||||
await syncGit();
|
||||
const branches = await git.branch(['--remotes', '--verbose']);
|
||||
return branches.all
|
||||
.map(localName)
|
||||
|
@ -392,6 +404,7 @@ export async function getAllRenovateBranches(
|
|||
}
|
||||
|
||||
export async function isBranchStale(branchName: string): Promise<boolean> {
|
||||
await syncGit();
|
||||
if (!(await branchExists(branchName))) {
|
||||
throw Error(
|
||||
'Cannot check staleness for branch that does not exist: ' + branchName
|
||||
|
@ -407,6 +420,7 @@ export async function isBranchStale(branchName: string): Promise<boolean> {
|
|||
}
|
||||
|
||||
export async function isBranchModified(branchName: string): Promise<boolean> {
|
||||
await syncGit();
|
||||
// First check cache
|
||||
if (config.branchIsModified[branchName] !== undefined) {
|
||||
return config.branchIsModified[branchName];
|
||||
|
@ -438,6 +452,7 @@ export async function isBranchModified(branchName: string): Promise<boolean> {
|
|||
}
|
||||
|
||||
export async function deleteBranch(branchName: string): Promise<void> {
|
||||
await syncGit();
|
||||
try {
|
||||
await git.raw(['push', '--delete', 'origin', branchName]);
|
||||
logger.debug({ branchName }, 'Deleted remote branch');
|
||||
|
@ -457,6 +472,7 @@ export async function deleteBranch(branchName: string): Promise<void> {
|
|||
}
|
||||
|
||||
export async function mergeBranch(branchName: string): Promise<void> {
|
||||
await syncGit();
|
||||
await git.reset(ResetMode.HARD);
|
||||
await git.checkout(['-B', branchName, 'origin/' + branchName]);
|
||||
await git.checkout(config.currentBranch);
|
||||
|
@ -468,6 +484,7 @@ export async function mergeBranch(branchName: string): Promise<void> {
|
|||
export async function getBranchLastCommitTime(
|
||||
branchName: string
|
||||
): Promise<Date> {
|
||||
await syncGit();
|
||||
try {
|
||||
const time = await git.show(['-s', '--format=%ai', 'origin/' + branchName]);
|
||||
return new Date(Date.parse(time));
|
||||
|
@ -478,6 +495,7 @@ export async function getBranchLastCommitTime(
|
|||
}
|
||||
|
||||
export async function getBranchFiles(branchName: string): Promise<string[]> {
|
||||
await syncGit();
|
||||
try {
|
||||
const diff = await git.diffSummary([branchName, config.currentBranch]);
|
||||
return diff.files.map((file) => file.file);
|
||||
|
@ -491,6 +509,7 @@ export async function getFile(
|
|||
filePath: string,
|
||||
branchName?: string
|
||||
): Promise<string | null> {
|
||||
await syncGit();
|
||||
if (branchName) {
|
||||
const exists = await branchExists(branchName);
|
||||
if (!exists) {
|
||||
|
@ -510,6 +529,7 @@ export async function getFile(
|
|||
}
|
||||
|
||||
export async function hasDiff(branchName: string): Promise<boolean> {
|
||||
await syncGit();
|
||||
try {
|
||||
return (await git.diff(['HEAD', branchName])) !== '';
|
||||
} catch (err) {
|
||||
|
@ -545,6 +565,7 @@ export async function commitFiles({
|
|||
message,
|
||||
force = false,
|
||||
}: CommitFilesConfig): Promise<string | null> {
|
||||
await syncGit();
|
||||
logger.debug(`Committing files to branch ${branchName}`);
|
||||
if (!privateKeySet) {
|
||||
await writePrivateKey(config.localDir);
|
||||
|
|
Loading…
Reference in a new issue