Custom git command for formatting code. git-fmt provides a wrapper around omnifmt, an automatic code formatter. It adds the ability to operate on specific tracked files in the repository.
Formatted code is:
- Easier to write: never worry about minor formatting concerns while hacking away.
- Easier to read: when all code looks the same you need not mentally convert others' formatting style into something you can understand.
- Easier to maintain: mechanical changes to the source don't cause unrelated changes to the file's formatting; diffs show only the real changes.
- Uncontroversial: never have a debate about spacing or brace position ever again.
(Bullet points taken from https://blog.golang.org/go-fmt-your-code.)
Installing git-fmt is easiest done using either stack (recommended) or Cabal.
Using stack:
stack install git-fmt
export PATH=$PATH:~/.local/bin
Using Cabal:
cabal-install git-fmt
export PATH=$PATH:~/.cabal/bin
The git-fmt binary provides an interface for selecting files and piping them through external pretty-printers. It supports both prettifying the files immediately and performing dry-runs to see which files are ugly. Given that it uses the omnifmt library underneath, the syntax and features are quite similar. The main difference is that git-fmt restricts files to being tracked by the git repository and that by default it only operates on files in the index.
The basics:
git-fmt operates only on tracked git files (thus it implicitly respects the '.gitignore' file).
By default it operates on files in the index (i.e., --operate-on head
).
It is possible to operate on all tracked files (--operate-on-tracked
) or on a specific reference
(--operate-on REF
).
The REF
argument is passed directly into git diff REF --name-only
, so you can even play with
ranges such as master...
.
Passing arguments to git-fmt will narrow down the operation files.
For example, git fmt --operate-on-tracked src/
will format all tracked files under 'src/' and
git fmt --operate-on head src/
will format all files in the index under 'src/'.
Modes:
git-fmt can run in three different modes, normal, dry-run and diff.
The normal and dry-run modes act the same as omnifmt.
Diff mode however uses git diff
as opposed to diff
.
By default the diff isn't paged, so to get output similar to git diff
or git log
it is
recommended to use [-p|--paginate]
, e.g., git -p fmt -m diff
.
NB: it isn't possible to pipe the diff into git apply
due to the destination file path
header.
git-fmt delegates to omnifmt for configuration, see here for documentation and examples.
Add the following (depending on your shell) to include support for auto-completion.
Bash:
source <(git-fmt --bash-completion-script `which git-fmt`)
zsh:
autoload -Uz bashcompinit && bashcompinit
source <(git-fmt --bash-completion-script `which git-fmt`)
NB: auto-completion doesn't work well with git's command macro. I.e., git fmt <TAB>
won't
work, but git-fmt <TAB>
will. #71 will remain
open until this is addressed.