Longer than usual post, so added a TLDR; version at the bottom

The problem …

The first few months using Git, I used to frequently jump back and forth between using Git Bash and SourceTree. I really wanted to get in the habit of using git at the console, but some things just felt easier with a GUI that I could scroll and click my way through.

One of those paint points was viewing repository history - the commit tree. I knew I could get a really customized history view on the console with some magic incantation of git log and it’s many MANY argument options. But with log it was a lot of trial and error:

  • Run git log --oneline --graph --decorate --abbrev-commit --all -20
  • Oh wait, I’ve got more than 20 commits on my branch. I wanted to see where my branch split from master but that isn’t included in here.
  • Run git log --oneline --graph --decorate --abbrev-commit --all -30
  • Still don’t see master! git log sorts commits in history by when they were created, it looks like other branches had commits created after the tip of master.
  • First lets set an alias lg for that command so I don’t have to type it out each time. Then lets not give it a count argument, instead pipe the output to less so I can see the history a page at a time: git lg | less
  • Great, two pages down I finally see master but I hit the page key one too many times and now I can’t scroll back up - Aaaargghhhhhhhh!!!!

I know today that there’s a better way to do what I was trying to do here, but just including this as an example of why I started looking for alternative solutions. The better way in case any one is curious: git lg $(git merge-base master feature)..feature

… and the solution

tig is described as a ‘ncurses-based text-mode interface for git’. I already had my head buried in a few new terms/areas at the time and didn’t want to add ncurses to the list, so I’ve never really looked up what that means. A quick skim of the Wikipedia entry today tells me its a library for writing TUIs (Terminal User Interfaces) - that checks out with my experience. tig is a console utility that hides a crazy amount of GUI-like functionality underneath.

You already have tig installed

“Uhh what now?!” is probably what you are thinking. But its true - Git Bash actually comes with a bunch of Unixy tools ported to Windows. You can find what else you’ve already got by looking in the /usr/bin folder in your Git for Windows installation. tig just happens to be one of them - speaks to its utility if its included by default right?

WORKS ON MY MACHINE DISCLAIMER: You can even use tig if you’re a PowerShell user - just add that location to your PATH variable.

Main view

So if you’re following along, run tig in Git Bash / PowerShell while inside a git repository folder. When run without any arguments, tig launches straight into the main view. This view is the commit history for the repository, but scrollable, searchable and clickable (or ENTER-able for the KBD warriors).

Shortcut Operation
j / Down Arrow Move down to next commit
k / Up Arrow Move up to previous commit
/<keyword> Search for keyword in log
Enter Open the diff view for this commit
q Go back to previous view / Quit tig if no previous view

You can configure this view to periodically refresh so you are always viewing an up-to-date log. More on this further below in the customization section.

tig is a stand-in replacement for git log, and so will accept any parameters that you would have used with that command. For example, you can view history for a single file or directory by supplying the path as an argument: tig -- ./src/app/Program.cs

Diff view

When you hit ENTER on a commit in the main view, tig opens a nice diff of that commit on the side (or bottom depending on window width). There’s a few things you can do here too:

  • Hitting ENTER on a filename, will jump down to the diff for that specific file.
  • Hitting [ will increase the number of lines of context displayed around changed lines. ] goes the other direction.

The diff view is a first class citizen in tig, so you can actually have it fill the screen instead of being a split window by pressing d on a line containing a commit SHA. Yep, you can actually hit d on any line containing a SHA - and tig will open the diff for that SHA.

Other views

The main and diff views are the ones I use the most, but there’s a few more in tig that come in handy.

Tree view

Hit t on a line with a commit SHA and this drops you into the tree view. This is a directory browser view of the repository as of that commit hash. I find this one interesting but not terribly useful - or atleast I haven’t found a good use for it yet.

Stage view

Hit s anywhere inside tig and it takes you the stage view - a nicely formatted view of git status. Move up/down to select a file and hit u to stage/unstage it. You can even stage/unstage parts of files by from the diff for the file. Hit c to commit.

Stash view

Hit y to view any stashes you have saved. All the same shortcuts from above apply (d to view a diff, t to view the directory tree, etc.).

References view

Hit r to go into the references view or what you would usually get from git branch. Hitting Enter here shows you a log of the branch you have selected.

Cherry-picking and merging

From the main view, you can cherry-pick commits onto your currently checked-out branch by just hitting C on the commit line. You can similarly merge branches into your active branch by hitting M on the branch tip - can’t get any easier than that.

Customizing the view

You can change how tig displays information using a few shortcuts:

Shortcut Operation
SHIFT+A Toggle different styles for author names
SHIFT+~ Toggle styles for the graphics (you’ll want to change this as the default doesn’t render well)
SHIFT+# Toggle line numbers (you can jump to a line with :<NUMBER><ENTER>)
SHIFT+X Toggle commit SHAs
SHIFT+D Toggle date display formats

Of course you don’t want to have to set this each time you open tig. You can create a .tigrc file with your favoured options. Here’s mine:

# General settings
set tab-size = 4
set ignore-case = true
set refresh-mode = periodic
set refresh-interval = 1
set mouse = true
set mouse-scroll = true
set diff-context = 5
set line-graphics = ascii

# Main view settings
set main-view = line-number:yes,interval:1 date:relative id:yes author:full commit-title:yes,graph:yes,refs:yes

# Colors
color cursor black green

Where can I find out more?

The tig doc [https://devhints.io/tig] and manual are excellent and are very short reads, so I would highly recommend them.

The cheat sheet here should be helpful for the first few weeks. The shortcuts are fairly easy to remember so they’ll get etched in memory quite quickly.

Too long, didn’t read version

tig is a Terminal UI application that lets you interact with a git repository in a number of ways. You already have it installed, so you should give it a try!

Here’s a recording of what tig can do: