a3ad389569dda38ea08cba59530a43005e814c60
   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
  38# parse command-line options. all unrecognized options and arguments
  39# are passed through to the 'git diff' command.
  40my ($difftool_cmd, $extcmd, $gui, $help, $prompt);
  41GetOptions('g|gui!' => \$gui,
  42        'h' => \$help,
  43        'prompt!' => \$prompt,
  44        'y' => sub { $prompt = 0; },
  45        't|tool:s' => \$difftool_cmd,
  46        'x|extcmd:s' => \$extcmd);
  47
  48if (defined($help)) {
  49        usage(0);
  50}
  51if (defined($difftool_cmd)) {
  52        if (length($difftool_cmd) > 0) {
  53                $ENV{GIT_DIFF_TOOL} = $difftool_cmd;
  54        } else {
  55                print "No <tool> given for --tool=<tool>\n";
  56                usage(1);
  57        }
  58}
  59if (defined($extcmd)) {
  60        if (length($extcmd) > 0) {
  61                $ENV{GIT_DIFFTOOL_EXTCMD} = $extcmd;
  62        } else {
  63                print "No <cmd> given for --extcmd=<cmd>\n";
  64                usage(1);
  65        }
  66}
  67if ($gui) {
  68        my $guitool = "";
  69        $guitool = Git::config('diff.guitool');
  70        if (length($guitool) > 0) {
  71                $ENV{GIT_DIFF_TOOL} = $guitool;
  72        }
  73}
  74if (defined($prompt)) {
  75        if ($prompt) {
  76                $ENV{GIT_DIFFTOOL_PROMPT} = 'true';
  77        } else {
  78                $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
  79        }
  80}
  81
  82setup_environment();
  83my @command = ('git', 'diff', @ARGV);
  84
  85# ActiveState Perl for Win32 does not implement POSIX semantics of
  86# exec* system call. It just spawns the given executable and finishes
  87# the starting program, exiting with code 0.
  88# system will at least catch the errors returned by git diff,
  89# allowing the caller of git difftool better handling of failures.
  90my $rc = system(@command);
  91exit($rc | ($rc >> 8));