mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-11 22:46:27 +00:00
feat(git): Add helpers for platform-native commit (#13955)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
This commit is contained in:
parent
5ab9faf589
commit
9809ba476b
3 changed files with 85 additions and 4 deletions
|
@ -753,4 +753,29 @@ describe('util/git/index', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('pushCommitAsRef', () => {
|
||||
it('creates non-branch ref', async () => {
|
||||
const commit = git.getBranchCommit('develop');
|
||||
await git.pushCommitAsRef(commit, 'refs/foo/bar');
|
||||
const repo = Git(tmpDir.path);
|
||||
const res = (await repo.raw(['ls-remote'])).split(/\s+/);
|
||||
expect(res).toContain('refs/foo/bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('listCommitTree', () => {
|
||||
it('creates non-branch ref', async () => {
|
||||
const commit = git.getBranchCommit('develop');
|
||||
const res = await git.listCommitTree(commit);
|
||||
expect(res).toEqual([
|
||||
{
|
||||
mode: '100644',
|
||||
path: 'past_file',
|
||||
sha: '913705ab2ca79368053a476efa48aa6912d052c5',
|
||||
type: 'blob',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -40,6 +40,7 @@ import type {
|
|||
LocalConfig,
|
||||
StatusResult,
|
||||
StorageConfig,
|
||||
TreeItem,
|
||||
} from './types';
|
||||
|
||||
export { setNoVerify } from './config';
|
||||
|
@ -704,11 +705,12 @@ export async function prepareCommit({
|
|||
}: CommitFilesConfig): Promise<CommitResult | null> {
|
||||
const { localDir } = GlobalConfig.get();
|
||||
await syncGit();
|
||||
logger.debug(`Preparing files for commiting to branch ${branchName}`);
|
||||
logger.debug(`Preparing files for committing to branch ${branchName}`);
|
||||
await handleCommitAuth(localDir);
|
||||
try {
|
||||
await git.reset(ResetMode.HARD);
|
||||
await git.raw(['clean', '-fd']);
|
||||
const parentCommitSha = config.currentBranchSha;
|
||||
await git.checkout(['-B', branchName, 'origin/' + config.currentBranch]);
|
||||
const deletedFiles: string[] = [];
|
||||
const addedModifiedFiles: string[] = [];
|
||||
|
@ -787,7 +789,7 @@ export async function prepareCommit({
|
|||
{ deletedFiles, ignoredFiles, result: commitRes },
|
||||
`git commit`
|
||||
);
|
||||
const commit = commitRes?.commit || 'unknown';
|
||||
const commitSha = commitRes?.commit || 'unknown';
|
||||
if (!force && !(await hasDiff(`origin/${branchName}`))) {
|
||||
logger.debug(
|
||||
{ branchName, deletedFiles, addedModifiedFiles, ignoredFiles },
|
||||
|
@ -797,7 +799,8 @@ export async function prepareCommit({
|
|||
}
|
||||
|
||||
const result: CommitResult = {
|
||||
sha: commit,
|
||||
parentCommitSha,
|
||||
commitSha,
|
||||
files: files.filter((fileChange) => {
|
||||
if (fileChange.type === 'deletion') {
|
||||
return deletedFiles.includes(fileChange.path);
|
||||
|
@ -898,3 +901,48 @@ export function getUrl({
|
|||
pathname: repository + '.git',
|
||||
});
|
||||
}
|
||||
|
||||
export async function pushCommitAsRef(
|
||||
commitSha: string,
|
||||
refName: string
|
||||
): Promise<void> {
|
||||
await git.raw(['update-ref', refName, commitSha]);
|
||||
await git.raw(['push', '--force', 'origin', refName]);
|
||||
}
|
||||
|
||||
const treeItemRegex = regEx(
|
||||
/^(?<mode>\d{6})\s+(?<type>blob|tree)\s+(?<sha>[0-9a-f]{40})\s+(?<path>.*)$/
|
||||
);
|
||||
|
||||
const treeShaRegex = regEx(/tree\s+(?<treeSha>[0-9a-f]{40})\s*/);
|
||||
|
||||
/**
|
||||
*
|
||||
* $ git cat-file -p <commit-sha>
|
||||
*
|
||||
* > tree <tree-sha>
|
||||
* > parent 59b8b0e79319b7dc38f7a29d618628f3b44c2fd7
|
||||
* > ...
|
||||
*
|
||||
* $ git cat-file -p <tree-sha>
|
||||
*
|
||||
* > 040000 tree 389400684d1f004960addc752be13097fe85d776 .devcontainer
|
||||
* > 100644 blob 7d2edde437ad4e7bceb70dbfe70e93350d99c98b .editorconfig
|
||||
* > ...
|
||||
*
|
||||
*/
|
||||
export async function listCommitTree(commitSha: string): Promise<TreeItem[]> {
|
||||
const commitOutput = await git.raw(['cat-file', '-p', commitSha]);
|
||||
const { treeSha } = treeShaRegex.exec(commitOutput)?.groups ?? {};
|
||||
const contents = await git.raw(['cat-file', '-p', treeSha]);
|
||||
const lines = contents.split(newlineRegex);
|
||||
const result: TreeItem[] = [];
|
||||
for (const line of lines) {
|
||||
const matchGroups = treeItemRegex.exec(line)?.groups;
|
||||
if (matchGroups) {
|
||||
const { path, mode, type, sha } = matchGroups;
|
||||
result.push({ path, mode, type, sha });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -93,10 +93,18 @@ export interface SourceBranchConflict {
|
|||
}
|
||||
|
||||
export interface CommitResult {
|
||||
sha: string;
|
||||
parentCommitSha: string;
|
||||
commitSha: string;
|
||||
files: FileChange[];
|
||||
}
|
||||
|
||||
export interface TreeItem {
|
||||
path: string;
|
||||
mode: string;
|
||||
type: string;
|
||||
sha: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a git authentication rule in the form of e.g.:
|
||||
* git config --global url."https://api@github.com/".insteadOf "https://github.com/"
|
||||
|
|
Loading…
Reference in a new issue