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

Calculate and record uncommittedHash when creating a build #798

Merged
merged 6 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions node-src/git/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,29 @@ export async function getBranch() {
}
}

// Retrieve the hash of all uncommitted files, which includes staged, unstaged, and untracked files,
// excluding deleted files (which can't be hashed) and ignored files. There is no one single Git
// command to reliably get this information, so we use a combination of commands grouped together.
export async function getUncommittedHash() {
const listStagedFiles = 'git diff --name-only --diff-filter=d --cached';
const listUnstagedFiles = 'git diff --name-only --diff-filter=d';
const listUntrackedFiles = 'git ls-files --others --exclude-standard';
const listUncommittedFiles = [listStagedFiles, listUnstagedFiles, listUntrackedFiles].join(';');

const uncommittedHash = (
await execGitCommand(
// Pass the combined list of filenames to hash-object to retrieve a list of hashes. Then pass
// the list of hashes to hash-object again to retrieve a single hash of all hashes. We use
// stdin to avoid the limit on command line arguments.
`(${listUncommittedFiles}) | git hash-object --stdin-paths | git hash-object --stdin`
ghengeveld marked this conversation as resolved.
Show resolved Hide resolved
)
).trim();

// In case there are no uncommited changes (empty list), we always get this same hash.
const noChangesHash = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391';
return uncommittedHash === noChangesHash ? '' : uncommittedHash;
}

export async function hasPreviousCommit() {
const result = await execGitCommand(`git --no-pager log -n 1 --skip=1 --format="%H"`);
return !!result.trim();
Expand Down
8 changes: 6 additions & 2 deletions node-src/tasks/gitInfo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import picomatch from 'picomatch';

import getCommitAndBranch from '../git/getCommitAndBranch';
import { getSlug, getVersion } from '../git/git';
import { getSlug, getUncommittedHash, getVersion } from '../git/git';
import { getParentCommits } from '../git/getParentCommits';
import { getBaselineBuilds } from '../git/getBaselineBuilds';
import { exitCodes, setExitCode } from '../lib/setExitCode';
Expand Down Expand Up @@ -62,8 +62,12 @@ export const setGitInfo = async (ctx: Context, task: Task) => {
} = ctx.options;

ctx.git = {
version: await getVersion(),
...(await getCommitAndBranch(ctx, { branchName, patchBaseRef, ci })),
uncommittedHash: await getUncommittedHash().catch((e) => {
ctx.log.warn('Failed to retrieve uncommitted files hash', e);
return null;
}),
version: await getVersion(),
};

if (!ctx.git.slug) {
Expand Down
1 change: 1 addition & 0 deletions node-src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export interface Context {
committedAt: number;
slug?: string;
mergeCommit?: string;
uncommittedHash?: string;
parentCommits?: string[];
baselineCommits?: string[];
changedFiles?: string[];
Expand Down
Loading