bug-diffutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-diffutils] New diff option to compare file/directory properties


From: Duncan Moore
Subject: [bug-diffutils] New diff option to compare file/directory properties
Date: Mon, 27 Sep 2010 12:29:34 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.9) Gecko/20100915 Thunderbird/3.1.4

Here's a description and source of a new diff option to compare file and directory properties. I'd welcome any comments on the input and output formats, terminology, any other suggestions etc.

--compare=[content,time,mode,size,owner,group,all,objects]
This option provides a number of file properties to compare, for normal and both context output styles. Keyword 'content' means the file contents, and 'all' means all file properties (excluding 'objects'). A '~' prefix removes the keyword property. So --compare=all,~mode is the same as --compare=content,time,size,owner,group. The 'objects' keyword is not strictly a property. It means compare all 'file objects' with themselves and each other. By 'file objects', I mean regular files (including symbolic links), directories and special files (like 'character special files' etc, basically anything that's not a directory or regular file). Directories and special files are considered to be empty files as far as content is concerned. The intention is that --compare=all,objects gives enough information for 'patch' to be able to handle most changes to files and directory structures, other than changes to binary files. Note that special files are only handled in this way when in subdirectories. If specified at the top level, they would be treated like a regular file - this is in keeping with how 'diff' currently works.

Any difference in content or file properties causes the specified property information to be written to a modified context style header. Note that the keyword 'time' is not written - this saves space, and is more compatible with the existing context header line format.

  % diff -u --compare=all aaa bbb
--- aaa 2010-09-23 20:51:06.984375000 +0100 mode=-rw-r--r-- size=4 owner=Duncan group=None +++ bbb 2010-09-23 20:51:03.015625000 +0100 mode=-rwxr--r-- size=4 owner=Duncan group=None
  @@ -1 +1 @@
  -111
  +222

  % diff --compare=content aaa bbb
<<< aaa
>>> bbb
  1c1
< 111
  ---
> 222

  % diff --compare=mode c d
<<< c mode=-rw-r--r--
>>> d mode=-rwxr--r--

  % diff -r -u -N --compare=all,objects 6aDR 6bDR
  diff -r -u -N '--compare=all,objects' 6aDR 6bDR
--- 6aDR 2010-09-24 18:00:26.890625000 +0100 mode=drwxr-xr-x size=0 owner=Duncan group=None object=directory +++ 6bDR 2000-01-01 00:00:01.000000000 +0000 mode=drwxr-xr-x size=0 owner=Duncan group=None object=directory
  diff -r -u -N '--compare=all,objects' 6aDR/dir1 6bDR/dir1
--- 6aDR/dir1 1999-12-31 23:59:59.000000000 +0000 mode=drwxr-xr-x size=0 owner=Duncan group=None object=directory +++ 6bDR/dir1 2010-09-24 17:59:48.640625000 +0100 mode=drwxr-xr-x size=0 owner=Duncan group=None object=directory
  diff -r -u -N '--compare=all,objects' 6aDR/dir1/csf 6bDR/dir1/csf
  --- 6aDR/dir1/csf non-existent file
+++ 6bDR/dir1/csf 2010-09-24 17:59:48.640625000 +0100 mode=crw-rw-rw- size=0 owner=Duncan group=None object=character special file
  diff -r -u -N '--compare=all,objects' 6aDR/dir1/object2 6bDR/dir1/object2
--- 6aDR/dir1/object2 1999-12-31 23:59:59.000000000 +0000 mode=-rw-r--r-- size=2 owner=Duncan group=None object=regular file +++ 6bDR/dir1/object2 2000-01-01 00:00:01.000000000 +0000 mode=drwxr-xr-x size=0 owner=Duncan group=None object=directory
  @@ -1 +0,0 @@
  -a
diff -r -u -N '--compare=all,objects' 6aDR/dir1/object2/dir3 6bDR/dir1/object2/dir3
  --- 6aDR/dir1/object2/dir3 non-existent directory
+++ 6bDR/dir1/object2/dir3 2000-01-01 00:00:01.000000000 +0000 mode=drwxr-xr-x size=0 owner=Duncan group=None object=directory diff -r -u -N '--compare=all,objects' 6aDR/dir1/object2/dir3/file4 6bDR/dir1/object2/dir3/file4
  --- 6aDR/dir1/object2/dir3/file4 non-existent file
+++ 6bDR/dir1/object2/dir3/file4 2000-01-01 00:00:01.000000000 +0000 mode=-rw-r--r-- size=2 owner=Duncan group=None object=regular file
  @@ -0,0 +1 @@
  +a
  diff -r -u -N '--compare=all,objects' 6aDR/np 6bDR/np
--- 6aDR/np 2010-09-24 18:00:26.890625000 +0100 mode=prw-rw-rw- size=0 owner=Duncan group=None object=fifo
  +++ 6bDR/np non-existent file
  diff -r -u -N '--compare=all,objects' 6aDR/object1 6bDR/object1
--- 6aDR/object1 1999-12-31 23:59:59.000000000 +0000 mode=drwxr-xr-x size=0 owner=Duncan group=None object=directory +++ 6bDR/object1 2000-01-01 00:00:01.000000000 +0000 mode=-rw-r--r-- size=2 owner=Duncan group=None object=regular file
  @@ -0,0 +1 @@
  +a
diff -r -u -N '--compare=all,objects' 6aDR/object1/file2 6bDR/object1/file2 --- 6aDR/object1/file2 1999-12-31 23:59:59.000000000 +0000 mode=-rw-r--r-- size=2 owner=Duncan group=None object=regular file
  +++ 6bDR/object1/file2 non-existent file
  @@ -1 +0,0 @@
  -a

The --compare option format and the output format have been designed to balance the following criteria as much as possible:

a) backwards compatibility.
b) minimising the number of options.
c) making the output easy for users to read and 'patch' to process.

Alternative approaches for the format of the output header would have been to write only the specified file properties that actually differ. This would be more in keeping with what would normally be expected of 'diff' (i.e. show what's different, not what's the same). The properties could also have been written one per line e.g.:

  --- 6aDR/dir1/object2
  +++ 6bDR/dir1/object2
  --- time = 1999-12-31 23:59:59.000000000 +0000
  +++ time = 2000-01-01 00:00:01.000000000 +0000
  --- mode = -rw-r--r--
  +++ mode = drwxr-xr-x
  --- size = 2
  +++ size = 0
  --- object = regular file
  +++ object = directory

This would be a bit easier for 'patch' to process, but maybe less easy for the user to scan through. It would also be more prone to breaking any existing processors of 'diff' context output because there would be extra header lines. With the current approach, the property line can get quite long, but each property tends to be in roughly the same horizontal screen position, which makes it easier for users to scan through recursive diffs for a particular property. Something I haven't done, but which would fit in well with the 'one property per line' format is an option to not dereference links. (i.e. a --no-follow-link or --no-dereference option). This would cause symbolic links to be treated like any other special file, giving without --compare=all,objects a message like:

  File 6a/z is a regular file while file 6b/z is a symbolic link

and with --compare=all,objects, file properties relating to the link itself (rather than the file pointed to) and a header including:

  +++ object = symbolic link <name_of_the_file_pointed_to_here>

The only special files I've tested are 'character special files' and fifos, as I'm not too familar with most of them. There are probably special requirements for some of them that I'm unaware of.

Source changes are attached. If you want to test the updates out, you'll also need the gnulib modules filemode and idcache. (The new --if-different option (see yesterdays message) is also included in the source. The the two options are entirely distinct, but it's not too easy to disentangle the logic).




Attachment: KKK.patch
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]