« Perls of VisdomMy settings, everywhere »

Wed, Feb 15, 2012

[Icon][Icon]'cuz multiple steps into one is cool :)

• Post categories: Omni, FOSS, Technology, My Life, Programming, Helpful

If you work on a large codebase, you'll probably find yourself coming across code where you think "Who wrote this? When? Why?" and wishing you knew more about what lead to what you're looking at being written.

If you use a version control system, you can probably find out. If you're using git, it's easy: You use git blame, a helpful function that tells you the commit for every single line of code in a file.

You then look at that commit, and between the commit message and looking at all the code that was written as part of it, you stand a better chance of working out the "Who/why/when" problem.

But that's a bit tedious. So since we all use vim at work, I came up with something nicer: Press a shortcut key, and vim will show you the commit responsible for your current line. The whole process from above, instantly available in your text editor.

It was surprisingly simple, too. All it needs is:

In your .vimrc:
" Get the commit responsible for the current line
nmap <f4> :call BlameCurrentLine()<cr>
" Get the current line number & file name, view the git commit that inserted it
fun! BlameCurrentLine()
let lnum = line(".")
let file = @%
exec "!gitBlameFromLineNo " lnum file

This maps the functionality to the F4 function key. Feel free to pick another.. All it does is get your current line & file, and pass it to a command which does the git stuff.

You could do the rest with a simple bash one-liner, but for easier maintainability, I stuck it into a little Perl script in /usr/local/bin/:


use strict;
use warnings;

use v5.10;

my $debug = 0;

my $line_no = $ARGV[0];
my $file_name = $ARGV[1];
say "Line: $line_no | File: $file_name" if $debug;

# Get the git blame for the line & file
my $line = `git blame -L $line_no,$line_no $file_name`;
say "Line: $line" if $debug;

# Reduce this just to the SHA
chomp $line;
(my $sha = $line) =~ s/^(\S+).*/$1/;
say "SHA: $sha" if $debug;

# Show the commit for that SHA
system("git show $sha");

Yeah, it's a bit over-engineered for such a simple task. But I can foresee having to meddle with it quite a bit in future.

But it's really quite cool, being able to press a button in your editor and get everything you might need to know about the line you're working on, just like that.

So here it is, for anyone else who might want it :)


Comment from: Åke [Visitor] · http://akeiexil.wordpress.com
Very nice indeed. I haven't experimented with vim's cooler features but that is _very_ useful!
16/02/12 @ 11:45
Comment from: Htbaa [Visitor] · http://blog.htbaa.com
Only seems to work when the Git directory is in the home directory. Could possibly be changed with a chdir() in the Perl script to the script location.
25/02/12 @ 09:25

[Links][icon] My links

[Icon][Icon]About Me

[Icon][Icon]About this blog

[Icon][Icon]My /. profile

[Icon][Icon]My Wishlist


[FSF Associate Member]

October 2014
Mon Tue Wed Thu Fri Sat Sun
 << <   > >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    


User tools

XML Feeds

eXTReMe Tracker

Valid XHTML 1.0 Transitional

Valid CSS!

[Valid RSS feed]