Skip to content

Feature - add emptyTreeCommit #1036

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 4 additions & 0 deletions .changeset/blank-club-mauve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
'simple-git': minor
---
Create new interface `git.emptyTreeCommit` to obtain the commit hash for the repo prior to the first commit.
3 changes: 2 additions & 1 deletion simple-git/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,11 @@ in v2 (deprecation notices were logged to `stdout` as `console.warn` in v2).
- `.grep(searchTerm)` searches for a single search term across all files in the working tree, optionally passing a standard [options](#how-to-specify-options) object of additional arguments
- `.grep(grepQueryBuilder(...))` use the `grepQueryBuilder` to create a complex query to search for, optionally passing a standard [options](#how-to-specify-options) object of additional arguments

## git hash-object
## git hash-object / hash properties

- `.hashObject(filePath, write = false)` computes the object ID value for the contents of the named file (which can be
outside of the work tree), optionally writing the resulting value to the object database.
- `.emptyTreeCommit()` gets the commit hash for the repo in its initial empty state before the `git.firstCommit` was applied, useful for computing the insert-only initial commit with `git.diffSummary`.

## git init

Expand Down
2 changes: 2 additions & 0 deletions simple-git/src/lib/simple-git-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import checkout from './tasks/checkout';
import countObjects from './tasks/count-objects';
import commit from './tasks/commit';
import config from './tasks/config';
import emptyTreeCommit from './tasks/empty-tree-commit';
import firstCommit from './tasks/first-commit';
import grep from './tasks/grep';
import { hashObjectTask } from './tasks/hash-object';
Expand Down Expand Up @@ -147,6 +148,7 @@ Object.assign(
commit(),
config(),
countObjects(),
emptyTreeCommit(),
firstCommit(),
grep(),
log(),
Expand Down
15 changes: 15 additions & 0 deletions simple-git/src/lib/tasks/empty-tree-commit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Response, SimpleGit } from '../../../typings';
import { SimpleGitApi } from '../simple-git-api';
import { trailingFunctionArgument } from '../utils';
import { straightThroughStringTask } from './task';

export default function (): Pick<SimpleGit, 'emptyTreeCommit'> {
return {
emptyTreeCommit(this: SimpleGitApi): Response<string> {
return this._runTask(
straightThroughStringTask(['hash-object', '-t', 'tree', '/dev/null'], true),
trailingFunctionArgument(arguments)
);
},
};
}
35 changes: 35 additions & 0 deletions simple-git/test/integration/diff-summary.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { like, newSimpleGit } from '@simple-git/test-utils';

describe('diffSummary', () => {
it('empty tree to first commit', async () => {
const git = newSimpleGit();
const emptyCommit = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
const firstCommit = await git.firstCommit();

const task = git.diffSummary([emptyCommit, firstCommit]);
const result = await task;

console.log(
(await git.raw('diff', '--stat=4096', emptyCommit, firstCommit)).replace(/\s/g, '#')
);
console.log(JSON.stringify(result, null, 2));

expect(result.changed).toBeGreaterThan(0);
expect(result.changed).toBe(result.files.length);
expect(result.insertions).toBeGreaterThan(0);
expect(result.deletions).toBe(0);
result.files.forEach((file) => {
if (file.binary) {
throw new Error(`Test assumes no binary files in first commit`);
}

expect(file.insertions).toBe(file.changes);
expect(file).toEqual(
like({
changes: file.insertions,
deletions: 0,
})
);
});
});
});
13 changes: 13 additions & 0 deletions simple-git/test/integration/empty-tree-commit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createTestContext } from '@simple-git/test-utils';

const EMPTY_SHA = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
const EMPTY_SHA_256 = '6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321';

describe('empty-tree-commit', () => {
it('gets the empty tree commit', async () => {
const context = await createTestContext();
const commit = await context.git.emptyTreeCommit();

expect(commit === EMPTY_SHA || commit === EMPTY_SHA_256).toBe(true);
});
});
5 changes: 5 additions & 0 deletions simple-git/typings/simple-git.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,11 @@ export interface SimpleGit extends SimpleGitBase {

diffSummary(callback?: types.SimpleGitTaskCallback<resp.DiffResult>): Response<resp.DiffResult>;

/**
* Gets the commit hash of the initial empty repo commit, immediately prior to the first commit in the repo
*/
emptyTreeCommit(callback?: types.SimpleGitTaskCallback<string>): Response<string>;

/**
* Sets an environment variable for the spawned child process, either supply both a name and value as strings or
* a single object to entirely replace the current environment variables.
Expand Down
Loading