summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2012-02-04 22:10:40 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2012-02-04 22:13:48 -0800
commit7f2f4bb36593c0d2ed3284b3b8be2951fa6d5008 (patch)
tree4402d9e4bcc36130bc6350506deeae2f890f1445
parent62ca21c8c1a5aa3488589dcb191a4ef04ae9ed4f (diff)
downloaddiffutils-7f2f4bb36593c0d2ed3284b3b8be2951fa6d5008.tar.gz
diff: -N, --unidirectional-new-file now compare to "-" too
* NEWS: Document this. * doc/diffutils.texi (Comparing Directories): Likewise. Also, document that these options work at the top level. * src/diff.c (compare_files): Treat EBADF like ENOENT, to handle the case where "-" is closed. Allow the other file to be STDIN_FILENO, in case it's "-". * tests/Makefile.am (TESTS): Add new-file. * tests/new-file: New file.
-rw-r--r--NEWS5
-rw-r--r--doc/diffutils.texi33
-rw-r--r--src/diff.c16
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/new-file38
5 files changed, 68 insertions, 25 deletions
diff --git a/NEWS b/NEWS
index 808c603..5a69cd7 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU diffutils NEWS -*- outline -*-
* Noteworthy changes in release ?.? (????-??-??) [?]
+** New features
+
+ --new-file (-N) and --unidirectional-new-file now allow comparisons to "-".
+ A standard input that's closed acts like a nonexistent file.
+
* Noteworthy changes in release 3.2 (2011-09-02) [stable]
diff --git a/doc/diffutils.texi b/doc/diffutils.texi
index 00403df..d4a68f8 100644
--- a/doc/diffutils.texi
+++ b/doc/diffutils.texi
@@ -1784,20 +1784,23 @@ subdirectories' files, but if you use the @option{-r} or
@option{--recursive} option, it compares every corresponding pair of files
in the directory trees, as many levels deep as they go.
-For file names that are in only one of the directories, @command{diff}
-normally does not show the contents of the file that exists; it reports
-only that the file exists in that directory and not in the other. You
-can make @command{diff} act as though the file existed but was empty in the
-other directory, so that it outputs the entire contents of the file that
+If only one file exists, @command{diff} normally does not show its
+contents; it merely reports that one file exists but the other does
+not. You can make @command{diff} act as though the missing file is
+empty, so that it outputs the entire contents of the file that
actually exists. (It is output as either an insertion or a
-deletion, depending on whether it is in the first or the second
-directory given.) To do this, use the @option{--new-file} (@option{-N})
-option.
-
-If the older directory contains one or more large files that are not in
+deletion, depending on whether the missing file is in the first or the
+second position.) To do this, use the @option{--new-file}
+(@option{-N}) option. This option affects command-line arguments as
+well as files found via directory traversal; for example, @samp{diff
+-N a b} treats @file{a} as empty if @file{a} does not exist but
+@file{b} does, and similarly @samp{diff -N - b} treats standard input
+as empty if it is closed but @file{b} exists.
+
+If the older directory contains large files that are not in
the newer directory, you can make the patch smaller by using the
@option{--unidirectional-new-file} option instead of @option{-N}.
-This option is like @option{-N} except that it only inserts the contents
+This option is like @option{-N} except that it inserts the contents only
of files that appear in the second directory but not the first (that is,
files that were added). At the top of the patch, write instructions for
the user applying the patch to remove the files that were deleted before
@@ -3843,9 +3846,8 @@ specifies the number of lines affected. @xref{RCS}.
@item -N
@itemx --new-file
-In directory comparison, if a file is found in only one directory,
-treat it as present but empty in the other directory. @xref{Comparing
-Directories}.
+If one file is missing, treat it as present but empty.
+@xref{Comparing Directories}.
@item --new-group-format=@var{format}
Use @var{format} to output a group of lines taken from just the second
@@ -3937,8 +3939,7 @@ Use @var{format} to output a line common to both files in if-then-else
format. @xref{Line Formats}.
@item --unidirectional-new-file
-When comparing directories, if a file appears only in the second
-directory of the two, treat it as present but empty in the other.
+If a first file is missing, treat it as present but empty.
@xref{Comparing Directories}.
@item -U @var{lines}
diff --git a/src/diff.c b/src/diff.c
index 972d84d..200112b 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -92,15 +92,11 @@ static bool binary;
enum { binary = true };
#endif
-/* When comparing directories, if a file appears only in one
- directory, treat it as present but empty in the other (-N).
- Then 'patch' would create the file with appropriate contents. */
+/* If one file is missing, treat it as present but empty (-N). */
static bool new_file;
-/* When comparing directories, if a file appears only in the second
- directory of the two, treat it as present but empty in the other
- (--unidirectional-new-file).
- Then 'patch' would create the file with appropriate contents. */
+/* If the first file is missing, treat it as present but empty
+ (--unidirectional-new-file). */
static bool unidirectional_new_file;
/* Report files compared that are the same (-s).
@@ -1155,9 +1151,11 @@ compare_files (struct comparison const *parent,
? (S_ISREG (cmp.file[f].stat.st_mode)
&& ! (cmp.file[f].stat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))
&& cmp.file[f].stat.st_size == 0)
- : (cmp.file[f].desc == ERRNO_ENCODE (ENOENT)
+ : ((cmp.file[f].desc == ERRNO_ENCODE (ENOENT)
+ || cmp.file[f].desc == ERRNO_ENCODE (EBADF))
&& ! parent
- && cmp.file[1 - f].desc == UNOPENED)))
+ && (cmp.file[1 - f].desc == UNOPENED
+ || cmp.file[1 - f].desc == STDIN_FILENO))))
cmp.file[f].desc = NONEXISTENT;
for (f = 0; f < 2; f++)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2f6ad53..afc9aad 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -8,6 +8,7 @@ TESTS = \
help-version \
function-line-vs-leading-space \
label-vs-func \
+ new-file \
no-dereference \
no-newline-at-eof \
stdin
diff --git a/tests/new-file b/tests/new-file
new file mode 100755
index 0000000..af7cc4c
--- /dev/null
+++ b/tests/new-file
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Test --new-file (-N) and --unidirectional-new-file.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+fail=0
+
+echo a > a || fail=1
+
+echo '0a1
+> a' > exp || fail=1
+
+diff -N - a <&- > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file - a <&- > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff -N b - < a > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file b - < a > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+echo '1d0
+< a' > exp || fail=1
+
+diff -N a - <&- > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file a - <&- > out; test $? = 2 || fail=1
+
+diff -N - b < a > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file - b < a > out; test $? = 2 || fail=1
+
+Exit $fail