difftool --dir-diff: symlink all files matching the working tree
Some users like to edit files in their diff tool when using "git difftool --dir-diff --symlink" to compare against the working tree but difftool currently only created symlinks when a file contains unstaged changes. Change this behaviour so that symlinks are created whenever the right-hand side of the comparison has the same SHA1 as the file in the working tree. Note that textconv filters are handled in the same way as by git-diff and if a clean filter is not the inverse of its smudge filter we already get a null SHA1 from "diff --raw" and will symlink the file without going through the new hash-object based check. Signed-off-by: John Keeping <john@keeping.me.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									e0976dcf83
								
							
						
					
					
						commit
						02c56314aa
					
				|  | @ -72,7 +72,9 @@ with custom merge tool commands and has the same value as `$MERGED`. | |||
| --symlinks:: | ||||
| --no-symlinks:: | ||||
| 	'git difftool''s default behavior is create symlinks to the | ||||
| 	working tree when run in `--dir-diff` mode. | ||||
| 	working tree when run in `--dir-diff` mode and the right-hand | ||||
| 	side of the comparison yields the same content as the file in | ||||
| 	the working tree. | ||||
| + | ||||
| Specifying `--no-symlinks` instructs 'git difftool' to create copies | ||||
| instead.  `--no-symlinks` is the default on Windows. | ||||
|  |  | |||
|  | @ -83,6 +83,21 @@ sub exit_cleanup | |||
| 	exit($status | ($status >> 8)); | ||||
| } | ||||
|  | ||||
| sub use_wt_file | ||||
| { | ||||
| 	my ($repo, $workdir, $file, $sha1, $symlinks) = @_; | ||||
| 	my $null_sha1 = '0' x 40; | ||||
|  | ||||
| 	if ($sha1 eq $null_sha1) { | ||||
| 		return 1; | ||||
| 	} elsif (not $symlinks) { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	my $wt_sha1 = $repo->command_oneline('hash-object', "$workdir/$file"); | ||||
| 	return $sha1 eq $wt_sha1; | ||||
| } | ||||
|  | ||||
| sub setup_dir_diff | ||||
| { | ||||
| 	my ($repo, $workdir, $symlinks) = @_; | ||||
|  | @ -159,10 +174,10 @@ EOF | |||
| 		} | ||||
|  | ||||
| 		if ($rmode ne $null_mode) { | ||||
| 			if ($rsha1 ne $null_sha1) { | ||||
| 				$rindex .= "$rmode $rsha1\t$dst_path\0"; | ||||
| 			} else { | ||||
| 			if (use_wt_file($repo, $workdir, $dst_path, $rsha1, $symlinks)) { | ||||
| 				push(@working_tree, $dst_path); | ||||
| 			} else { | ||||
| 				$rindex .= "$rmode $rsha1\t$dst_path\0"; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -370,6 +370,28 @@ test_expect_success PERL 'difftool --dir-diff' ' | |||
| 	echo "$diff" | stdin_contains file | ||||
| ' | ||||
|  | ||||
| write_script .git/CHECK_SYMLINKS <<\EOF | ||||
| for f in file file2 sub/sub | ||||
| do | ||||
| 	echo "$f" | ||||
| 	readlink "$2/$f" | ||||
| done >actual | ||||
| EOF | ||||
|  | ||||
| test_expect_success PERL,SYMLINKS 'difftool --dir-diff --symlink without unstaged changes' ' | ||||
| 	cat >expect <<-EOF && | ||||
| 	file | ||||
| 	$(pwd)/file | ||||
| 	file2 | ||||
| 	$(pwd)/file2 | ||||
| 	sub/sub | ||||
| 	$(pwd)/sub/sub | ||||
| 	EOF | ||||
| 	git difftool --dir-diff --symlink \ | ||||
| 		--extcmd "./.git/CHECK_SYMLINKS" branch HEAD && | ||||
| 	test_cmp actual expect | ||||
| ' | ||||
|  | ||||
| test_expect_success PERL 'difftool --dir-diff ignores --prompt' ' | ||||
| 	diff=$(git difftool --dir-diff --prompt --extcmd ls branch) && | ||||
| 	echo "$diff" | stdin_contains sub && | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 John Keeping
						John Keeping