Archive
Defining your own Git commands
When you use a command prompt long enough, you’ll find yourself repeating some common command sequences. If you value your time, you’ll probably start saving shell aliases and even full shell scripts to simplify these things.
The same is true with using Git: you’ll probably find yourself repeating some long commands, and wish for an easier way. You may also just have some tricky Git recipes that you want to remember. Well sure enough, you can write Git aliases too, as well as add your own scripts as git subcommands. The Git wiki has a pretty good page describing aliases, so I’ll let you read that, and there are examples too. Here are a few more examples that I felt are worth sharing.
up = remote update
This first one is just pure laziness. A git remote update
is the same as git fetch
for all configured remotes, and now git up
can do the same with less typing.
new = log ..@{upstream} pend = log @{upstream}..
These show how the current branch differs from the upstream tracking branch (often origin/master
, but could be anything). My version of git new
is different than the example on the Git wiki, instead showing what commits you’ve fetched but not yet pulled/merged. Then git pend
is the opposite, showing what commits are pending to go out in a push.
log1 = log --abbrev-commit --pretty=oneline logf = log --pretty=fuller
These are just shortcuts for formatted logs; git log1
for one line per commit, and git logf
for the fuller format that includes committer info (instead of just author). The log1
options could also be condensed down to --oneline
these days, but that wasn’t available when I first wrote this alias.
lol = log --graph --decorate --pretty=oneline --abbrev-commit lola = log --graph --decorate --pretty=oneline --abbrev-commit --all
More logging tricks, and for these I’ll give credit to the blog where I found them. These add ASCII-art graph lines to help visualize merges, and they also label tags and branch heads.
show-patch = format-patch --stdout -1
This works like git show
, dumping the most recent commit on stdout, but with format-patch
it uses email-style headers. This makes it easier to elsewhere use git am
on that patch with preserved commit message, author, and date. It also includes binary diffs by default.
make = !test -d \"$(git rev-parse --show-toplevel)\" && make -C \"$_\"
This runs make from the top of the git directory, no matter what your current working directory is, so you can just git make
anywhere. The test -d
beforehand is just a precaution to make sure you’re really within a git path, otherwise you’ll get both a git error and make complaining of an empty -C
argument.
Once you start getting into complicated “!...
” sequences, it may make sense to break it out into its own file. As long as you name it starting with “git-
“, like git-unique-abbrev
in my last post, and save it somewhere in your PATH
, then you can call it as you would any other git command like git unique-abbrev
. Another good example is this git merge-ff
script on StackOverflow, which lets you safely fast-forward any branch without affecting your current work tree.
The last one I’ll leave you with is back to shell aliases:
alias gcd='test -d "$(git rev-parse --show-toplevel)" && cd "$_"'
This changes your current directory to the top of the git tree, using the same mechanism as I did for git make
. This has to be a shell alias, not a git command or a script, because it’s changing the working directory of the shell. Don’t forget cd -
to jump back too.