]>
Commit | Line | Data |
---|---|---|
5c38ea31 | 1 | #!/usr/bin/env perl |
f47f1e2c | 2 | # Copyright (c) 2009, 2010 David Aguilar |
5c38ea31 DA |
3 | # |
4 | # This is a wrapper around the GIT_EXTERNAL_DIFF-compatible | |
a904392e DA |
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 | # | |
5c38ea31 DA |
11 | # Any arguments that are unknown to this script are forwarded to 'git diff'. |
12 | ||
d48b2841 | 13 | use 5.008; |
5c38ea31 DA |
14 | use strict; |
15 | use warnings; | |
16 | use Cwd qw(abs_path); | |
17 | use File::Basename qw(dirname); | |
18 | ||
4cefa495 DA |
19 | require Git; |
20 | ||
5c38ea31 DA |
21 | my $DIR = abs_path(dirname($0)); |
22 | ||
23 | ||
24 | sub usage | |
25 | { | |
26 | print << 'USAGE'; | |
f47f1e2c DA |
27 | usage: git difftool [-t|--tool=<tool>] [-x|--extcmd=<cmd>] |
28 | [-y|--no-prompt] [-g|--gui] | |
29 | ['git diff' options] | |
5c38ea31 DA |
30 | USAGE |
31 | exit 1; | |
32 | } | |
33 | ||
34 | sub setup_environment | |
35 | { | |
36 | $ENV{PATH} = "$DIR:$ENV{PATH}"; | |
37 | $ENV{GIT_PAGER} = ''; | |
afcbc8e7 | 38 | $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper'; |
5c38ea31 DA |
39 | } |
40 | ||
41 | sub exe | |
42 | { | |
43 | my $exe = shift; | |
46ae156d DA |
44 | if ($^O eq 'MSWin32' || $^O eq 'msys') { |
45 | return "$exe.exe"; | |
46 | } | |
47 | return $exe; | |
5c38ea31 DA |
48 | } |
49 | ||
50 | sub generate_command | |
51 | { | |
52 | my @command = (exe('git'), 'diff'); | |
53 | my $skip_next = 0; | |
54 | my $idx = -1; | |
d531174f | 55 | my $prompt = ''; |
5c38ea31 DA |
56 | for my $arg (@ARGV) { |
57 | $idx++; | |
58 | if ($skip_next) { | |
59 | $skip_next = 0; | |
60 | next; | |
61 | } | |
46ae156d | 62 | if ($arg eq '-t' || $arg eq '--tool') { |
5c38ea31 | 63 | usage() if $#ARGV <= $idx; |
2464456a | 64 | $ENV{GIT_DIFF_TOOL} = $ARGV[$idx + 1]; |
5c38ea31 DA |
65 | $skip_next = 1; |
66 | next; | |
67 | } | |
68 | if ($arg =~ /^--tool=/) { | |
2464456a | 69 | $ENV{GIT_DIFF_TOOL} = substr($arg, 7); |
5c38ea31 DA |
70 | next; |
71 | } | |
f47f1e2c DA |
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 | } | |
4cefa495 | 82 | if ($arg eq '-g' || $arg eq '--gui') { |
42accaec DA |
83 | eval { |
84 | my $tool = Git::command_oneline('config', | |
85 | 'diff.guitool'); | |
86 | if (length($tool)) { | |
87 | $ENV{GIT_DIFF_TOOL} = $tool; | |
88 | } | |
89 | }; | |
4cefa495 DA |
90 | next; |
91 | } | |
8b733222 | 92 | if ($arg eq '-y' || $arg eq '--no-prompt') { |
d531174f | 93 | $prompt = 'no'; |
a904392e DA |
94 | next; |
95 | } | |
96 | if ($arg eq '--prompt') { | |
d531174f | 97 | $prompt = 'yes'; |
5c38ea31 DA |
98 | next; |
99 | } | |
8b733222 | 100 | if ($arg eq '-h' || $arg eq '--help') { |
5c38ea31 DA |
101 | usage(); |
102 | } | |
103 | push @command, $arg; | |
104 | } | |
d531174f RJ |
105 | if ($prompt eq 'yes') { |
106 | $ENV{GIT_DIFFTOOL_PROMPT} = 'true'; | |
107 | } elsif ($prompt eq 'no') { | |
108 | $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true'; | |
109 | } | |
5c38ea31 DA |
110 | return @command |
111 | } | |
112 | ||
113 | setup_environment(); | |
677fbff8 AR |
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. | |
e8d11804 AR |
120 | my $rc = system(generate_command()); |
121 | exit($rc | ($rc >> 8)); |