jswanner
Helpful git aliases and config settings
I was about to reply to Why doesn’t Phoenix use Conventional Commit prefixes? - #41 by sodapopcan with some git aliases that I use for things like amending and rebasing commits, but then I thought it would be better to have a separate topic for that discussion, so here we are.
These are some git aliases I use frequently:
amend = commit -v --amend
fixup = !sh -c '_c=$(git rev-parse "$0") && git commit --fixup "$_c" && git rebase --autosquash --autostash --interactive "$_c"^ && unset _c'
force-push = push --force --force-with-lease
intend-to-add = add --intent-to-add
pop = stash pop
Most of these are for saving a few key strokes, for git commands I use extremely frequently (like git status -sb and git commit -v), I have fish shell abbreviations for those that are just 2-3 characters long.
The fixup alias above I find quite useful. It uses git rev-parse so that way the commit to be fixed can be specified by (partial) sha or something like HEAD~3, it’ll then commit what’s staged as a fixup commit and finally start an interactive rebase where most of the time nothing else needs to be done but to confirm.
I have other aliases for things like different formats of git log --all --graph but honestly I don’t use them that much.
Some other settings that I recommend:
[core]
pager = $(brew --prefix git)/share/git-core/contrib/diff-highlight/diff-highlight | LESSCHARSET='utf-8' less -F -R -X
[branch]
sort = -committerdate
[rerere]
enabled = true
Most Liked
adamu
This creates a bash function g, for git, which defaults to git status when there are no arguments.
function g () {
if [[ $# == 0 ]]
then
git status
else
git "$@"
fi
}
christhekeele
I have quite a few aliases and config recommendations. My personal favorite is git oops.
Tip: Patch Mode
Neither config nor alias per-se, but very useful: I do almost all my staging of changes hunk-by-hunk rather than file-by-file with git add -p (--patch). Check it out if you’ve never used it before! It allows me to craft much more intentional commits from a messy work tree.
It especially makes it really easy to do things like add temporary imports/requires/aliases for debugging purposes, and log/debug statements, in your code without accidentally committing them, or having to unwind them for committing purposes.
There are quite a few options when adding in “patch” mode, ? will give you some context. Over time I’ve incorporated y,n,q,a,d,j pretty deep into my muscle memory and workflow, but it takes some time and just y/n/q is a good start. For the purpose of subdividing hunks in order to separate a debug log line from some relevant code you want to commit, use s.
Already use git add -p? Did you know that --patch also works with:
git resetto selectively un-stage changes from files in the index into the work treegit restoreto selectively discard changes from files in the work treegit stashto selectively stash changes from files out of the work tree
Config
A lot of my config is fairly specific to my own preferred git workflows, but these are workflow-agonistic, useful for anyone, and in my opinion should be defaults.
-
rerere.enabled = trueReuse Recorded Resolution. Better ink than mine has been spilled on this, but essentially, if you ever rebase at all, you want this set. It makes dealing with merge conflicts while rebasing palatable.
git config set --global rerere.enabled true -
merge.conflictstyle = diff3Adds a third section to merge conflicts, showing what the code looked like before either conflicting commit touched it. This gives essential context to what each author was trying to accomplish when changing the code, making it much more trivial to reconcile.
git config set --global merge.conflictstyle diff3 -
diff.mnemonicprefix = trueUses helpful prefixes rather than the default
a/file/nameandb/file/namewhen diffing between things, where at least one thing is not a commit. Makes it easier to remember halfway scrolling through a long diff if you are comparing between a commit (c/), the index (i/), or the work tree (w/); or comparing two arbitrary commits (back toa/andb/).Useful if you often run
git diffwith various arguments (git diff,git diff <ref>,git diff --cached).git config set --global diff.mnemonicprefix true
Aliases
I also don’t care for the git alphabet soup shortcuts many folk use, it makes it harder for rich tab-completion and command history tools to work. I type just fast enough that using the full form doesn’t really slow down common operations, and think just slowly enough it wouldn’t speed up uncommon ones. I also tend to make more typos mashing out a short vowel-less alias and jamming Enter than I would composing a full command using things closer to full words.
Utility
-
git aliasAn alias that lists all aliases.
git config set --global alias.alias "!alias(){ git config --get-regexp '^alias.${1}'; }; alias" -
git cherrypickBecause I forget the
-incherry-pick, every time.git config set --global alias.cherrypick cherry-pick
Informational
-
git currentShows the current local branch.
Useful for scripting purposes, prompt display, or command substitution.
For example, when pushing up a branch for the first time,
git push -u origin $(git current).git config set --global alias.current rev-parse --abbrev-ref HEAD -
git lastShows a rich display of the last commit.
Customizable using pretty formats.
git config set --global alias.last "log -n1 --pretty='format:Commit: %C(yellow)%H%nAuthored by: %C(magenta)%aN %Creset%ar%nCommited by: %Cblue%cN %Creset%cr%n%n%B'" -
git latest [N]Shows a rich summary of the last
Ncommits, default5.Customizable using pretty formats.
(I use
--- >8 ---to separate commits because I also usecommit.cleanup = scissorsand it pleases me.)git config set --global alias.latest "log -n${1:-5} --pretty='format:%Cgreen---------------------- >8 ----------------------%nCommit: %C(yellow)%H%nAuthored by: %C(magenta)%aN %Creset%ar%nCommited by: %Cblue%cN %Creset%cr%n%n%s%n'" -
git contains <ref>Lists the branches a
<ref>is in.Performs a
fetchfirst to ensure you are up-to-date with, ex, PRs being merged into mainline while working on your branch.git config set --global alias.contains "!contains(){ git fetch && git rev-parse ${1:-HEAD} | xargs git branch -r --contains; }; contains" -
git ancestor <branch1> [<branch2>]Shows the last commit shared between two branches. Uses
HEADif only one branch is provided.git config set --global alias.ancestor merge-base --octopus
History Modification
-
git oops [-m "new message"] [-a | list/of/files]Add something you forgot to the latest commit.
Any staged changes in the index are folded into the last commit you made. Other unstaged changes in the work tree can be added by listing files, or all unstaged changes can be added with
-a.The commit’s message can be changed with
-m, but unlike standard commiting, you will not be presented with an editor if none is provided: the existing message will be left as-is.git config set --global alias.oops commit --amend --no-edit -
git rollback [N]Soft-resets the latest
Ncommits, default1.All changes in rolled back commits are preserved, staged into the index.
git config set --global alias.rollback "!rollback(){ cd ${GIT_PREFIX:-.} && git reset HEAD~${1:-1} --soft; }; rollback"
matt-savvy
If you use Oh My Zsh, there’s a gold mine of aliases at your fingertips.
Two personal aliases that I use all the time:
glm - See the commits for the current branch since it branched off from master.
alias glm='git log --oneline master..'
gccp - Copy the current (short) commit hash to the clipboard (pbcopy usually only on OSX, replace with xclip or whatever else you use if needed).
I use this when making changes on a Pull Request. It’s super helpful to respond to a comment and include the commit hash with makes the change being discussed. Github automatically turns this text (if the commit exists on GH) into a link to the commit, making it super easy for followup reviews, etc.
alias gccp="git rev-parse --short HEAD | tr -d '\n' | pbcopy"
Popular in Dev Env & Tools
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










