Skip to content

Scenarios Overview

The library ships 27 curated scenarios across 6 kinds. Each produces a deterministic git repo state — same setup, same result, every time.

By kind

Branch (13 scenarios)

NameWhat you get
empty-repoFreshly-initialized repo: no commits, no files, no remotes. HEAD on main but unborn.
feature-pr-readyfeat/widget-v2 4 commits ahead of main, clean worktree.
feature-branch-one-commitmain + feat/x (1 commit ahead).
multi-commit-branchfeat/dashboard with 8 varied commits.
two-commit-featureBaseline + a feat commit on main, clean worktree.
branch-tracking-upstreammain tracks origin/main, both at same commit.
branch-ahead-of-upstreammain is 3 commits ahead of origin/main.
branch-behind-upstreammain is 3 commits behind origin/main.
branch-divergedmain is 2 ahead AND 2 behind origin/main.
multi-remote-with-trackingFork-workflow: origin + upstream remotes with tracking.
branch-sync-showcaseFive branches in five different sync states.
detached-headHEAD detached at main~2.
signed-commits-requiredcommit.gpgsign=true + user.signingkey set.

Operation (5 scenarios)

NameWhat you get
mid-bisect20 commits + active git bisect, HEAD at midpoint.
mid-merge-conflictIn-progress merge with 1 conflict on src/widget.ts.
mid-rebase-conflictIn-progress rebase with 1 conflict on src/config.ts.
mid-cherry-pick-conflictIn-progress cherry-pick with 1 conflict on src/utils.ts.
mid-revert-conflictIn-progress revert with 1 conflict on src/service.ts.

History (4 scenarios)

NameWhat you get
rich-history-graph20+ commits, 2 --no-ff merges, 1 unmerged branch.
chip-rendering-showcase6 commits with different ref-chip kinds (HEAD, local, remote, tag).
shallow-clone10 commits but only 4 reachable (.git/shallow set).
large-repo115 commits across 3 branches with 3 tags.

Worktree (3 scenarios)

NameWhat you get
single-staged-fileBaseline + 1 staged README.
dirty-many-files12 staged + 6 unstaged + 3 untracked files.
multiple-worktreesPrimary worktree + 3 linked worktrees.

Stash (1 scenario)

NameWhat you get
stashed-changesClean main + 3 stashes (LIFO ordered).

Submodule (1 scenario)

NameWhat you get
submodule-with-historyParent + vendor/lib submodule (4 commits, branch = main).

Using scenarios

// One-shot
const repo = await spinUpScenario('mid-merge-conflict')
// With extra steps
const repo = await fromScenario('feature-pr-ready',
addCommit({ message: 'extra', files: { 'x.ts': 'x\n' } }),
)
// Via Jest adapter
describeWithScenario('mid-merge-conflict', (getRepo) => {
it('has conflicts', async () => {
const repo = getRepo()
const status = await repo.git.status()
expect(status.conflicted.length).toBeGreaterThan(0)
})
})

Filtering by tag

Some scenarios carry tags for finer-grained filtering:

import { findScenariosByTag } from '@gfargo/git-scenarios'
// All conflict scenarios
const conflicts = findScenariosByTag(['conflict'])
// → mid-merge-conflict, mid-rebase-conflict, mid-cherry-pick-conflict, mid-revert-conflict