|0.1.4||Feb 16, 2022|
|0.1.3||Oct 2, 2021|
#1326 in Command line utilities
Oaf, a nicer Git
Oaf is a Git client that brings a more user-friendly CLI to Git.
It's based on the following ideas:
- Merge is used to apply the changes introduced in another branch to the current branch.
- The commits done in a branch are different from the commits merged into a branch.
- Merges are a good thing that should be encouraged. They prevent conflicts from happening later, by establishing a clear precedence between two sets of changes.
- Merges can introduce logical conflicts, so the user should have the opportunity to test a merge before committing it.
- Push and Pull are operations to synchronize two copies of the same branch.
--is used to separate options from inputs that might look like options, not to separate file inputs from other kinds of inputs.
- Working on several branches at once should be as easy as possible.
- Users should have the opportunity to see what changes would be introduced by merging their current work into its eventual target.
- It is usually a bad idea to commit a version of the code that has never existed on disk.
- The Git index (staging area/cache) is an implementation detail that is not useful to most users.
- History is valuable, and should usually be preserved. It allows later readers to understand the precise context in which a change was introduced.
Differences from Git
merge-diffcommand to show what would happen if you committed and and merged your changes into a branch.
catcommand to retrieve old versions of files.
fake-mergeto pretend to merge a branch, while actually making no changes to your local contents.
squash-commitconvert the current set of commits into a single commit.
ignoreignores the specified files by updating .gitignore
New commands as Git external commands
All new commands can also be used as Git external commands, as long as the oaf
binary can be accessed via that name prefixed with 'git-'. e.g. by running
ln -s ~/.local/bin/oaf ~/.local/bin/git-merge-diff you can then run
git merge-diff. (This assumes that ~/.local/bin is in your path, and you have oaf installed there.)
Commands with changed behaviour
merge --no-ff --no-commit.
logshows only commits from the current branch (and its ancestors) by default. (2.)
- For a branch that has never been pushed before,
pushwill automatically push to
originwith the current branch's name.
switchallows you to pick up where you left off, without committing or explicitly stashing your pending changes. (7.)
-a(10.). To commit only some changes, consider using
oaf stash [-p]to temporarily remove unwanted changes. This gives you an opportunity to test that version before committing it (8.).
diffdefaults to HEAD for its source (10.). It provides source and target as options (6.). It defaults to patience diff to prefer contiguous matches over longer, broken-up matches.
restoredefaults to HEAD for its source (10.).
statususes a short format. When determining whether a file is modified, it (effectively) compares the working tree to HEAD (10.).
Note: if you just want the new commands, not the changed behaviour, see "New commands as Git external commands" above.
checkoutis superseded by
All commands not listed by
oaf help will automatically fall through to
oaf write-tree -h is the same as
git write-tree -h.
oaf falls through to
oaf will also fall through to external
git commands. So
git-lfs can also be invoked as
oaf lfs. Currently, Oaf
does not have native support for extension.
Oaf is a front-end for Git, so all of its operations on repositories are performed by invoking Git commands. Everything it does could be accomplished by a series of Git commands, meaning everything is completely compatible with Git.
Interchange with other users
The use of
merge improves mechanical interoperability, but may cause friction
with some Git users and tools. Most developers would agree that the changes
introduced on a branch are special in the context of that branch, but some do
not wish to use the first-parent mechanism to distinguish between branch
commits and merged-in commits. Because of this, they consider all merges to
Since maintaining first-parent ancestry is not a priority, they may mess it up through fast-forward "merges", especially foxtrot "merges".
Note that using
rebase in place of
merge can also hamper interoperability,
so this a catch-22, but one that Git users have long accepted.
Oaf is in its early days, so binaries are provided for only x86-64.
It is written in the Rust language, so you'll need a copy of the Rust
toolchain to install from source. The easiest way to do that is:
cargo install --locked oaf. This will install the latest published version.
Git must be installed for Oaf to function. Oaf is typically tested with Git 2.25.x
Oaf draws some inspiration from my previous work on
- Bazaar VCS
- the bzrtools plugins
- Fai, the Friendly Arch Interface
- aba, an Arch I wrote in shell to add support for Git-style external commands.
While the Git repository format won out over Bazaar, many concepts from the Bazaar user model can be applied to Git. Oaf is my attempt to begin to do that. There is also Breezy, which is a fork of Bazaar with Git support built-in.