Merge branch 'jk/diff-convfilter-test-fix'

* jk/diff-convfilter-test-fix:
  Avoid using non-portable `echo -n` in tests.
  add userdiff textconv tests
  document the diff driver textconv feature
  diff: add missing static declaration

Conflicts:
	Documentation/gitattributes.txt
This commit is contained in:
Junio C Hamano 2008-11-12 21:50:41 -08:00
commit 459d60084f
7 changed files with 178 additions and 20 deletions

View file

@ -216,10 +216,12 @@ Generating diff text
`diff`
^^^^^^
The attribute `diff` affects if 'git-diff' generates textual
patch for the path or just says `Binary files differ`. It also
can affect what line is shown on the hunk header `@@ -k,l +n,m @@`
line.
The attribute `diff` affects how 'git' generates diffs for particular
files. It can tell git whether to generate a textual patch for the path
or to treat the path as a binary file. It can also affect what line is
shown on the hunk header `@@ -k,l +n,m @@` line, tell git to use an
external command to generate the diff, or ask git to convert binary
files to a text format before generating the diff.
Set::
@ -230,7 +232,8 @@ Set::
Unset::
A path to which the `diff` attribute is unset will
generate `Binary files differ`.
generate `Binary files differ` (or a binary patch, if
binary patches are enabled).
Unspecified::
@ -241,21 +244,21 @@ Unspecified::
String::
Diff is shown using the specified custom diff driver.
The driver program is given its input using the same
calling convention as used for GIT_EXTERNAL_DIFF
program. This name is also used for custom hunk header
selection.
Diff is shown using the specified diff driver. Each driver may
specify one or more options, as described in the following
section. The options for the diff driver "foo" are defined
by the configuration variables in the "diff.foo" section of the
git config file.
Defining a custom diff driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defining an external diff driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The definition of a diff driver is done in `gitconfig`, not
`gitattributes` file, so strictly speaking this manual page is a
wrong place to talk about it. However...
To define a custom diff driver `jcdiff`, add a section to your
To define an external diff driver `jcdiff`, add a section to your
`$GIT_DIR/config` file (or `$HOME/.gitconfig` file) like this:
----------------------------------------------------------------
@ -331,6 +334,43 @@ patterns are available:
- `tex` suitable for source code for LaTeX documents.
Performing text diffs of binary files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sometimes it is desirable to see the diff of a text-converted
version of some binary files. For example, a word processor
document can be converted to an ASCII text representation, and
the diff of the text shown. Even though this conversion loses
some information, the resulting diff is useful for human
viewing (but cannot be applied directly).
The `textconv` config option is used to define a program for
performing such a conversion. The program should take a single
argument, the name of a file to convert, and produce the
resulting text on stdout.
For example, to show the diff of the exif information of a
file instead of the binary information (assuming you have the
exif tool installed):
------------------------
[diff "jpg"]
textconv = exif
------------------------
NOTE: The text conversion is generally a one-way conversion;
in this example, we lose the actual image contents and focus
just on the text data. This means that diffs generated by
textconv are _not_ suitable for applying. For this reason,
only `git diff` and the `git log` family of commands (i.e.,
log, whatchanged, show) will perform text conversion. `git
format-patch` will never generate this output. If you want to
send somebody a text-converted diff of a binary file (e.g.,
because it quickly conveys the changes you have made), you
should generate it separately and send it as a comment _in
addition to_ the usual binary diff that you might send.
Performing a three-way merge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2
diff.c
View file

@ -1283,7 +1283,7 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two)
emit_binary_diff_body(file, two, one);
}
void diff_filespec_load_driver(struct diff_filespec *one)
static void diff_filespec_load_driver(struct diff_filespec *one)
{
if (!one->driver)
one->driver = userdiff_find_by_path(one->path);

View file

@ -13,7 +13,7 @@ file if core.symlinks is false.'
test_expect_success \
'preparation' '
git config core.symlinks false &&
l=$(echo -n file | git hash-object -t blob -w --stdin) &&
l=$(printf file | git hash-object -t blob -w --stdin) &&
echo "120000 $l symlink" | git update-index --index-info'
test_expect_success \

View file

@ -13,12 +13,12 @@ even if a plain file is in the working tree if core.symlinks is false.'
test_expect_success \
'preparation' '
git config core.symlinks false &&
l=$(echo -n file | git hash-object -t blob -w --stdin) &&
l=$(printf file | git hash-object -t blob -w --stdin) &&
echo "120000 $l symlink" | git update-index --index-info'
test_expect_success \
'modify the symbolic link' '
echo -n new-file > symlink &&
printf new-file > symlink &&
git update-index symlink'
test_expect_success \

118
t/t4030-diff-textconv.sh Executable file
View file

@ -0,0 +1,118 @@
#!/bin/sh
test_description='diff.*.textconv tests'
. ./test-lib.sh
find_diff() {
sed '1,/^index /d' | sed '/^-- $/,$d'
}
cat >expect.binary <<'EOF'
Binary files a/file and b/file differ
EOF
cat >expect.text <<'EOF'
--- a/file
+++ b/file
@@ -1 +1,2 @@
0
+1
EOF
cat >hexdump <<'EOF'
#!/bin/sh
perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' "$1"
EOF
chmod +x hexdump
test_expect_success 'setup binary file with history' '
printf "\\0\\n" >file &&
git add file &&
git commit -m one &&
printf "\\1\\n" >>file &&
git add file &&
git commit -m two
'
test_expect_success 'file is considered binary by porcelain' '
git diff HEAD^ HEAD >diff &&
find_diff <diff >actual &&
test_cmp expect.binary actual
'
test_expect_success 'file is considered binary by plumbing' '
git diff-tree -p HEAD^ HEAD >diff &&
find_diff <diff >actual &&
test_cmp expect.binary actual
'
test_expect_success 'setup textconv filters' '
echo file diff=foo >.gitattributes &&
git config diff.foo.textconv "$PWD"/hexdump &&
git config diff.fail.textconv false
'
test_expect_failure 'diff produces text' '
git diff HEAD^ HEAD >diff &&
find_diff <diff >actual &&
test_cmp expect.text actual
'
test_expect_success 'diff-tree produces binary' '
git diff-tree -p HEAD^ HEAD >diff &&
find_diff <diff >actual &&
test_cmp expect.binary actual
'
test_expect_failure 'log produces text' '
git log -1 -p >log &&
find_diff <log >actual &&
test_cmp expect.text actual
'
test_expect_failure 'format-patch produces binary' '
git format-patch --no-binary --stdout HEAD^ >patch &&
find_diff <patch >actual &&
test_cmp expect.binary actual
'
cat >expect.stat <<'EOF'
file | Bin 2 -> 4 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
EOF
test_expect_failure 'diffstat does not run textconv' '
echo file diff=fail >.gitattributes &&
git diff --stat HEAD^ HEAD >actual &&
test_cmp expect.stat actual
'
# restore working setup
echo file diff=foo >.gitattributes
cat >expect.typechange <<'EOF'
--- a/file
+++ /dev/null
@@ -1,2 +0,0 @@
-0
-1
diff --git a/file b/file
new file mode 120000
index ad8b3d2..67be421
--- /dev/null
+++ b/file
@@ -0,0 +1 @@
+frotz
\ No newline at end of file
EOF
# make a symlink the hard way that works on symlink-challenged file systems
test_expect_failure 'textconv does not act on symlinks' '
printf frotz > file &&
git add file &&
git ls-files -s | sed -e s/100644/120000/ |
git update-index --index-info &&
git commit -m typechange &&
git show >diff &&
find_diff <diff >actual &&
test_cmp expect.typechange actual
'
test_done

View file

@ -18,11 +18,11 @@ git add file &&
git commit -m initial &&
git branch b-symlink &&
git branch b-file &&
l=$(echo -n file | git hash-object -t blob -w --stdin) &&
l=$(printf file | git hash-object -t blob -w --stdin) &&
echo "120000 $l symlink" | git update-index --index-info &&
git commit -m master &&
git checkout b-symlink &&
l=$(echo -n file-different | git hash-object -t blob -w --stdin) &&
l=$(printf file-different | git hash-object -t blob -w --stdin) &&
echo "120000 $l symlink" | git update-index --index-info &&
git commit -m b-symlink &&
git checkout b-file &&

View file

@ -424,7 +424,7 @@ cd "$WORKDIR"
test_expect_success 'cvs update (-p)' '
touch really-empty &&
echo Line 1 > no-lf &&
echo -n Line 2 >> no-lf &&
printf "Line 2" >> no-lf &&
git add really-empty no-lf &&
git commit -q -m "Update -p test" &&
git push gitcvs.git >/dev/null &&