@jameslnewell/git-diff
v0.4.1
Published
Utilities for obtaining the git diff status of files in a repository.
Readme
@jameslnewell/git-diff
Utilities for obtaining the git diff status of files in a repository.
Installation
npm install @jameslnewell/git-diffUsage
Diff Options
cwd?: stringThe current working directorybase?: stringThe base commit or branch to compare fromhead?: stringThe head commit or branch to compare to
Async
import * as Diff from '@jameslnewell/git-diff';
const diff = await Diff.diffAsync({
base: 'main',
head: 'feature-branch',
});
if (Diff.added(diff, 'prisma/*') || Diff.modified(diff, 'prisma/*')) {
// do something
// e.g. prisma generate && prisma migrate
}Sync
import * as Diff from '@jameslnewell/git-diff';
const diff = Diff.diffSync({
base: 'main',
head: 'feature-branch',
});
if (Diff.added(diff, 'prisma/*') || Diff.modified(diff, 'prisma/*')) {
// do something
}Predicates
Each predicate returns true when at least one path matches. The optional second argument is a path or glob (or array of either) to scope the check.
Diff.any(diff, paths?)— any file at allDiff.added(diff, paths?)Diff.changed(diff, paths?)Diff.deleted(diff, paths?)Diff.modified(diff, paths?)Diff.renamed(diff, paths?)Diff.unknown(diff, paths?)
if (Diff.added(diff)) {
/* any added */
}
if (Diff.added(diff, 'src/**')) {
/* any added under src/ */
}
if (Diff.any(diff, ['prisma/*', 'src/db/**'])) {
/* anything touched */
}Filters and views
Diff.filterByPaths(diff, paths)— returns a newDiffcontaining only entries whose path matches one of the globs (array required).Diff.filterByStatuses(diff, statuses)— returns a newDiffcontaining only entries with one of the given statuses (array required).Diff.paths(diff)— returns the paths as an array.Diff.statuses(diff)— returns the statuses as an array.
Compose to build more specific queries:
import * as Diff from '@jameslnewell/git-diff';
// All added file paths under src/
const newSourceFiles = Diff.paths(
Diff.filterByPaths(Diff.filterByStatuses(diff, [Diff.Status.Added]), [
'src/**',
]),
);Faking a diff in tests
Diff is just Record<Path, Status>, so a test fixture is a plain object literal:
import {added, Status, type Diff} from '@jameslnewell/git-diff';
const diff: Diff = {
'src/main.ts': Status.Added,
};
added(diff, 'src/**'); // trueHandling a non-existent base
A common use case is diffing against a mutable tag on CI/CD.
import * as Diff from '@jameslnewell/git-diff';
const diff = await Diff.diffAsync({
base: 'last-deployment',
head: 'HEAD',
});On the initial CI/CD run the mutable tag may not yet exist and git diff will error.
In order to handle this case its recommended you diff against the first commit instead.
import * as Diff from '@jameslnewell/git-diff';
const base = 'last-deployment';
const head = 'HEAD';
let diff: Diff.Diff;
try {
diff = await Diff.diffAsync({base, head});
} catch (error) {
if (Diff.isBadRevisionError(error)) {
diff = await Diff.diffAsync({
base: await Diff.firstCommitAsync({ref: head}),
head,
});
} else {
throw error;
}
}License
MIT
