Configure Git, Like a Boss

I have just created a Git presentation. The presentation is named Git, Practical Tips, and it contains good practices that I have picked up during my four years as a Git user.

The presentation consists of six parts, A quick introduction; History manipulation with merge, rebase and reset; Finding with Git; Configuration; Under the hood; and Interacting with Github.

If you find this interesting and would like to hear a very practical presentation about Git tips and tricks, feel free to contact me :)

In this post I will describe how to configure Git to work well from the command line. It consists of two main parts, Git configuration and Bash configuration.

I will only describe some select samples of my configuration here. If you want to see more, my configuration files are on Github.

Git Configuration

The Git configuration part is just a bunch of aliases I use. Some are simple and some are more advanced. The aliases are declared in my global git config file, ~/.gitconfig under the [alias] tag. Here are some of most important ones.

git add --patch

git ap (git add --patch) is awesome. It lets me add selected parts of the changes in my working directory, allowing me to create a consistent commit with a simple clear commit message.

git add --update

git au adds all the changed files to the index. I use it mainly when I forget to remove a file with git rm and instead remove it with rm. In this case Git will see that the file is missing but not staged for removal. When I run git au it will be added to the index as if I had used git rm in the first place.

git stash save -u

git ss stashes everything in my working directory, including untracked files (-u). The reason I use git stash save instead of just git stash is that it allows me to write a message for the stash, similar to a commit message.

git amend

git amend lets me add more changes to the previous commit. It is very useful when I forget to add a change to the index before I commit it. It amends the new changes in the index and lets me edit the old commit message. git amendc does the same thing but reuses the old commit message.

git alias

git alias shows me all my aliases. Starting with a bang (!) is necessary to execute arbitrary bash commands. Note that the git command must be included. The code in the alias means, list configuration, find aliases, show characters 7 and on.

git log --diff-filter

git fa (find added) and git fd (find deleted) shows me a log of commits where files were added and deleted respectively. It is great for finding out how and when my files get deleted. I use it with a filename git fd my-missing-file.rb or with with grep, git fd | grep -C 3 missing.

grep -C 3 means shows me 3 lines of context around the matching line.

git log-pretty

git l is my main logging command it and prints a beautiful compact log. When I reuse an alias I must use the shell command alias, the bang (!), since Git does not allow me to reference an alias from another directly.

git log --simplify-by-decoration

git lt (log tagged) uses --simplify-by-decoration to show a list of "important" commits. Important in this case means commits that are pointed to by a branch or tagged. It reuses the log-hist alias above.

Bash Configuration

I used to have a bunch of aliases, such as ga, gd, etc. but, now I use my Git aliases instead. But I still have configuration for command completion and a nice informative prompt.

function g()

I use the git command more than any other command during a days work. git status is the subcommand I use mostly. I have optimized for this by creating a function g() that has status as its default argument.

The g() function gives me a lot of power out of a single character.

function gg()

My second (and last) function is gg().

gg() allows me to type a commit message without any quotes.

bash-completion

Installing bash-completion gives me command completion for commands, subcommands and more.

I use Homebrew to install Git, brew install git. It gives me a new version of Git. It also installs git-completion.bash in /usr/local/etc/bash_completion.d/.

I use the same configuration on Ubuntu and I check for the file in /etc/bash-completion.d/ too.

This is great but, what about my beautiful little g() function? How do I make it work with command completion? It turns out to be quite easy. Include the following little snippet in a configuration file, such as .bashrc.

The snippet reuses the functions, __git_complete and __git_main included with git-completion.bash to make completion work with g too. Lovely!

bash-prompt

In later versions of Git, the prompt functionality has been extracted out into its own script, git-prompt.sh. I include it like this.

I configure my prompt like this, it contains a little more magic than the plain Git configuration. I put it in one of my bash configuration files, such as .bashrc.

The function __git_ps1() can further be configured with some environment variables. This is what use.

The resulting prompt looks like this:

The different signs to the right indicate:

More info can be found in git-prompt.sh.

Credits

Obviously I have not figured this out all by myself. Here are some of my sources:

This Post Has 2 Comments

  1. Hi Anders,

    I have a variation over the compact git hist alias, which I think reads a bit nicer. Of course it’s a matter of taste, but here goes:

    alias.hist=log –pretty=format:”%h %ad | [%aE]: %s%d” –graph –date=short

    I also have an alias for pushing the local checked out branch to the remote repo:

    alias.pub=!f() { git push -u ${1:-origin} git symbolic-ref HEAD; }; f

    The latter alias is also an example of a git scriptlet, which I think you would find interesting.

  2. @Steen, I agree that your log is nice, but I like mine better :)
    But, I really like your pub alias, I’ll add it to my config right away.
    I didn’t know you could write sciptlets, very nice!

    I simplified your version to exclude the function.

    pub = "!git push -u ${1:-origin}
    git symbolic-ref HEAD"

    Thanks!

Leave a Reply

Close Menu