gitx is a Fish shell utility for versioning files from different places on a machine into one or more git repos.
- Language: Fish shell scripts (
.fish) - Runtime: interpreted (no compile/build step)
- Repo model: bare repos under
~/.gitx/repos/<repo>/repo, work tree/ - Main commands:
gitx,gitx-init,gitx-track,gitx-untrack,gitx-commit
There is no build pipeline for binaries. Development is test/demo oriented.
# Fast pass/fail checks (recommended during development)
make test-presenter-contracts
# Targeted suites
make test-passthrough-presenter-contracts
make test-usage-gitx-presenter-contracts
# Full run (very verbose: demos + contracts)
make test-all-presenters
# Visual/demo output only
make demo-presenters
make demo-init-presenter
make demo-track-presenter
make demo-untrack-presenter
make demo-commit-presenter
make demo-passthrough-presenter
make demo-problem-presenter
make demo-usage-presentermake test-passthrough-presenter-contracts: Runs only passthrough presenter contract assertions.make test-usage-gitx-presenter-contracts: Runs only usage presenter contract assertions.make test-presenter-contracts: Runs both contract suites; use as the default fast gate.make test-all-presenters: Runs demos plus contract suites; use for end-to-end confidence when presenter output changes.- Rule of thumb: run targeted suite(s) first, then
make test-presenter-contracts, and only runmake test-all-presenterswhen broad output/presenter behavior changed.
The project does not use a unit-test framework runner. Run one assertion directly with fish + rg.
fish -c 'source functions/__gitx_present_passthrough.fish; __gitx_present_passthrough' 2>&1 \
| rg -F "Error: __gitx_present_passthrough requires at least 1 argument"- If
rgfinds the expected text: exit code0(pass) - If it does not: exit code
1(fail)
make test-all-presentersis intentionally noisy because it includes all demo presenters.- Contract tests are strict assertions (
rg -F ... || exit 1) and fail the target on mismatch. - Success markers at the end:
✓ All passthrough presenter contract tests passed✓ All usage gitx presenter contract tests passed✓ All tests passed successfully
- On failure,
makeprintsError 1and exits non-zero.
- Main command files:
functions/gitx*.fish - Presenter files:
functions/__gitx_present_<name>.fish - Completion files:
completions/<command>.fish - Function names mirror command names or presenter filenames.
- Prefer descriptive snake_case names (
repo_name,dry_run,items_count). - Use
set -lfor local scope by default. - Keep related names grouped (
repo_*,success_*, etc.).
- Validate arity early with
count $argv. - Assign validated args to named locals immediately.
- Use early
return 1for invalid input paths.
- Use
commandprefix for external tools to avoid function recursion. - Capture status immediately after command execution:
command <cmd>set -l rc $status
- Send errors to stderr using
echo "Error: ..." >&2.
- Presenters own user-facing output.
- Use
set_color+ reset withset_color normal. - Color conventions:
green: successcyan: informational/usage/next stepsbrblack: dry-run outputred: errors/problems
- Symbol conventions:
✓success◉dry-run indicator✗failure
-
Keep function
--descriptionand completion-dtext aligned in intent. -
Use user-goal wording (what command does) over internal implementation details.
-
Current command descriptions:
gitx: Run git commands against a gitx repo or all of them at oncegitx-init: Create a new gitx repo that can track files from anywhere on your systemgitx-track: Add files to a gitx repo so they start being trackedgitx-untrack: Stop tracking files from a gitx repogitx-commit: Commit files changed - if any - with an optional message
-
Current dry-run descriptions:
gitx-init --dry-run: Preview what would happen without making changesgitx-track --dry-run: Preview which files would be trackedgitx-untrack --dry-run: Preview which files would stop being trackedgitx-commit --dry-run: Preview what would be committed
- Validate argument count at function start.
- Use
--descriptionon all functions. - Quote variable expansions (
"$repo","$argv[1]"). - Prefer
testfor conditionals (test $dry_run -eq 1). - Keep presenter output consistent with existing visual style.
functions/
gitx.fish
gitx-init.fish
gitx-track.fish
gitx-untrack.fish
gitx-commit.fish
__gitx_present_*.fish
completions/
*.fish
Makefile
README.md
- No
.cursor/rules/directory found. - No
.cursorrulesfile found. - No
.github/copilot-instructions.mdfile found.
- Keep commits focused; avoid unrelated refactors.
- Do not commit generated artifacts (logs, caches, temp files,
.venv, local env files, demo output captures) unless explicitly requested. - Treat presenter/output wording changes as user-facing changes; keep them isolated from logic changes when possible.
- Before pushing, run relevant test gates for touched areas:
- Minimum:
make test-presenter-contracts - If presenter output changed: run targeted suite(s) and consider
make test-all-presentersfor end-to-end confidence.
- Minimum:
- Never commit directly to
main. - Always create a feature/fix branch before committing (for example:
feat/...,fix/...,chore/...). - Push the branch and open a PR for every code change.
- Treat PR creation as the review gate; do not merge before review feedback.
- After review, address comments with follow-up commits on the same branch.
- Re-run relevant tests after each review-driven update before pushing again.
- Always follow explicit instructions left by the user/repo owner on code review comments.
- Double-check reviewer claims before implementing: verify with docs and/or local reproduction first.
- Never blindly apply reviewer suggestions; if a claim is incorrect, explain why in the PR discussion and keep behavior correct.
- No traditional linting tool is configured.
- No enforced formatter is configured (optional:
fish_indent). --dry-runshould be supported for all mutating commands.- Favor small, behavior-preserving changes unless explicitly asked otherwise.