# wfxr/forgit: fzf-powered interactive git commands for Bash, Zsh and Fish

> forgit wraps everyday git operations in fzf pickers, turning file staging, branch switching and stash handling into selection menus. It is a shell plugin, not a TUI, and the README documents the full command list.

**wfxr/forgit** — :zzz: A utility tool powered by fzf for using git interactively.

- Repository: https://github.com/wfxr/forgit
- Stars: 5,085 · Forks: 167
- Language: Shell
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/wfxr-forgit

## What forgit changes about typing git commands

Most git mistakes at the command line come from naming the wrong thing. You type a branch name from memory, or a path you half-remember, and git does what you said. forgit replaces the naming step with a picker: it feeds candidate branches, files, commits or stashes into fzf and applies the git command to whatever you select.

The audience is narrow and specific. You need fzf installed, a POSIX-style shell (the README lists Bash, Zsh and Fish), and a working preference for the keyboard over a mouse. The README describes the tool as lightweight and easy to use, and the implementation matches that description: the repository's top level holds shell plugin files (forgit.plugin.sh, forgit.plugin.zsh), a bin/ directory, completions/, conf.d/ and tests/. There is no compiled binary to build and no daemon.

The command list is the substance. ga is an interactive git add selector, gd views diffs, glo browses the log, gsw switches branches, gss shows stashes, gbl picks a file to blame, and gclean drives git clean. Each name is short because it is meant to be typed constantly. The README's table runs to roughly thirty commands, covering worktrees (gwt, gwa, gwd), fixup and squash flows (gfu, gsq, grw), and reflog viewing (grl).

## How the fzf picker sits between you and git

forgit does not reimplement git. The mechanism visible in the README is a wrapper: a shell function for each command gathers the relevant git output, pipes it into fzf, and then runs the underlying git command against the chosen line. That is why the command list reads like a mapping onto git subcommands rather than a new vocabulary.

The architecture follows from that. There is one entry point per operation, so nothing is shared between them except fzf itself and the shell's function namespace. Two consequences matter. First, the tool inherits git's own behaviour exactly, including its error messages and its safety rules, because git is what actually runs. Second, forgit's own surface area is small enough to audit by reading shell scripts, which is a reasonable thing to do before sourcing anything into your rc file.

The README also shows a second front end: completions for git forgit and configured git aliases, shipped as completions/git-forgit.bash and completions/git-forgit.fish. So the same operations can be reached as git subcommands rather than shell functions. Fish users get tab completion for git forgit and for configured aliases; Bash users can either drop the completion file into ~/.local/share/bash-completion/completions or source it explicitly, and the README distinguishes the two cases: the first gives completion for git forgit and aliases, the second adds completion for the shell functions and aliases such as gsw.

## Installing forgit with Homebrew and running a first ga

forgit's README gives several install paths: shell package managers (zplug, zgen, antigen, fisher, omf, zinit, oh-my-zsh, sheldon), Homebrew, the AUR, or cloning the repository and sourcing it manually. The one requirement stated up front is fzf version 0.60.0 or higher. The README warns that if your OS package manager bundles an older fzf, you may need fzf's own install script instead.

Homebrew installs the package, but you still have to source the plugin for your shell. These are the lines the README gives, one per shell:

```bash
# Fish:
# ~/.config/fish/config.fish:
[ -f $HOMEBREW_PREFIX/share/forgit/forgit.plugin.fish ]; and source $HOMEBREW_PREFIX/share/forgit/forgit.plugin.fish

# Zsh:
# ~/.zshrc:
[ -f $HOMEBREW_PREFIX/share/forgit/forgit.plugin.zsh ] && source $HOMEBREW_PREFIX/share/forgit/forgit.plugin.zsh

# Bash:
# ~/.bashrc:
[ -f $HOMEBREW_PREFIX/share/forgit/forgit.plugin.sh ] && source $HOMEBREW_PREFIX/share/forgit/forgit.plugin.sh
```

After restarting the shell, the functions should exist. A first real use is staging part of a messy working tree. Run ga in a repository with several changed files:

```bash
cd ~/code/some-project
ga
```

According to the README, ga is an interactive git add selector, so you should see an fzf list of changed files rather than a prompt. Selecting entries stages them. The same pattern holds for the rest of the list: gd to view a diff, glo to browse the log, gsw to switch branches. If you prefer the git subcommand form, the completions files support git forgit, and the README notes that the AUR package and the Homebrew formula configure completions automatically while other install methods require the manual step described above.

## Where forgit stops being the right tool

The dependency on fzf 0.60.0 or higher is the first hard boundary. On a machine where you cannot upgrade fzf, for example a locked-down build host with an old distribution package, forgit will not work as documented, and the README's suggested remedy is to install fzf through its own script rather than the package manager. That is a real constraint on shared or managed machines.

The second limitation is structural. forgit is a set of one-shot pickers, not a persistent interface. Every command starts an fzf process, you choose, and you are back at the shell prompt. There is no continuous view of the repository, no way to move between staging and history without re-invoking a command, and no state carried across invocations. If your mental model of git work is a dashboard you keep open, forgit will feel like a series of interruptions.

Third, the README does not document rollback or undo behaviour for the destructive commands in the list. gclean drives git clean, gbd drives git branch -D, and grh drives git reset HEAD. Those are the operations where an accidental selection costs work. The README describes what each command does and does not describe a confirmation step or a recovery path, so the safety of a mis-selection is whatever the underlying git command does. Treat the picker as a faster way to type the same command, not as a guard against typing the wrong one.

Finally, the scope is deliberately bounded. forgit wraps git; it does not add a merge conflict editor, a staging-area model of its own, or anything resembling a diff-review workflow. For those you need a different class of tool.

## Lazygit compared with forgit's picker model

The obvious alternative is Lazygit, and the difference is architectural rather than cosmetic. Lazygit is a standalone terminal application with its own persistent interface: you launch it, it takes over the terminal, and you move between panels for status, branches, commits and stashes without returning to the shell. forgit is a plugin that lives inside your existing shell session and produces one fzf selection at a time.

That distinction decides most adoption questions. Lazygit needs to be installed as its own program and entered and exited as a mode; forgit needs fzf and a sourced shell file, and it composes with whatever else is in your rc file. If your work is a long sequence of git operations in one repository, Lazygit's persistent view avoids the repeated startup cost and keeps context on screen. If your git use is sporadic and interleaved with other shell work, forgit's model avoids the mode switch entirely.

There is a second, quieter difference. forgit's commands map one-to-one onto git subcommands, so what you learn transfers directly back to plain git and to scripts. A custom interface with its own keybindings and its own vocabulary does not transfer the same way. That matters if you work across machines where you cannot install a new binary but can source a shell file.

Neither tool is a superset of the other. Choosing between them is mostly a question of whether you want git operations to be a place you go, or a thing you do.

## Maintenance, releases and what the MIT licence means here

The repository is not archived and the last push was on 2026-09-17, six days before this writing. Releases are frequent and versioned by date: 26.09.1 on 2026-09-09, 26.09.0 on 2026-09-01, 26.08.0 on 2026-08-01. That cadence tells you the project is being tagged regularly, and it also tells you something about upgrade cost: because the version string encodes the month, you can see at a glance how far behind a pinned install is.

Upgrading depends on how you installed it. Homebrew and the AUR packages are updated by their package managers, with the AUR offering both forgit for the latest release and forgit-git to track the default branch. The shell package managers pull from the repository, and the README's sheldon example pins a revision explicitly:

```toml
[plugins.forgit]
github = "wfxr/forgit"
rev = "26.01.0"  # check https://github.com/wfxr/forgit/releases for latest version
use = ["forgit.plugin.zsh"]
apply = ["source"]
```

That pinned rev is the upgrade cost in concrete form: nothing moves until you change the string. If you clone the repository manually, you are tracking the default branch and get changes on your next pull, which is the opposite trade-off. The README does not describe a migration process between releases, so a pinned install should be bumped deliberately and tested in the shell you actually use.

The licence is MIT, referenced in the README badge and the LICENSE file at the repository root. In practical terms that permits reuse and redistribution with the licence text retained, but the specifics of your situation, including attribution in a bundled internal tool, are a question for your own legal review rather than something this article can settle.

## Conclusion

forgit suits shell users who already run fzf and want git's file-level and branch-level operations to become selection menus without leaving the terminal. It is the wrong choice if you want a persistent full-screen git UI with panes and mouse support, since forgit runs one fzf invocation per command and returns you to the prompt. Before adopting, confirm your fzf is version 0.60.0 or higher, since the README states older versions bundled by OS package managers may not work, and check whether your install method configures completions automatically or needs the manual step.

## FAQ

### What fzf version does forgit require?

The README states fzf version 0.60.0 or higher. It also warns that if your OS package manager bundles an older version, you might need to install fzf using its own install script.

### Which shells does forgit support?

The README lists Bash, Zsh and Fish, and the repository ships forgit.plugin.sh, forgit.plugin.zsh and forgit.plugin.fish plus completion files for Bash and Fish. Homebrew installs require you to source the matching plugin file in your shell's config.

### Do I need to configure completions for forgit manually?

Only for some install methods. The README says completions are configured automatically when installing through Homebrew or the AUR, while all other methods require manual setup, such as placing completions/git-forgit.bash in ~/.local/share/bash-completion/completions.

### How do I install forgit on Arch Linux?

The README points to AUR packages maintained by the developers: forgit for the latest release, or forgit-git to track the latest commits from the default branch. Completions are configured automatically with either.

## Sources

- [Issues](https://github.com/wfxr/forgit/issues)
- [License: MIT](https://github.com/wfxr/forgit/blob/main/LICENSE)
- [README](https://github.com/wfxr/forgit/blob/main/README.md)
- [Releases](https://github.com/wfxr/forgit/releases)
- [wfxr/forgit on GitHub](https://github.com/wfxr/forgit)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wfxr-forgit
