]>
Commit | Line | Data |
---|---|---|
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 | ||
13 | use 5.008; | |
14 | use strict; | |
15 | use warnings; | |
16 | use Cwd qw(abs_path); | |
17 | use File::Basename qw(dirname); | |
18 | ||
19 | require Git; | |
20 | ||
21 | my $DIR = abs_path(dirname($0)); | |
22 | ||
23 | ||
24 | sub usage | |
25 | { | |
26 | print << 'USAGE'; | |
27 | usage: git difftool [-t|--tool=<tool>] [-x|--extcmd=<cmd>] | |
28 | [-y|--no-prompt] [-g|--gui] | |
29 | ['git diff' options] | |
30 | USAGE | |
31 | exit 1; | |
32 | } | |
33 | ||
34 | sub setup_environment | |
35 | { | |
36 | $ENV{PATH} = "$DIR:$ENV{PATH}"; | |
37 | $ENV{GIT_PAGER} = ''; | |
38 | $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper'; | |
39 | } | |
40 | ||
41 | sub exe | |
42 | { | |
43 | my $exe = shift; | |
44 | if ($^O eq 'MSWin32' || $^O eq 'msys') { | |
45 | return "$exe.exe"; | |
46 | } | |
47 | return $exe; | |
48 | } | |
49 | ||
50 | sub generate_command | |
51 | { | |
52 | my @command = (exe('git'), 'diff'); | |
53 | my $skip_next = 0; | |
54 | my $idx = -1; | |
55 | my $prompt = ''; | |
56 | for my $arg (@ARGV) { | |
57 | $idx++; | |
58 | if ($skip_next) { | |
59 | $skip_next = 0; | |
60 | next; | |
61 | } | |
62 | if ($arg eq '-t' || $arg eq '--tool') { | |
63 | usage() if $#ARGV <= $idx; | |
64 | $ENV{GIT_DIFF_TOOL} = $ARGV[$idx + 1]; | |
65 | $skip_next = 1; | |
66 | next; | |
67 | } | |
68 | if ($arg =~ /^--tool=/) { | |
69 | $ENV{GIT_DIFF_TOOL} = substr($arg, 7); | |
70 | next; | |
71 | } | |
72 | if ($arg eq '-x' || $arg eq '--extcmd') { | |
73 | usage() if $#ARGV <= $idx; | |
74 | $ENV{GIT_DIFFTOOL_EXTCMD} = $ARGV[$idx + 1]; | |
75 | $skip_next = 1; | |
76 | next; | |
77 | } | |
78 | if ($arg =~ /^--extcmd=/) { | |
79 | $ENV{GIT_DIFFTOOL_EXTCMD} = substr($arg, 9); | |
80 | next; | |
81 | } | |
82 | if ($arg eq '-g' || $arg eq '--gui') { | |
83 | eval { | |
84 | my $tool = Git::command_oneline('config', | |
85 | 'diff.guitool'); | |
86 | if (length($tool)) { | |
87 | $ENV{GIT_DIFF_TOOL} = $tool; | |
88 | } | |
89 | }; | |
90 | next; | |
91 | } | |
92 | if ($arg eq '-y' || $arg eq '--no-prompt') { | |
93 | $prompt = 'no'; | |
94 | next; | |
95 | } | |
96 | if ($arg eq '--prompt') { | |
97 | $prompt = 'yes'; | |
98 | next; | |
99 | } | |
100 | if ($arg eq '-h') { | |
101 | usage(); | |
102 | } | |
103 | push @command, $arg; | |
104 | } | |
105 | if ($prompt eq 'yes') { | |
106 | $ENV{GIT_DIFFTOOL_PROMPT} = 'true'; | |
107 | } elsif ($prompt eq 'no') { | |
108 | $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true'; | |
109 | } | |
110 | return @command | |
111 | } | |
112 | ||
113 | setup_environment(); | |
114 | ||
115 | # ActiveState Perl for Win32 does not implement POSIX semantics of | |
116 | # exec* system call. It just spawns the given executable and finishes | |
117 | # the starting program, exiting with code 0. | |
118 | # system will at least catch the errors returned by git diff, | |
119 | # allowing the caller of git difftool better handling of failures. | |
120 | my $rc = system(generate_command()); | |
121 | exit($rc | ($rc >> 8)); |