a399f3d2a23ea69f8e84f31070e00aeb4845dc32
   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 Getopt::Long qw(:config pass_through);
  17use Git;
  18
  19sub usage
  20{
  21        my $exitcode = shift;
  22        print << 'USAGE';
  23usage: git difftool [-t|--tool=<tool>]
  24                    [-x|--extcmd=<cmd>]
  25                    [-g|--gui] [--no-gui]
  26                    [--prompt] [-y|--no-prompt]
  27                    ['git diff' options]
  28USAGE
  29        exit($exitcode);
  30}
  31
  32sub setup_environment
  33{
  34        $ENV{GIT_PAGER} = '';
  35        $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper';
  36}
  37
  38sub exe
  39{
  40        my $exe = shift;
  41        if ($^O eq 'MSWin32' || $^O eq 'msys') {
  42                return "$exe.exe";
  43        }
  44        return $exe;
  45}
  46
  47# parse command-line options. all unrecognized options and arguments
  48# are passed through to the 'git diff' command.
  49my ($difftool_cmd, $extcmd, $gui, $help, $prompt);
  50GetOptions('g|gui!' => \$gui,
  51        'h' => \$help,
  52        'prompt!' => \$prompt,
  53        'y' => sub { $prompt = 0; },
  54        't|tool:s' => \$difftool_cmd,
  55        'x|extcmd:s' => \$extcmd);
  56
  57if (defined($help)) {
  58        usage(0);
  59}
  60if (defined($difftool_cmd)) {
  61        if (length($difftool_cmd) > 0) {
  62                $ENV{GIT_DIFF_TOOL} = $difftool_cmd;
  63        } else {
  64                print "No <tool> given for --tool=<tool>\n";
  65                usage(1);
  66        }
  67}
  68if (defined($extcmd)) {
  69        if (length($extcmd) > 0) {
  70                $ENV{GIT_DIFFTOOL_EXTCMD} = $extcmd;
  71        } else {
  72                print "No <cmd> given for --extcmd=<cmd>\n";
  73                usage(1);
  74        }
  75}
  76if ($gui) {
  77        my $guitool = "";
  78        $guitool = Git::config('diff.guitool');
  79        if (length($guitool) > 0) {
  80                $ENV{GIT_DIFF_TOOL} = $guitool;
  81        }
  82}
  83if (defined($prompt)) {
  84        if ($prompt) {
  85                $ENV{GIT_DIFFTOOL_PROMPT} = 'true';
  86        } else {
  87                $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
  88        }
  89}
  90
  91setup_environment();
  92my @command = (exe('git'), 'diff', @ARGV);
  93
  94# ActiveState Perl for Win32 does not implement POSIX semantics of
  95# exec* system call. It just spawns the given executable and finishes
  96# the starting program, exiting with code 0.
  97# system will at least catch the errors returned by git diff,
  98# allowing the caller of git difftool better handling of failures.
  99my $rc = system(@command);
 100exit($rc | ($rc >> 8));