Re: patchfs fix for unified diffs



On Tuesday, October 14, 2003 at 00:34, Pavel Roskin wrote:
[..]
> I like the idea, but I'm afraid your implementation is incomplete.  There
> are more cases when the file is split into parts by looking at at the
> separators only.  Let's see:
> 
> list - fixed in your patch
> copyout - fixed in your patch
> rm - not fixed
> copyin - not fixed

My version (4.6.0) had a more basic copyin and didn't support
rm at all.

> Is there any reason to handle rm and copyin differently?  Maybe it's
> better to put this code in one place?  Also, context diffs need this fix
> too, if I understand correctly.

Much code is duplicated all over that script. If I was to fix patchfs,
I'd rewrite it completely as a true VFS instead. Why? Because viewing
the last patch in the file requires the script to read through all
of the file! This could be fixed by keeping a table of indices in the
file the first time it was read. And extfs can't keep persistent data
like that right now, only VFS can.

About context diffs: It seems the same cannot be done for context
diffs. Sometimes unmodified lines are not included in those diffs
at all:

***************
*** 189,194 ****
--- 195,201 ----
            $state=$len=0;
        }
  
+       #foo
        $len+=length;
      }

This is not done in unified diffs.
Anyway, the attached patch fixes the copyin and rm commands as well.
(Not the way you and I would prefer, but it is better than a broken
patchfs.) It also fixed some bugs I introduced in the list and
copyout commands...

Regards,

Oskar (oskar osk mine nu)
diff -u patchfs.in.v0 patchfs.in
--- patchfs.in.v0	2003-10-14 09:27:07.000000000 +0200
+++ patchfs.in	2003-10-14 09:46:44.000000000 +0200
@@ -169,7 +169,14 @@
 	    }
 	}
 
-	if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
+	if ($state==1 && $unified && /^@@ -(\d+),(\d+) \+(\d+),(\d+) @@/) {
+	    my $lines = $2+$4;
+	    while ($lines > 0 && defined (my $line = <I>)) {
+    	    	$lines -= 1 if $line =~ /^[-+]/;
+    	    	$lines -= 2 if $line =~ /^ /;
+	    	$len += length $line;
+	    }
+	} elsif (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
 	    # start of new file
 	    if ($state==1) {
 		printf "-rw-r--r-- 1 %s %s %d %s %s%s\n", $uid, $gid, $len, datetime($time), $prefix, $f
@@ -218,7 +225,16 @@
 	    }
 	}
 
-	if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
+	if ($state==1 && $unified && /^@@ -(\d+),(\d+) \+(\d+),(\d+) @@/) {
+	    my $lines = $2+$4;
+	    $buf .= $_ if $found;
+	    while ($lines > 0 && defined ($_ = <I>)) {
+    	    	$lines -= 1 if /^[-+]/;
+    	    	$lines -= 2 if /^ /;
+		$buf .= $_ if $found;
+	    }
+	    next;
+	} elsif (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
 	    last if ($state==1 && $found);
 	    $state=1;
 
@@ -265,7 +281,16 @@
 	    }
 	}
 
-	if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
+	if ($state==1 && $unified && /^@@ -(\d+),(\d+) \+(\d+),(\d+) @@/) {
+	    my $lines = $2+$4;
+	    print $tmp $_ if !$found;
+	    while ($lines > 0 && defined ($_ = <I>)) {
+    	    	$lines -= 1 if /^[-+]/;
+    	    	$lines -= 2 if /^ /;
+		print $tmp $_ if !$found;
+	    }
+	    next;
+	} elsif (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
 	    $state=1;
 
 	    ($fsrc,$fdst,)=parse_header($unified,$context,\$_);
@@ -321,7 +346,13 @@
 	    $context=1 if (/^\*\*\* /);
 	}
 
-	if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
+	if ($unified && /^@@ -(\d+),(\d+) \+(\d+),(\d+) @@/) {
+	    my $lines = $2+$4;
+	    while ($lines > 0 && defined ($_ = <I>)) {
+    	    	$lines -= 1 if /^[-+]/;
+    	    	$lines -= 2 if /^ /;
+	    }
+	} elsif (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
 	    ($fsrc,$fdst,)=parse_header($unified,$context,\$_);
 	    ($f,)=diff_filename($fsrc,$fdst);
 	    push(@files,$f);


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