bug-cvs
[Top][All Lists]
Advanced

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

bug in cvs 1.11.22 regarding removed files


From: Paul Edwards
Subject: bug in cvs 1.11.22 regarding removed files
Date: Wed, 9 Jan 2008 20:29:48 +1100

This is a demonstration of a bug in CVS 1.11.22 plus a fix.

I tried to submit this about 4 years ago, but it was producing an
unexpected error and it was never resolved. I think I know why the
unexpected error occurred and have submitted a different fix.

Here are the changes against the latest CVS.  I can't actually run
sanity.sh on either of my systems.  On one system, Solaris's "id"
doesn't have "-u".  On the other, Cygwin is failing for unknown reason
(see check.log attached).  The test cases are thus the original ones
constructed by Mark 4 years ago based on the test cases that I
submitted that demonstrated the problem, except that I've updated them
to go into the latest CVS.

The problem occurs when one person modifies a file and another person
deletes the file.  CVS doesn't detect the conflict in some circumstances.

Please don't expose this email address I'm posting with, as this is my good
email address.  The address@hidden rarely seems to work, although it is
meant to, but I don't care about it being exposed.

Hopefully the fix will make it in this time! It's only been 4 years!!! I'm now back at the site where I discovered the problem in the first place, and checked
to see if the latest CVS had resolved the problem (the original patch I
submitted has been installed there - now the new one on the new CVS is).

I'm including the patch both instream and as a zip file. They're both the same, but I included the zip file in case the tabs get grunged by the mail system etc.

BFN.  Paul.


Index: ChangeLog
===================================================================
RCS file: /development/repository/ccvs/src/ChangeLog,v
retrieving revision 1.1.1.11
diff -c -r1.1.1.11 ChangeLog
*** ChangeLog 8 Jan 2008 04:29:48 -0000 1.1.1.11
--- ChangeLog 9 Jan 2008 01:45:20 -0000
***************
*** 1,3 ****
--- 1,9 ----
+ 2008-08-01  Paul Edwards <address@hidden>
+
+  * update.c (join_file): Detect deletion conflicts.
+  * sanity.sh (join,join4): Adjusted for this fix.
+    (join6,join7): Add new tests for conflicts.
+
 2006-06-08  Derek Price  <address@hidden>

  * sanity.sh (conflicts4): Test that the client honors Empty-conflicts.
***************
*** 2042,2048 ****

  * ignore.c (ignore_files): Use CVS_LSTAT() instead of lstat().
  * filesubr.c (xcmp): Make sure S_ISLNK exists before calling it.
!  (Reported by Paul Edwards <address@hidden>.)

 2003-10-31  Derek Price  <address@hidden>

--- 2048,2054 ----

  * ignore.c (ignore_files): Use CVS_LSTAT() instead of lstat().
  * filesubr.c (xcmp): Make sure S_ISLNK exists before calling it.
!  (Reported by Paul Edwards <address@hidden>.)

 2003-10-31  Derek Price  <address@hidden>

Index: sanity.sh
===================================================================
RCS file: /development/repository/ccvs/src/sanity.sh,v
retrieving revision 1.1.1.10
diff -c -r1.1.1.10 sanity.sh
*** sanity.sh 8 Jan 2008 04:30:13 -0000 1.1.1.10
--- sanity.sh 9 Jan 2008 01:45:20 -0000
***************
*** 1112,1118 ****
  tests="${tests} rcslib multibranch import importb importc import-CVS"
  tests="$tests import-quirks"
  tests="${tests} update-p import-after-initial branch-after-import"
!  tests="${tests} join join2 join3 join4 join5 join6 join7"
  tests="${tests} join-readonly-conflict join-admin join-admin-2"
  tests="${tests} join-rm"
  tests="${tests} new newb conflicts conflicts2 conflicts3 conflicts4"
--- 1112,1118 ----
  tests="${tests} rcslib multibranch import importb importc import-CVS"
  tests="$tests import-quirks"
  tests="${tests} update-p import-after-initial branch-after-import"
!  tests="${tests} join join2 join3 join4 join5 join6 join7 join8 join9"
  tests="${tests} join-readonly-conflict join-admin join-admin-2"
  tests="${tests} join-rm"
  tests="${tests} new newb conflicts conflicts2 conflicts3 conflicts4"
***************
*** 9124,9141 ****
 U first-dir/file2
'"${PROG}"' checkout: file first-dir/file2 exists, but has been added in revision T2
 U first-dir/file3
! '"${PROG}"' checkout: scheduling first-dir/file3 for removal
 U first-dir/file4
! '"${PROG}"' checkout: scheduling first-dir/file4 for removal
 U first-dir/file7
'"${PROG}"' checkout: file first-dir/file9 does not exist, but is present in revision T2'

    # Verify that the right changes have been scheduled.
    cd first-dir
    dotest join-17 "${testcvs} -q update" \
! 'A file1
! R file3
! R file4'

    # Modify file4 locally, and do an update with a merge.
    cd ../../1/first-dir
--- 9124,9139 ----
 U first-dir/file2
'"${PROG}"' checkout: file first-dir/file2 exists, but has been added in revision T2
 U first-dir/file3
! '"${PROG}"' checkout: file first-dir/file3 has been modified, but has been removed in revision T2
 U first-dir/file4
! '"${PROG}"' checkout: file first-dir/file4 has been modified, but has been removed in revision T2
 U first-dir/file7
'"${PROG}"' checkout: file first-dir/file9 does not exist, but is present in revision T2'

    # Verify that the right changes have been scheduled.
    cd first-dir
    dotest join-17 "${testcvs} -q update" \
! 'A file1'

    # Modify file4 locally, and do an update with a merge.
    cd ../../1/first-dir
***************
*** 9143,9149 ****
    dotest join-18 "${testcvs} -q update -jT1 -jT2 ." \
 'U file1
 '"${PROG}"' update: file file2 exists, but has been added in revision T2
! '"${PROG}"' update: scheduling file3 for removal
 M file4
'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2 '"${PROG}"' update: file file9 does not exist, but is present in revision T2'
--- 9141,9147 ----
    dotest join-18 "${testcvs} -q update -jT1 -jT2 ." \
 'U file1
 '"${PROG}"' update: file file2 exists, but has been added in revision T2
! '"${PROG}"' update: file file3 has been modified, but has been removed in revision T2
 M file4
'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2 '"${PROG}"' update: file file9 does not exist, but is present in revision T2'
***************
*** 9151,9157 ****
    # Verify that the right changes have been scheduled.
    dotest join-19 "${testcvs} -q update" \
 'A file1
- R file3
 M file4'

    # Do a checkout with a merge from a single revision.
--- 9149,9154 ----
***************
*** 9175,9181 ****
 retrieving revision 1\.1\.2\.2
 Merging differences between 1\.1 and 1\.1\.2\.2 into file2
 U first-dir/file3
! ${PROG} checkout: scheduling first-dir/file3 for removal
 U first-dir/file4
${PROG} checkout: file first-dir/file4 has been modified, but has been removed in revision branch
 U first-dir/file7
--- 9172,9178 ----
 retrieving revision 1\.1\.2\.2
 Merging differences between 1\.1 and 1\.1\.2\.2 into file2
 U first-dir/file3
! '"${PROG}"' update: scheduling file3 for removal
 U first-dir/file4
${PROG} checkout: file first-dir/file4 has been modified, but has been removed in revision branch
 U first-dir/file7
***************
*** 9209,9215 ****
 retrieving revision 1\.1
 retrieving revision 1\.1\.2\.2
 Merging differences between 1\.1 and 1\.1\.2\.2 into file2
! ${PROG} update: scheduling file3 for removal
 M file4
${PROG} update: file file4 is locally modified, but has been removed in revision branch ${PROG} update: file file9 does not exist, but is present in revision branch"
--- 9206,9212 ----
 retrieving revision 1\.1
 retrieving revision 1\.1\.2\.2
 Merging differences between 1\.1 and 1\.1\.2\.2 into file2
! '"${PROG}"' update: scheduling file3 for removal
 M file4
${PROG} update: file file4 is locally modified, but has been removed in revision branch ${PROG} update: file file9 does not exist, but is present in revision branch"
***************
*** 9803,9809 ****
 R file10
 A file2
 '"${PROG}"' update: file file2 exists, but has been added in revision T2
! '"${PROG}"' update: scheduling file3 for removal
 M file4
'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2
 R file6
--- 9800,9806 ----
 R file10
 A file2
 '"${PROG}"' update: file file2 exists, but has been added in revision T2
! '"${PROG}"' update: file file3 has been modified, but has been removed in revision T2
 M file4
'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2
 R file6
***************
*** 9817,9823 ****
 'A file1
 R file10
 A file2
- R file3
 M file4
 R file6
 A file7
--- 9814,9819 ----
***************
*** 10143,10148 ****
--- 10139,10256 ----



+         join8)
+           mkdir join8; cd join8
+           mkdir combine
+           mkdir base
+           mkdir pvcs
+           mkdir project
+
+           echo "aaa" >base/file.txt
+           echo "bbb" >pvcs/file.txt
+           echo "ccc" >project/xxx.txt
+
+           cd base
+           dotest join8-1 \
+ "${testcvs} import -b 1.1.101 -ko -m 'base import' join8 base base-1" \
+ "N join8/file\.txt
+
+ No conflicts created by this import"
+
+           cd ../pvcs
+           dotest join8-2 \
+ "${testcvs} import -b 1.1.201 -ko -m 'pvcs import' join8 pvcs pvcs-1" \
+ "C join8/file\.txt
+
+ 1 conflicts created by this import.
+ Use the following command to help the merge:
+
+ ${PROG} checkout -j<prev_rel_tag> -jpvcs-1 join8"
+
+           cd ../project
+           dotest join8-3 \
+ "${testcvs} import -b 1.1.301 -ko -m 'project import' join8 project p roject-1" \
+ "N join8/xxx\.txt
+
+ No conflicts created by this import"
+
+           cd ..
+           dotest join8-4 \
+ "${testcvs} checkout -r pvcs-1 -j base-1 -j project-1 -d combine join8" \
+ "${PROG} checkout: Updating combine
+ U combine/file\.txt
+ ${PROG} checkout: file combine/file\.txt has been modified, but has been removed in revision project-1
+ U combine/xxx\.txt"
+
+           cd ..
+
+           if $keep; then
+             echo Keeping ${TESTDIR} and exiting due to --keep
+                    exit 0
+           fi
+
+           rm -r join8
+           rm -rf ${CVSROOT_DIRNAME}/join8
+           ;;
+
+
+
+         join9)
+           mkdir join9; cd join9
+           mkdir combine
+           mkdir base
+           mkdir pvcs
+           mkdir project
+
+           echo "aaa" >base/file.txt
+           echo "aaa" >pvcs/file.txt
+           echo "ccc" >project/xxx.txt
+
+           cd base
+           dotest join9-1 \
+ "${testcvs} import -b 1.1.101 -ko -m 'base import' join9 base base-1" \
+ "N join9/file\.txt
+
+ No conflicts created by this import"
+
+           cd ../pvcs
+           dotest join9-2 \
+ "${testcvs} import -b 1.1.201 -ko -m 'pvcs import' join9 pvcs pvcs-1" \
+ "C join9/file\.txt
+
+ 1 conflicts created by this import.
+ Use the following command to help the merge:
+
+ ${PROG} checkout -j<prev_rel_tag> -jpvcs-1 join9"
+
+           cd ../project
+           dotest join9-3 \
+ "${testcvs} import -b 1.1.301 -ko -m 'project import' join9 project project-1" \
+ "N join9/xxx\.txt
+
+ No conflicts created by this import"
+
+           cd ..
+           dotest join9-4 \
+ "${testcvs} checkout -r pvcs-1 -j base-1 -j project-1 -d combine join9" \
+ "${PROG} checkout: Updating combine
+ U combine/file\.txt
+ ${PROG} checkout: scheduling combine/file\.txt for removal
+ U combine/xxx\.txt"
+
+           cd ..
+
+           if $keep; then
+             echo Keeping ${TESTDIR} and exiting due to --keep
+                    exit 0
+           fi
+
+           rm -r join9
+           rm -rf ${CVSROOT_DIRNAME}/join9
+          ;;
+
+
+
  join-readonly-conflict)
    # Previously, only tests 1 & 11 were being tested.  I added the
    # intermediate dotest's to try and diagnose a different failure
Index: update.c
===================================================================
RCS file: /development/repository/ccvs/src/update.c,v
retrieving revision 1.1.1.10
diff -c -r1.1.1.10 update.c
*** update.c 8 Jan 2008 04:30:04 -0000 1.1.1.10
--- update.c 9 Jan 2008 01:45:20 -0000
***************
*** 2218,2226 ****
     {
  char *mrev;

-  if (rev2 != NULL)
-      free (rev2);
-
  /* If the first revision doesn't exist either, then there is
            no change between the two revisions, so we don't do
            anything.  */
--- 2218,2223 ----
***************
*** 2228,2233 ****
--- 2225,2232 ----
  {
      if (rev1 != NULL)
   free (rev1);
+      if (rev2 != NULL)
+   free (rev2);
      return;
  }

***************
*** 2269,2274 ****
--- 2268,2275 ----
  {
      if (rev1 != NULL)
   free (rev1);
+      if (rev2 != NULL)
+   free (rev2);
      return;
  }

***************
*** 2295,2300 ****
--- 2296,2303 ----

      if (rev1 != NULL)
   free (rev1);
+      if (rev2 != NULL)
+   free (rev2);

      return;
  }
***************
*** 2320,2331 ****
--- 2323,2370 ----

      if (rev1 != NULL)
   free (rev1);
+      if (rev2 != NULL)
+   free (rev2);
+
+      return;
+  }
+
+  /* If the file has changed, genuinely changed,
+            in comparison to the greatest common ancestor (rev1),
+            then there is a conflict we can not resolve.  See above for
+            the rationale.  */
+  if ((strcmp (rev1, vers->vn_user) != 0)
+      && RCS_cmp_file(vers->srcfile,
+                         rev1,
+                         (char **)NULL,
+                         rev2,
+                         vers->options,
+                         finfo->file))
+  {
+      if (jdate2 != NULL)
+   error (0, 0,
+ "file %s has been modified, but has been removed in revision %s as of %s",
+          finfo->fullname, jrev2, jdate2);
+      else
+   error (0, 0,
+          "file %s has been modified, but has been removed in revision %s",
+          finfo->fullname, jrev2);
+
+      /* FIXME: Should we arrange to return a non-zero exit
+                status?  */
+
+      if (rev1 != NULL)
+   free (rev1);
+      if (rev2 != NULL)
+   free (rev2);

      return;
  }

  if (rev1 != NULL)
      free (rev1);
+  if (rev2 != NULL)
+      free (rev2);

  /* The user file exists and has not been modified.  Mark it
            for removal.  FIXME: If we are doing a checkout, this has

reply via email to

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