It's no secret that I'm a big fan of git, and of distributed version control in general; they offer a compelling toolset and degree of flexibility that you would be hard pressed to find in a “traditional” centralized version control system. Instead of discussing the merits of a DVCS or performing feature comparisons between particular implementations -- there are enough of those already -- let's take a look at how you can bend Git to your will through configuration, and a few useful aliases. If you've not encountered this before, you'll be surprised at how much can be accomplished with just a few lines in a configuration file.
This is where the magic happens. Git, by default, will attempt to find a
.gitconfig file in three places:
GIT_DIR/configfor per-repository configurations
~/.gitconfigfor user-specific configurations
$(prefix)/etc/gitconfigfor system-wide configurations
Read up on the various options and overrides that
as well as alternative methods to interactively add/remove/replace configuration options.
For the rest of this article we'll be adding configurations to
~/.gitconfig, but there's nothing stopping you from doing it
in a per-repository (or even system-wide) configuration file instead.
For reference, here is a simplified version of the config I use:
Now let's go through what these configuration options actually do.
[color] diff = auto status = auto
These were, in all likelihood, the first configuration options I setup once I had installed Git for the first time. I work in a terminal window all day, and having proper and consistent colourization makes all the difference when attempting to quickly determine the state of your repository:
With these options set, all
branch commands will have (where appropriate) colourized output.
If you ever plan on making your repository available to other developers, these options are essential for identifying who you are. They're pretty self-explanatory:
[user] name = Joël Perras email = firstname.lastname@example.org
The sole configuration I have under this segment is something of a personal preference. When I'm four folders deep into a repository
and I invoke
git status, I don't need to see where the changed/added/deleted files are relative to where I invoked the
command -- I'm far more interested in their absolute location relative to the repository root. That's where
relativePaths = false comes in handy:
[status] relativePaths = false
There are some files you just never want to commit, no matter what project you're working on. As an avid vim user,
I sometimes have a few
*.swp files lying around (mostly due to my own fault), which have no place in any project history.
Instead of adding an ignore rule to each and every repository, I added this configuration directive to my
~/.gitconfig, indicating where
my global never-track-any-of-these-file-patterns exists:
[core] excludesfile = /Users/joel/.gitignore
Now we get to the interesting stuff. Aliases in Git are exactly what you expect them to be: user-defined shortcuts that group together pre-existing git (and sometimes shell) commands and their options.
Edit: As some people have pointed out, there are a few flags/commands that will not work unless you have git
1.7.2 or above installed. Pardon the confusion.
[alias] d = diff dc = diff --cached lc = log ORIG_HEAD.. --stat --no-merges gl = log --oneline --decorate --stat --graph st = status -sb serve = !git daemon --reuseaddr --verbose --base-path=. --export-all ./.git prune-all = !git remote | xargs -n 1 git remote prune whatis = show -s --pretty='tformat:%h (%s, %ad)' --date=short whois = "!sh -c 'git log -i -1 --pretty=\"format:%an <%ae>\n\" --author=\"$1\"' -"
git d and git dc
I'm often taking diffs between different revisions in projects, so these two are quite heavily used.
Lists all new commits after you fetched. This is especially useful when working on a very active project with multiple developers.
This is the default command that I invoke when I wish to inspect the log. The output is concise as well as informative:
My preferred method of viewing the status of a repository, which gets rid of the fluff that usually accompanies the help-type text of git status:
git remote prune doesn't know how to prune all of your remotes at once, let's teach it that trick. This is especially
useful if you're tracking many remotes from various contributors to a project where the branches get nuked/renamed on a regular basis.
git whatis <commit-ish>
Pass this command a hash, branch name or tag, and it will give you a one-liner containing the commit message associated to it as well as the date it was committed on. Useful when git show is more information than you need.
git whois <name|email>
Another one of those useful commands when you're working on a project with a multitude of collaborators, and need to fish out an email address when all you remember is part of their name, or vice versa. Note that if the collaborator in question never configured their name and/or email address (as described above), then this command will not be very useful.
And that's it! With nothing more than a few lines in a configuration file, we've managed to make Git be more informative as well as more concise. If you have any tips/tricks/configs that you can't live without, leave a comment below.
Quite a few of the aliases and what I would consider "sane" configuration options have been lifted from the official wiki for Git. I highly recommend perusing it, once you've become familiar with Git itself.