jswanner

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

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

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 reset to selectively un-stage changes from files in the index into the work tree
  • git restore to selectively discard changes from files in the work tree
  • git stash to 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 = true

    Reuse 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 = diff3

    Adds 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 = true

    Uses helpful prefixes rather than the default a/file/name and b/file/name when 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 to a/ and b/).

    Useful if you often run git diff with 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 alias

    An alias that lists all aliases.

    git config set --global alias.alias "!alias(){ git config --get-regexp '^alias.${1}'; }; alias"
    
  • git cherrypick

    Because I forget the - in cherry-pick, every time.

    git config set --global alias.cherrypick cherry-pick
    

Informational

  • git current

    Shows 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 last

    Shows 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 N commits, default 5.

    Customizable using pretty formats.

    (I use --- >8 --- to separate commits because I also use commit.cleanup = scissors and 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 fetch first 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 HEAD if 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 N commits, default 1.

    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

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"

Where Next?

Popular in Dev Env & Tools Top

SpaceVim
I am author of SpaceVim, As you know SpaceVim is a vim config which provide layer feature. https://github.com/SpaceVim/SpaceVim I want ...
New
AstonJ
Welcome to our thread for Mac users :smiley: Windows users please use this thread Linux users please use this thread For those who dis...
New
pinksynth
Hey everybody. I was wondering if anybody here has used Panic’s Nova editor. It came out recently and I saw there was no Elixir Formatte...
New
sodapopcan
I get the impression that the Elixir community at large is using nvim, though it occurred to me that I don’t actually know this so I thou...
New
AstonJ
Following on from this post in Do you use LittleSnitch or the equivalent on your OS? I think it might be worth us creating this thread so...
New
AstonJ
While on the theme of routers: Is your computer's internet connection wired or wireless? (Poll) Which router do you use? How do you se...
New
AstonJ
macOS had always used your Account Name as your Username (Case-Preserving) but from around Catalina onwards it started downcasing usernam...
New
AstonJ
If you use a VPN or are interested in any please vote in the poll - you can select as many options as you want :icon_biggrin: I’ve added...
New
Tyson
I know there are lot of shell-theme nerds in this group. I want to share a little something that Claude and I have been working on in our...
New
zmzlois
I was looking for an open router sdk in elixir but i didn’t find anything so here you go openrouter_sdk | Hex
New

Other popular topics Top

vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31265 143
New
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41989 114
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement