difftool: Eliminate global variables

Organize the script so that it has a single main() function which calls out to dir_diff() and file_diff() functions. This eliminates "dir-diff"-specific variables that do not need to be calculated when performing a regular file-diff. Signed-off-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

David Aguilar committed Jul 22, 2012 at 20:57 UTC 75cd75830993e3b545f2b151d8eea2f3178f9ba4
1 file changed +75 -53
git-difftool.perl
+75 -53
@@ -22,11 +22,6 @@ use File::Temp qw(tempdir);
22 use Getopt::Long qw(:config pass_through);
23 use Git;
24
25 -my @working_tree;
26 -my $rc;
27 -my $repo = Git->repository();
28 -my $repo_path = $repo->repo_path();
29 -
25 sub usage
26 {
27 my $exitcode = shift;
@@ -43,6 +38,8 @@ USAGE
38
39 sub find_worktree
40 {
41 + my ($repo) = @_;
42 +
43 # Git->repository->wc_path() does not honor changes to the working
44 # tree location made by $ENV{GIT_WORK_TREE} or the 'core.worktree'
45 # config variable.
@@ -61,8 +58,6 @@ sub find_worktree
58 return $worktree;
59 }
60
64 -my $workdir = find_worktree();
65 -
61 sub print_tool_help
62 {
63 my ($cmd, @found, @notfound);
@@ -97,10 +92,13 @@ sub print_tool_help
92
93 sub setup_dir_diff
94 {
95 + my ($repo, $workdir) = @_;
96 +
97 # Run the diff; exit immediately if no diff found
98 # 'Repository' and 'WorkingCopy' must be explicitly set to insure that
99 # if $GIT_DIR and $GIT_WORK_TREE are set in ENV, they are actually used
100 # by Git->repository->command*.
101 + my $repo_path = $repo->repo_path();
102 my $diffrepo = Git->repository(Repository => $repo_path, WorkingCopy => $workdir);
103 my $diffrtn = $diffrepo->command_oneline('diff', '--raw', '--no-abbrev', '-z', @ARGV);
104 exit(0) if (length($diffrtn) == 0);
@@ -121,6 +119,7 @@ sub setup_dir_diff
119 my $rindex = '';
120 my %submodule;
121 my %symlink;
122 + my @working_tree = ();
123 my @rawdiff = split('\0', $diffrtn);
124
125 my $i = 0;
@@ -188,7 +187,7 @@ sub setup_dir_diff
187 ($inpipe, $ctx) = $repo->command_input_pipe(qw/update-index -z --index-info/);
188 print($inpipe $lindex);
189 $repo->command_close_pipe($inpipe, $ctx);
191 - $rc = system('git', 'checkout-index', '--all', "--prefix=$ldir/");
190 + my $rc = system('git', 'checkout-index', '--all', "--prefix=$ldir/");
191 exit($rc | ($rc >> 8)) if ($rc != 0);
192
193 $ENV{GIT_INDEX_FILE} = "$tmpdir/rindex";
@@ -238,7 +237,7 @@ sub setup_dir_diff
237 }
238 }
239
241 - return ($ldir, $rdir);
240 + return ($ldir, $rdir, @working_tree);
241 }
242
243 sub write_to_file
@@ -261,54 +260,70 @@ sub write_to_file
260 close($fh);
261 }
262
264 -# parse command-line options. all unrecognized options and arguments
265 -# are passed through to the 'git diff' command.
266 -my ($difftool_cmd, $dirdiff, $extcmd, $gui, $help, $prompt, $tool_help);
267 -GetOptions('g|gui!' => \$gui,
268 - 'd|dir-diff' => \$dirdiff,
269 - 'h' => \$help,
270 - 'prompt!' => \$prompt,
271 - 'y' => sub { $prompt = 0; },
272 - 't|tool:s' => \$difftool_cmd,
273 - 'tool-help' => \$tool_help,
274 - 'x|extcmd:s' => \$extcmd);
275 -
276 -if (defined($help)) {
277 - usage(0);
278 -}
279 -if (defined($tool_help)) {
280 - print_tool_help();
281 -}
282 -if (defined($difftool_cmd)) {
283 - if (length($difftool_cmd) > 0) {
284 - $ENV{GIT_DIFF_TOOL} = $difftool_cmd;
285 - } else {
286 - print "No <tool> given for --tool=<tool>\n";
287 - usage(1);
263 +sub main
264 +{
265 + # parse command-line options. all unrecognized options and arguments
266 + # are passed through to the 'git diff' command.
267 + my ($difftool_cmd, $dirdiff, $extcmd, $gui, $help, $prompt, $tool_help);
268 + GetOptions('g|gui!' => \$gui,
269 + 'd|dir-diff' => \$dirdiff,
270 + 'h' => \$help,
271 + 'prompt!' => \$prompt,
272 + 'y' => sub { $prompt = 0; },
273 + 't|tool:s' => \$difftool_cmd,
274 + 'tool-help' => \$tool_help,
275 + 'x|extcmd:s' => \$extcmd);
276 +
277 + if (defined($help)) {
278 + usage(0);
279 }
289 -}
290 -if (defined($extcmd)) {
291 - if (length($extcmd) > 0) {
292 - $ENV{GIT_DIFFTOOL_EXTCMD} = $extcmd;
293 - } else {
294 - print "No <cmd> given for --extcmd=<cmd>\n";
295 - usage(1);
280 + if (defined($tool_help)) {
281 + print_tool_help();
282 }
297 -}
298 -if ($gui) {
299 - my $guitool = '';
300 - $guitool = Git::config('diff.guitool');
301 - if (length($guitool) > 0) {
302 - $ENV{GIT_DIFF_TOOL} = $guitool;
283 + if (defined($difftool_cmd)) {
284 + if (length($difftool_cmd) > 0) {
285 + $ENV{GIT_DIFF_TOOL} = $difftool_cmd;
286 + } else {
287 + print "No <tool> given for --tool=<tool>\n";
288 + usage(1);
289 + }
290 + }
291 + if (defined($extcmd)) {
292 + if (length($extcmd) > 0) {
293 + $ENV{GIT_DIFFTOOL_EXTCMD} = $extcmd;
294 + } else {
295 + print "No <cmd> given for --extcmd=<cmd>\n";
296 + usage(1);
297 + }
298 + }
299 + if ($gui) {
300 + my $guitool = '';
301 + $guitool = Git::config('diff.guitool');
302 + if (length($guitool) > 0) {
303 + $ENV{GIT_DIFF_TOOL} = $guitool;
304 + }
305 + }
306 +
307 + # In directory diff mode, 'git-difftool--helper' is called once
308 + # to compare the a/b directories. In file diff mode, 'git diff'
309 + # will invoke a separate instance of 'git-difftool--helper' for
310 + # each file that changed.
311 + if (defined($dirdiff)) {
312 + dir_diff($extcmd);
313 + } else {
314 + file_diff($prompt);
315 }
316 }
317
306 -# In directory diff mode, 'git-difftool--helper' is called once
307 -# to compare the a/b directories. In file diff mode, 'git diff'
308 -# will invoke a separate instance of 'git-difftool--helper' for
309 -# each file that changed.
310 -if (defined($dirdiff)) {
311 - my ($a, $b) = setup_dir_diff();
318 +sub dir_diff
319 +{
320 + my ($extcmd) = @_;
321 +
322 + my $rc;
323 + my $repo = Git->repository();
324 +
325 + my $workdir = find_worktree($repo);
326 + my ($a, $b, @working_tree) = setup_dir_diff($repo, $workdir);
327 if (defined($extcmd)) {
328 $rc = system($extcmd, $a, $b);
329 } else {
@@ -327,7 +342,12 @@ if (defined($dirdiff)) {
342 chmod(stat("$b/$file")->mode, "$workdir/$file") or die $!;
343 }
344 }
330 -} else {
345 +}
346 +
347 +sub file_diff
348 +{
349 + my ($prompt) = @_;
350 +
351 if (defined($prompt)) {
352 if ($prompt) {
353 $ENV{GIT_DIFFTOOL_PROMPT} = 'true';
@@ -347,3 +367,5 @@ if (defined($dirdiff)) {
367 my $rc = system('git', 'diff', @ARGV);
368 exit($rc | ($rc >> 8));
369 }
370 +
371 +main();