Git operation state matrix: twenty measured cases

Dataset Last tested 26 October 2026

A Git command’s effect depends on the repository state it starts from. This matrix records twenty independent Git 2.56.0 cases so you can compare changes to the current commit, staging area, working files and saved stashes. Use a matching case as evidence about that example, then inspect your own starting state before choosing a command.

Read the state changes together

The table summarizes changes between each case’s recorded before and after states. “Changed” means the two recorded identifiers or hashes differ; it is not a judgment that the result is better or worse. The stash column shows the count before and after. A passed check means the case met its declared expectations, including preservation checks where relevant.

For example, the soft-reset case changes the current commit while preserving the recorded staged and working content. The mixed-reset case starts from its own clean repository and produces a different staged state. Those results make the modes’ separate effects visible without treating the word “reset” as a complete description of the operation1.

Twenty measured cases

Every case used Git 2.56.0, independently initialized fictional data and fixed commit timestamps in UTC. Actual observation timestamps are retained per record. The table’s command links open the corresponding version-pinned official documentation; they do not run a command.

CaseOperationHEADIndexFilesStashesExitChecks
R01Undo a local commit; keep stagingchangedsamesame0 → 00Pass
R02Undo a local commit; keep unstaged editschangedchangedsame0 → 00Pass
R03Unstage a tracked filesamechangedsame0 → 00Pass
R04Discard a tracked working editsamesamechanged0 → 00Pass
R05Create a branch at the current commitsamesamesame0 → 00Pass
R06Switch to an existing branchsamesamesame0 → 00Pass
R07Rename the current local branchsamesamesame0 → 00Pass
R08Reverse the latest linear commitchangedchangedchanged0 → 00Pass
R09Stash a tracked editsamechangedchanged0 → 10Pass
R10Stash an untracked file and tracked editsamesamechanged0 → 10Pass
R11Apply a stash and retain the entrysamesamechanged1 → 10Pass
R12Pop a stash successfullysamesamechanged1 → 00Pass
R13Inspect staged changessamesamesame0 → 00Pass
R14Inspect unstaged changessamesamesame0 → 00Pass
R15Inspect one file’s historysamesamesame0 → 00Pass
R16Recover a recent branch tipsamesamesame0 → 00Pass
R17Stop tracking a file; keep its contentssamechangedsame0 → 00Pass
R18Abort a conflicted mergesamechangedchanged0 → 00Pass
R19Abort a conflicted rebasechangedchangedchanged0 → 00Pass
R20Add an existing branch in a worktreesamesamesame0 → 00Pass

“Same” and “changed” compare the recorded values only. “Pass” covers the case’s explicit checks, not every possible effect of the command.

Download the complete record

The canonical JSON carries the complete before and after states, assertions, source URLs and observation dates. The CSV export is a derivative view with protected text cells. Read the method and source ledger with either file.

The summaries cannot replace those records. A command may leave HEAD unchanged while changing staging or working files. Another may change a branch name without changing the commit. Reading several fields together is the point of the matrix: it prevents a single unchanged value from becoming a claim that nothing happened.

What the hashes represent

The index hash summarizes its logical staged entries, rather than filesystem timestamps inside the index file. The working-content hash summarizes a mapping from repository-relative paths to file-content hashes. Separate file hashes and index entries are retained so a reader can inspect which content contributes to a difference.

The current commit identifier answers a different question. It identifies the commit checked out in that case, rather than all existing references or all recoverable objects. The branch field records the current branch, and status distinguishes staged, working and untracked changes. These fields are complementary observations; none is a universal summary of repository health.

The two diff cases are intentionally read-only comparisons. Their assertions check output and unchanged recorded state. The ordinary and staged forms compare different endpoints2. Their usefulness comes from showing the requested difference without silently staging or committing it, which is also demonstrated in the worked diff comparison.

Reproduce a case before generalizing

The case instructions explain how to run the original scripts with the pinned Git version. Each case is initialized independently, with a fictional author and fixed commit dates. Reproduction should compare the meaningful state and assertions, rather than assume that unrelated environment output proves or disproves the outcome.

The worktree case needs particular care in interpretation. Adding another working directory can leave the original directory’s state unchanged while creating a useful new checkout elsewhere. The added worktree has separate checked-out state and staging, while repository history is shared3. The worktree guide exercises that separation and the guards around checkout and removal.

A recovery row is similarly narrow. It preserves a recent unique commit and recovers its reference in a controlled repository. It is not evidence that a deleted object, an expired log or an uncommitted file can always be recovered. Read the case’s starting state and checks before treating its outcome as relevant to a different situation.

Use the matrix with the task guides

Start with the command explorer to identify the state change you need. Then use the guide for the operation and compare its setup with the corresponding records here. If your case introduces an untested condition, such as a remote operation or a different history shape, treat that as a reason for further investigation rather than silently extending the result.

The original observation data is licensed under CC BY 4.0. The original case scripts are MIT licensed. Updates should identify the Git version and rerun the independent cases; changing a description without rerunning a changed example would not create new measurement evidence.

Not covered on this page

Sources

  1. git-reset — Git 2.56.0. ↩

  2. git-diff — Git 2.56.0. ↩

  3. git-worktree — Git 2.56.0. ↩

How we test: methodology. Found a mistake? Corrections.