info-cvs
[Top][All Lists]
Advanced

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

Re: CVS corrupts binary files ...


From: Paul Sander
Subject: Re: CVS corrupts binary files ...
Date: Tue, 8 Jun 2004 14:45:23 -0700

Oops, I omitted the Sept. 16 patch.  Here it is at the bottom.

--- Forwarded mail from address@hidden

>--- Forwarded mail from address@hidden

>[ On Saturday, June 5, 2004 at 20:52:06 (-0700), Paul Sander wrote: ]
>> Subject: Re: CVS corrupts binary files ...
>>
>> Yeah, well, sending such hapless people away is easier
>> than fixing the tool.

>The tool is not "broken" -- I.e. there's nothing to fix!

>CVS is designed _only_ for tracking changes in human written text files.

So you say.  I maintain that the diff and merge tools can be easily
swapped out without making significant changes to the CVS design.
With regard to merge tools, I proved my point with a patch posted to
this forum on Sept. 16, 2001.  I've included that patch at the bottom
of this message.

>If you want to design (and implement) a new tool that does work well
>with non-text files then please do so.  That'll give us yet another tool
>to recommend people use when they want to.

No need.  See the patch below.

>>  Demonstrating that such support
>> could be added to CVS was done in less than eight man-hours;

>Nope -- it's just not possible, as you should well know.  This is a
>fundamental and purposeful design limitation in CVS.  The entire concept
>of concurrent editing, which is central to the design and goals of CVS,
>is completely antithetical to managing binary files.

I don't believe it was a "purposeful design limitation".  CVS was initially
designed before binary source formats were common, and it just didn't
happen to include a plug-in method to support them.

Keep in mind also that there's a difference between "binary files" and
"mergeable files".  The two concepts are in fact orthogonal; there are
mergeable binary types (given a suitable tool), and there are unmergeable
text types.  CVS is bad at storing unmergeable files, no matter whether
or not they're binary files.  CVS can be easily modified to support
mergeable binary types, as I've demonstrated, without significant impact
to its design.

>--- End of forwarded message from address@hidden


--- End of forwarded message from address@hidden

>From address@hidden Sun Sep 16 01:42:14 2001
X-Delivered: at request of sendmail on bugs
Received: from zul.wakawaka.com (zul.wakawaka.com [192.148.188.5])
        by bugs.wakawaka.com (8.8.8/8.8.5) with ESMTP id BAA11555
        for <address@hidden>; Sun, 16 Sep 2001 01:42:14 -0700 (PDT)
Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
        by zul.wakawaka.com (8.8.8/8.8.5) with ESMTP id BAA07411
        for <address@hidden>; Sun, 16 Sep 2001 01:46:33 -0700 (PDT)
Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org)
        by fencepost.gnu.org with esmtp (Exim 3.22 #1 (Debian))
        id 15iXGh-0007cp-00; Sun, 16 Sep 2001 04:27:11 -0400
Received: from zul.wakawaka.com ([205.219.70.4])
        by fencepost.gnu.org with esmtp (Exim 3.22 #1 (Debian))
        id 15iXEG-0007Se-00
        for <address@hidden>; Sun, 16 Sep 2001 04:24:40 -0400
Received: from bugs.wakawaka.com (bugs.wakawaka.com [192.148.188.8])
        by zul.wakawaka.com (8.8.8/8.8.5) with ESMTP id BAA07400
        for <address@hidden>; Sun, 16 Sep 2001 01:24:38 -0700 (PDT)
Received: from localhost (localhost [[UNIX: localhost]])
        by bugs.wakawaka.com (8.8.8/8.8.5) id BAA11542
        for address@hidden; Sun, 16 Sep 2001 01:20:53 -0700 (PDT)
Message-Id: <address@hidden>
From: address@hidden
In-Reply-To: <address@hidden>
X-Mailer: Mail User's Shell (7.2.6 beta(4)+dynamic 03/19/98)
To: address@hidden
Subject: Demo of extensible merge (was Re: giving up CVS)
Sender: address@hidden
Errors-To: address@hidden
X-BeenThere: address@hidden
X-Mailman-Version: 2.0.5
Precedence: bulk
List-Help: <mailto:address@hidden>
List-Post: <mailto:address@hidden>
List-Subscribe: <http://mail.gnu.org/mailman/listinfo/info-cvs>,
        <mailto:address@hidden>
List-Id: Announcements and discussions for the CVS version control system 
<info-cvs.gnu.org>
List-Unsubscribe: <http://mail.gnu.org/mailman/listinfo/info-cvs>,
        <mailto:address@hidden>
List-Archive: <http://mail.gnu.org/pipermail/info-cvs/>
Date: Sun, 16 Sep 2001 01:20:52 -0700
Status: OR

>--- Forwarded mail from Greg Woods:

>>  CVS is perfectly capable of supporting even
>> unmergable file types with only minor changes to its logic, specifically
>> by adding an extensible mechanism to select the correct merge tool for the
>> data type at hand.

>So you seem to claim.  So far though you've only proposed the most
>superficial of functional specifications, and certainly there's been no
>appearance of running code to cloud the issue....

I call your bluff and raise you a nickel...

>> This is only true as long as CVS treats everything as text files.  There
>> is nothing holding us back from modifying CVS to accomodate non-text
>> files in a meaningful way and still retain the concurrent development
>> paradigm intact.

>Go for it.  I look forward to seeing your "Binary CVS" edition in the
>very near future!

>Hopefully with it you can steal away all the people who are currently
>abusing the original CVS by trying to use it to manage change in
>projects containing binary files.  Best wishes and good riddance!  ;-)

No need.  The following patch to CVS v1.11 seems to do exactly what
I promised.

The following patch replaces the existing diff3-based merge algorithm
with the extensible one that I posted a while ago, with a slight
refinement.  The patch modifies the update.c and rcscmds.c files as
needed to that end (while removing special -kb handling), and changes
a single diagnostic that becomes misleading in this context.  It also
adds three Bourne Shell scripts:  cvsmerge is the top-level wrapper
that matches the working file's name to a regular expression and invokes
an appropriate merge tool.  cvsmerge.ascii invokes the usual diff3-based
merge.  cvsmerge.binary performs a simple two-way selection, taking the
version that differs from the common ancestor and indicating a conflict
if both contributors have changed.

This is simple demonstration code and is suitable only for those
who are willing to try new things in a test environment.  You must
modify the cvsmerge script to recognize the types of files at your
site.  It would be prudent to add a match of last resort to the end
of the list to maintain backward compatibility by invoking cvsmerge.ascii.

Constructive feedback is welcome.

>--- End of forwarded message from address@hidden

Index: tools/cvs/src/cvsmerge
diff -c /dev/null tools/cvs/src/cvsmerge:1.1.2.1
*** /dev/null   Sun Sep 16 01:05:14 2001
--- tools/cvs/src/cvsmerge      Sun Sep 16 01:00:25 2001
***************
*** 0 ****
--- 1,36 ----
+ #!/bin/sh
+ 
+ # Usage:  cvsmerge work ancestor contributor
+ 
+ me=`basename "$0"`
+ 
+ # The following table identifies the proper merge tool, based on the
+ # name of the working file.
+ 
+ cmd=`
+ cat <<EOF |
+ .*\.txt               cvsmerge.ascii
+ .*\.gif               cvsmerge.binary
+ .*\.jpg               cvsmerge.binary
+ EOF
+ 
+ # The following code plucks out the proper tool from the table above
+ # and invokes it.
+ 
+ sed -e 's/^/^/' -e 's/                */$     /' |
+ awk '-F       ' '
+ match(p1,$1)  { print $2 }
+ ' "p1=$1" |
+ head -1
+ `
+ 
+ if [ "x$cmd" = "x" ]
+ then
+       echo "${me}: Failed to locate the proper merge tool" 1>&2
+       exit 2
+ fi
+ 
+ echo "${me}: Invoking $cmd $1 $2 $3" 1>&2
+ $cmd "$1" "$2" "$3"
+ exit $?
+ 
Index: tools/cvs/src/cvsmerge.ascii
diff -c /dev/null tools/cvs/src/cvsmerge.ascii:1.1.2.1
*** /dev/null   Sun Sep 16 01:05:15 2001
--- tools/cvs/src/cvsmerge.ascii        Sun Sep 16 01:00:26 2001
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ 
+ diff3 -E -am -L "$1" -L "$2" -L "$3" "$1" "$2" "$3"
+ exit $?
Index: tools/cvs/src/cvsmerge.binary
diff -c /dev/null tools/cvs/src/cvsmerge.binary:1.1.2.1
*** /dev/null   Sun Sep 16 01:05:15 2001
--- tools/cvs/src/cvsmerge.binary       Sun Sep 16 01:00:26 2001
***************
*** 0 ****
--- 1,72 ----
+ #!/bin/sh
+ 
+ # merge.binary: 2-way selection merge program
+ 
+ # Usage:  merge.binary workfile ancestor contributor
+ 
+ me=`basename "$0"`
+ 
+ cmp "$1" "$2" > /dev/null
+ if [ $? = 0 ]
+ then
+       cmp "$2" "$3" > /dev/null
+       st=$?
+       if [ $st = 0 ]
+       then
+               # Files are identical, pick one
+               cat "$1"
+               if [ $? = 0 ]
+               then
+                       exit 0
+               else
+                       echo "${me}: Problem selecting workfile" 1>&2
+                       exit 2
+               fi
+       elif [ $st = 1 ]
+       then
+               # $3 differs from $1 and $2, pick it
+               cat "$3"
+               if [ $? = 0 ]
+               then
+                       exit 0
+               else
+                       echo "${me}: Problem selecting contributor" 1>&2
+                       exit 2
+               fi
+       else
+               echo "${me}: Problem comparing ancestor and contributor" 1>&2
+               exit 2
+       fi
+ else
+       cmp "$1" "$3" > /dev/null
+       st=$?
+       if [ $st = 0 ]
+       then
+               # $1 differs from $2 and $3, pick it
+               cat "$1"
+               if [ $? = 0 ]
+               then
+                       exit 0
+               else
+                       echo "${me}: Problem selecting workfile" 1>&2
+                       exit 2
+               fi
+       else
+               # Conflict
+               echo "${me}: Conflict between $1 and contributor" 1>&2
+               echo "${me}: Leaving $1 intact for manual merge" 1>&2
+               cat "$1"
+               if [ $? = 0 ]
+               then
+                       exit 1
+               else
+                       echo "${me}: Problem selecting workfile" 1>&2
+                       exit 2
+               fi
+       fi
+ fi
+ 
+ # Just in case
+ echo "${me}: Internal failure of binary selection merge" 1>&2
+ exit 2
+ 
Index: tools/cvs/src/rcscmds.c
diff -c tools/cvs/src/rcscmds.c:1.1.1.2 tools/cvs/src/rcscmds.c:1.1.1.2.4.1
*** tools/cvs/src/rcscmds.c:1.1.1.2     Sat Jan  8 23:38:27 2000
--- tools/cvs/src/rcscmds.c     Sun Sep 16 01:00:27 2001
***************
*** 297,302 ****
--- 297,303 ----
      /* Remember that the first word in the `call_diff_setup' string is used 
now
         only for diagnostic messages -- CVS no longer forks to run diff3. */
      diffout = cvs_temp_name();
+ #if 0
      call_diff_setup ("diff3");
      call_diff_arg ("-E");
      call_diff_arg ("-am");
***************
*** 313,318 ****
--- 314,328 ----
      call_diff_arg (tmp2);
  
      retval = call_diff3 (diffout);
+ #else
+     run_setup ("cvsmerge");
+ 
+     run_arg (workfile);
+     run_arg (tmp1);
+     run_arg (tmp2);
+ 
+     retval = run_exec(RUN_TTY,diffout,RUN_TTY,RUN_REALLY);
+ #endif
  
      if (retval == 1)
        cvs_outerr ("rcsmerge: warning: conflicts during merge\n", 0);
Index: tools/cvs/src/update.c
diff -c tools/cvs/src/update.c:1.3 tools/cvs/src/update.c:1.3.4.1
*** tools/cvs/src/update.c:1.3  Mon Jan 10 00:57:50 2000
--- tools/cvs/src/update.c      Sun Sep 16 01:00:27 2001
***************
*** 1897,1905 ****
--- 1897,1910 ----
      copy_file (finfo->file, backup);
      xchmod (finfo->file, 1);
  
+ #if 0
      if (strcmp (vers->options, "-kb") == 0
        || wrap_merge_is_copy (finfo->file)
        || special_file_mismatch (finfo, NULL, vers->vn_rcs))
+ #else
+     if ( wrap_merge_is_copy (finfo->file)
+       || special_file_mismatch (finfo, NULL, vers->vn_rcs))
+ #endif
      {
        /* For binary files, a merge is always a conflict.  Same for
           files whose permissions or linkage do not match.  We give the
***************
*** 2000,2007 ****
--- 2005,2018 ----
         xcmp on the temporary files without much hassle, I think.  */
      if (!noexec && !xcmp (backup, finfo->file))
      {
+ #if 0
        cvs_output (finfo->fullname, 0);
        cvs_output (" already contains the differences between ", 0);
+ #else
+       cvs_output ("If ",0);
+       cvs_output (finfo->fullname, 0);
+       cvs_output (" contains mergeable data, it may already contain the 
differences between ",0);
+ #endif
        cvs_output (vers->vn_user, 0);
        cvs_output (" and ", 0);
        cvs_output (vers->vn_rcs, 0);
***************
*** 2422,2430 ****
--- 2433,2446 ----
           print.  */
        write_letter (finfo, 'U');
      }
+ #if 0
      else if (strcmp (options, "-kb") == 0
             || wrap_merge_is_copy (finfo->file)
             || special_file_mismatch (finfo, rev1, rev2))
+ #else
+     else if ( wrap_merge_is_copy (finfo->file)
+            || special_file_mismatch (finfo, rev1, rev2))
+ #endif
      {
        /* We are dealing with binary files, or files with a
           permission/linkage mismatch, and real merging would

_______________________________________________
Info-cvs mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/info-cvs





reply via email to

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