Wednesday, 14 October 2009

Git: Getting Started with Aliases

Git has very quickly become my tool-of-choice for source control. It’s quick, it’s easy and it’s bloody good at what it does. It allows me to completely forget about source control, not fear things like branching and merging and just get on with writing code.

Git Aliases allow us to create shortcuts for common commands to make it even easier & quicker for us to use. In this post I cover creating simple aliases for common commands/scenarios (or at least those in my working day).

WARNING! Dragons Be Here!

We are going to be changing the Git configuration file! I strongly recommend you start with these by working on a fresh repository’s configuration file before adding the “--global” switch to apply changes across the board! By this, I mean:

  • Go to a temp directory.
  • Open up the Git bash/shell.
  • Type “git init”.
  • From this point on, all changes are to be made to this repository only by omitting the “--global” switch. I won’t even add it to the commands so you don’t screw up your system configuration by way of copy-and-paste!

Disclaimer: I am still very much getting used to working with MSYS, so there may be better ways to do things (esp. with the shell commands). I have simply done enough to “get things working”.

The Basics

Adding an alias is pretty simple, it takes the format of:

   1: git config alias.{shortcut} {command}

Where:

  • “shortcut” is the alias you would like to use.
  • “command” is the command you would like to execute.

Git Status

I often use “git status” to get a brief overview of what’s going on. This is especially after creating projects, generating files etc. so I can ensure my “ignore” flags are set on appropriate files.

Let’s alias it so we can just type “s” instead:

   1: git config alias.s status

Done! Now lets test it:

   1: $ git s
   2: ... {output ommitted}

See how we just type the alias? This is how we will execute future aliases.

Now let’s spice things up a bit by adding some switches to the command..

Commit Early, Commit Often, Commit Easy

Since we want to commit early, and commit often with a message - you do always add a commit message, right? ;)

   1: git config alias.c 'commit -a -m'

We can then commit all unindexed changes using the following:

   1: git c "This is my commit message"

NOTE: This commits unindexed changes (i.e. files under version control that have changes, but does NOT add new files).

I am currently trying to get the damn thing to perform a “git add .” followed by the “git commit -a -m” and read in the message argument passed - but having issues!

Either someone smarter than me will let me know how this is done, or I will crack it!

Reverting Changes

One of the main points of source control is that it gives us the freedom to mess with our code in a safe environment, where we can roll back changes if required.

Let’s set up a alias to revert the “HEAD” revision (last committed changes).

   1: git config alias.r 'revert head'

NOTE: The use of the single quotes - otherwise only the “revert” is added to the configuration file.

Resetting Working Copy & Cleaning

WARNING: This will lose any uncommitted changes and newly-created files without prompt! Exercise caution using this!

What if we have not been crazy enough to commit the changes? Here we need to use “git reset --hard” switch to bring the working copy right back to the HEAD revision. But, if files have been added, then we need to clean those up as well.

This is where the ability to chain commands together in an alias come in handy. This alias is a little different because we prefix with “!” which actually performs a shell command (hence the need to add the “git” too). More on this later..

   1: git config alias.hr '!git clean -f && git reset --hard'

Viewing the Log, Nicely Does It

Being a big fan of “commit early, commit often”, my commit messages tend to be short. So when reviewing the log, I just want a nice one-line output so I can skim-read the changes. Let’s clean up the log output:

   1: git config alias.l 'log --oneline'

We then get much nicer output using:

   1: $ git l
   2: 1982f99 Revert "Added More Code"
   3: bc66931 Added More Code

Shelling Out, Editing Excludes in Your Editor-of-Choice

As promised! Sometimes the Git commands just might not cut the mustard - so you might want to shell out to another command. This is easily done by prefixing the command with "!".

For example, You may often need to update your "excludes" file to prevent non-source files from being put under version control - so why not alias your fave editor:

   1: git config alias.ex \!\"c:\\program\ files\\notepad++\\notepad++.exe\"\ .gitignore

NOTE: There are a lot of escapes in the above which makes it look messy. Off my head I don’t know any way to clean this up - if you do, please comment!

Update: Following a comment from Mark, doubt was placed in my mind about the use of the “exclude” file, so I had a quick search and came across this. Therefore, to ensure that everyone gets the benefit of the ignore settings you create, place them in a file called “.gitignore”. The snippet above has been updated to suit.

Displaying Branch History to Screen

A nice switch I came across when first getting started was “graph”, which can be applied to the “log” command to get a nice ASCII-art-esque display of the branch history, let’s add an alias for “branch display”

   1: git config alias.bd 'log --graph --pretty=oneline --all'

Do you have any aliases you use on a regular basis? Did you find the above helpful?

Work hard. Play harder.

4 comments:

  1. Any reason you added items to the exclude file instead of adding a .gitignore file to each repository? I prefer this approach as it is versioned along with everything else and therefore included when you do a new clone of the repo. Nice article.

    ReplyDelete
  2. Hey Mark,

    Thanks for the feedback. With regards to your question - the .ignore file being edited is the local (individual) file for each repository. The path is relative to the current directory in the shell (which is the root of the project).

    I too believe in keeping all the required info in the repository so it is under version control!

    ReplyDelete
  3. Hey Mark,

    Just done some more digging as you put doubt into my mind! You are indeed correct!

    .gitignore files should be used rather than the excludes file for exactly the reason you specify. As per the GitFAQ.

    Will update the post now. Thanks again!

    ReplyDelete
  4. Sorry for my bad english. Thank you so much for your good post. Your post helped me in my college assignment, If you can provide me more details please email me.

    ReplyDelete