Review a git branch in the terminal

Reading time: 2 minutes

When I review a pull-request with many commits, I want to be able to see all the commits and step back and forth through them. I used to use a git GUI (or github’s web pages), but I hated having to leave the terminal to do that.

Today I whipped up a Perl program to stage all the commit information into tempfiles and fire up vim on them. I saved it in my bin path as ‘git-review’, so I can call it as “git review”. No promises of quality, but I’m sharing it in case anyone wants to steal/adapt it.

#!/usr/bin/env perl
use v5.10;
use strict;
use warnings;
use Path::Tiny;
use Capture::Tiny qw/capture_stdout/;

my ( $branch, $trunk ) = @ARGV;

die "Usage: $0 <branch> [trunk]"
  unless $branch;

$trunk //= 'master';

my $fork_point = qx{git merge-base --fork-point $trunk $branch};
chomp $fork_point;

die "Couldn't locate fork point for $branch from $trunk"
  unless $fork_point;

my @commits = map { chomp; $_ } qx/git rev-list $fork_point..$branch/;

my $tempdir = Path::Tiny->tempdir;

my @files;
for my $c (@commits) {
    push @files, my $file = $tempdir->child($c);
    $file->spew( scalar capture_stdout { system( qw/git show -p --stat/, $c ) } );
}

my $index = $tempdir->child("log");
$index->spew( scalar capture_stdout { system( qw/git log/, q[--pretty=%h %s%d], "$fork_point..$branch" ) } );
$index->append( "\ngit diff --stat\n", scalar capture_stdout { system( 'git', 'diff', '--stat', "$fork_point..$branch" ) } );

system( "vim", $index, reverse @files );

Now, since I use ingy’s git-hub command line tool, my pull-request review is as easy as this:

$ git hub pr-fetch 27
$ git review PR/27

•      •      •

If you enjoyed this or have feedback, please let me know by or