info-cvs
[Top][All Lists]
Advanced

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

Re: Is there anyway to not change a file when there are conflicts?


From: Paul Sander
Subject: Re: Is there anyway to not change a file when there are conflicts?
Date: Wed, 9 Jan 2002 09:44:13 -0800

Following is a demonstration-quality patch to show how CVS can be modified
to replace its existing merge capability with an extensible mechanism
that can be configured to handle merging in any way the CVS admin sees
fit.  What happens is that CVS' invocation diff3 to perform the merge is
replaced by an invocation of a shell script that looks up the name of
the file in a table an invokes the proper merge tool.  Examples are provided
to demonstrate merging binary files by selection and merging ASCII files
using diff3.

--- Forwarded mail from address@hidden

Here is the problem.  When CVS tries to merge a file and fails, it creates
the two different versions of the code snippit seperated by the
>>>>>=====<<<<<.  Or somesymbols like that.  We find that to be hard to deal
with most of the time.  We use another program called beyond compare to
merge the two together.  We do this by getting rid of the file it crearted
with those symbols and starting with the working copies modified file and
the newest repo version.  My question is.  Is there any way to leave the
file as is (in the not updated modified state) and mark it as having a
conflict?  We still want it to merge the two if there weren't conflicts.

--- 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




reply via email to

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