bade735cc1472740f39466e5fcc6707e417908e0
   1#!/usr/bin/env perl
   2# Copyright (c) 2009, 2010 David Aguilar
   3#
   4# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
   5# git-difftool--helper script.
   6#
   7# This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git.
   8# GIT_DIFFTOOL_NO_PROMPT, GIT_DIFFTOOL_PROMPT, and GIT_DIFF_TOOL
   9# are exported for use by git-difftool--helper.
  10#
  11# Any arguments that are unknown to this script are forwarded to 'git diff'.
  12
  13use 5.008;
  14use strict;
  15use warnings;
  16use Cwd qw(abs_path);
  17use File::Basename qw(dirname);
  18use Getopt::Long qw(:config pass_through);
  19use Git;
  20
  21sub usage
  22{
  23        print << 'USAGE';
  24usage: git difftool [-t|--tool=<tool>]
  25                    [-x|--extcmd=<cmd>] [-g|--gui]
  26                    [--prompt] [-y|--no-prompt]
  27                    ['git diff' options]
  28USAGE
  29        exit 1;
  30}
  31
  32sub setup_environment
  33{
  34        my $DIR = abs_path(dirname($0));
  35        $ENV{PATH} = "$DIR:$ENV{PATH}";
  36        $ENV{GIT_PAGER} = '';
  37        $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper';
  38}
  39
  40sub exe
  41{
  42        my $exe = shift;
  43        if ($^O eq 'MSWin32' || $^O eq 'msys') {
  44                return "$exe.exe";
  45        }
  46        return $exe;
  47}
  48
  49# parse command-line options. all unrecognized options and arguments
  50# are passed through to the 'git diff' command.
  51my ($difftool_cmd, $extcmd, $gui, $help, $prompt);
  52GetOptions('g|gui' => \$gui,
  53        'h' => \$help,
  54        'prompt!' => \$prompt,
  55        'y' => sub { $prompt = 0; },
  56        't|tool:s' => \$difftool_cmd,
  57        'x|extcmd:s' => \$extcmd);
  58
  59if (defined($help)) {
  60        usage();
  61}
  62if (defined($difftool_cmd)) {
  63        if (length($difftool_cmd) > 0) {
  64                $ENV{GIT_DIFF_TOOL} = $difftool_cmd;
  65        } else {
  66                print "No <tool> given for --tool=<tool>\n";
  67                usage();
  68        }
  69}
  70if (defined($extcmd)) {
  71        if (length($extcmd) > 0) {
  72                $ENV{GIT_DIFFTOOL_EXTCMD} = $extcmd;
  73        } else {
  74                print "No <cmd> given for --extcmd=<cmd>\n";
  75                usage();
  76        }
  77}
  78if (defined($gui)) {
  79        my $guitool = "";
  80        $guitool = Git::config('diff.guitool');
  81        if (length($guitool) > 0) {
  82                $ENV{GIT_DIFF_TOOL} = $guitool;
  83        }
  84}
  85if (defined($prompt)) {
  86        if ($prompt) {
  87                $ENV{GIT_DIFFTOOL_PROMPT} = 'true';
  88        } else {
  89                $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
  90        }
  91}
  92
  93setup_environment();
  94my @command = (exe('git'), 'diff', @ARGV);
  95
  96# ActiveState Perl for Win32 does not implement POSIX semantics of
  97# exec* system call. It just spawns the given executable and finishes
  98# the starting program, exiting with code 0.
  99# system will at least catch the errors returned by git diff,
 100# allowing the caller of git difftool better handling of failures.
 101my $rc = system(@command);
 102exit($rc | ($rc >> 8));