Skip to content

Repository files navigation

git-fi

A git plugin that maintains a temporary integration branch named fi. Merge multiple in-progress feature branches together to detect conflicts early and test features in collaboration — before they land on main.

Documentation & install | Specification

This README is for working on git-fi itself. To install and use it, see the documentation site.

Local development

Requires Node.js >= 18 and git >= 2.13.0.

The git floor tracks the newest git feature the code calls rather than a support policy. Today that feature is git branch -r --format=, which backs the batched branch listing (PRF-01) and which git gained in 2.13.0; every other invocation is older. Reaching for a newer git feature means raising the floor in PF-02 and src/git.ts together, and naming the feature that moved it so the next person doesn't have to re-derive the number.

git clone https://github.com/gettyimages/git-fi.git
cd git-fi
npm install                 # dev dependencies (tsx, typescript)

Day-to-day, git-fi runs straight from source — no global install needed:

npm start -- --help         # run src/ directly via tsx
npm run build               # compile TypeScript to dist/
npm test                    # build, then run the integration suite

npm test is the primary feedback loop: it drives the compiled binary against throwaway git repositories (a bare origin plus a working clone), exercising real git fetch/merge/push behavior end-to-end.

The implementation follows SPEC.md, which defines every requirement with a unique ID and includes mermaid diagrams for the major flows.

Trying your local build

To run the checkout as git fi in other repositories for a while:

npm run trial:on            # build, npm link, load this copy's completion
npm run trial:off           # unlink, restore the published version

trial:on symlinks the checkout onto your PATH, so later npm run builds take effect without reinstalling. It also runs install-completions --write .trial/completions and appends a marked block to ~/.zshrc that puts that directory on your fpath — the same command, writing the same two files, that a user installs with (CMP-06), so a trial exercises the shipped install path rather than a shortcut around it. Only ~/.zshrc is touched; under bash you get the linked binary and wire the completion yourself. trial:off deletes the block and .trial/, then reinstalls @gettyimages/git-fi from npm. Open a new terminal after either one.

If git fi runs something other than what you expect, which -a git-fi lists every git-fi on your PATH in resolution order.

The published package — npm install -g @gettyimages/git-fi, documented on the docs site — is the official install for end users. Reach for it here mainly to test the distribution itself; local development runs from source.

Project Structure

SPEC.md        Behavioral specification
STATUS.md      Requirement coverage
src/           TypeScript implementation
test/          Integration suite (Node test runner)
docs/          Docsify documentation site
scripts/       Build-time generators, the npm postinstall, the trial:on/off helper
man/           Generated man page (git-fi.1)
completions/   Generated bash + zsh completions (_git-fi, _git_fi, git-fi.bash)

The man page and shell completions are generated by scripts/gen-docs.ts, which draws the flag list from src/help.ts — the single source of truth for git-fi's flags. The completion logic itself lives in real shell files under scripts/completion/ (*.tmpl); the generator injects the flag list and stamps a banner. npm run build regenerates the outputs (via npm run gen:docs); those under man/ and completions/ are committed, so edit src/help.ts (flags) or scripts/completion/*.tmpl (completion logic) and rebuild rather than editing the generated files by hand. npm test and CI both run npm run verify:generated, which fails naming any committed artifact that no longer matches what the generator would write, so stale generated files surface before review rather than during it.

Three completion files ship because git fi is dispatched by two different providers: _git-fi drives zsh's built-in _git; git-fi.bash (defining _git_fi, git-completion style) drives git's own completion wrapper in bash; and _git_fi is the same _git_fi body on the zsh fpath, for git's wrapper under zsh. The git-native body (git-fi.bash.tmpl) is shared by the last two, so they can't drift. Each file has an install-completions target that prints it — bash, zsh, zsh-git respectively — and --write <dir> installs the zsh pair onto an fpath directory (CMP-06); adding a file here means adding its target in src/install-completions.ts.

A global npm install copies the zsh pair into <npm prefix>/share/zsh/site-functions from scripts/postinstall.mjs (CMP-07), so completion works with no extra step on the setups that carry that directory on their fpath. It's plain .mjs and lists the two filenames itself because npm runs postinstall before prepare, so dist/ doesn't exist yet on a fresh clone; a test pins its file list to what --write installs. It exits 0 on any failure — a non-zero postinstall fails npm install -g outright — and does nothing for a local install.

Contributing

Bug reports and pull requests are welcome on GitHub.

License

MIT — Copyright (c) 2017-2026 Getty Images.