Skip to content

feat(cli): --changed to run only the tests touched since a git ref #1010

Closed

Description

@Chemaclass

Problem

On a large suite, the fastest feedback loop is "run only what my branch touched", and bashunit cannot express it. Today the options are --rerun-failed (needs a previous failing run) or a hand-rolled git diff | xargs ./bashunit, which breaks on renames, deletions and quoting.

src/helper/git.sh exists but only holds get_latest_tag, so there is no git plumbing to build on yet.

Proposal

--changed [<ref>]     Run only test files changed since <ref> (default: origin/HEAD, then HEAD)

Selection set:

  1. Test files added or modified in git diff --name-only --diff-filter=d <ref>...HEAD, plus uncommitted changes in the working tree and index.
  2. Filtered to files that match the test-file pattern and live under the given path argument.

Deleted test files are dropped (--diff-filter=d). Behaviour when not inside a git work tree, or when <ref> does not resolve: exit non-zero with a clear message rather than silently running everything (#871 class of bug).

Explicitly out of scope for this issue: mapping source changes to the tests that cover them. That needs a @covers-style annotation and should be its own issue if wanted.

Where to change

  • src/helper/git.sh — add bashunit::helper::git::changed_files and bashunit::helper::git::is_repo.
  • src/helper/discovery.sh:208 load_test_files — intersect discovery with the changed set.
  • src/main/test.sh, src/config/env.sh (BASHUNIT_CHANGED), .env.example.

Acceptance criteria

  • --changed with no argument diffs against origin/HEAD when it resolves, otherwise HEAD
  • --changed main diffs against main
  • Uncommitted and staged modifications to a test file are included
  • Deleted test files are excluded (no "file not found" error)
  • Renamed test files select the new path only
  • Combines with --filter / --tag (intersection)
  • Outside a git work tree: non-zero exit with an explicit message, not a full run
  • An unresolvable ref: non-zero exit with the ref quoted in the message
  • No changed test files: "No tests found" path, current exit code preserved
  • Acceptance test builds a throwaway git repo in a temp dir (bashunit::temp_dir), not the bashunit repo itself

Repo checklist (agent)

  • TDD: RED → GREEN → REFACTOR. Write the failing test first.
  • Bash 3.0+ only: no printf -v, no += append, no declare -A, no [[ ]], no ${var,,}, no &>>, no ${arr[-1]}. Expanding a possibly-empty array under set -u needs ${arr[@]+"${arr[@]}"}.
  • A new CLI flag must be wired in all of these or a parity test fails:
  • Gates: make sa, make lint, ./bashunit tests/, ./bashunit --parallel tests/. Never run shfmt -w.
  • Docs: update docs/command-line.md. Editing docs/assertions.md invalidates the bashunit doc acceptance snapshot — regenerate it.
  • CHANGELOG.md: add one line under ## Unreleased.
  • Fixtures under tests/acceptance/fixtures/ must not end in *test.sh.
  • One issue = one PR.

Activity

  1. self-assigned this
    on Aug 10, 2026
  2. Chemaclass commented on Aug 10, 2026

    @Chemaclass
    MemberAuthor

    Done in #1038 (merged).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions