cvs-cvs
[Top][All Lists]
Advanced

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

[Cvs-cvs] ccvs/src ChangeLog sanity.sh update.c [cvs1-11-x-branch]


From: Derek Robert Price
Subject: [Cvs-cvs] ccvs/src ChangeLog sanity.sh update.c [cvs1-11-x-branch]
Date: Tue, 29 Jan 2008 20:34:39 +0000

CVSROOT:        /cvsroot/cvs
Module name:    ccvs
Branch:         cvs1-11-x-branch
Changes by:     Derek Robert Price <dprice>     08/01/29 20:34:37

Modified files:
        src            : ChangeLog sanity.sh update.c 

Log message:
        * update.c (join_file): Detect deletion conflicts.
        * sanity.sh (join, join4): Adjusted for this fix.
          (join8, join9): Add new tests for conflicts.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/ccvs/src/ChangeLog?cvsroot=cvs&only_with_tag=cvs1-11-x-branch&r1=1.2336.2.499&r2=1.2336.2.500
http://cvs.savannah.gnu.org/viewcvs/ccvs/src/sanity.sh?cvsroot=cvs&only_with_tag=cvs1-11-x-branch&r1=1.752.2.215&r2=1.752.2.216
http://cvs.savannah.gnu.org/viewcvs/ccvs/src/update.c?cvsroot=cvs&only_with_tag=cvs1-11-x-branch&r1=1.202.4.30&r2=1.202.4.31

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/cvs/ccvs/src/ChangeLog,v
retrieving revision 1.2336.2.499
retrieving revision 1.2336.2.500
diff -u -b -r1.2336.2.499 -r1.2336.2.500
--- ChangeLog   28 Jan 2008 01:22:52 -0000      1.2336.2.499
+++ ChangeLog   29 Jan 2008 20:34:34 -0000      1.2336.2.500
@@ -1,3 +1,10 @@
+2008-01-29  Derek R. Price  <address@hidden>
+           Paul Edwards  <address@hidden>
+
+       * update.c (join_file): Detect deletion conflicts.
+       * sanity.sh (join, join4): Adjusted for this fix.
+         (join8, join9): Add new tests for conflicts.
+
 2008-01-27  Mark D. Baushke  <address@hidden>
 
        * filesubr.c (xreadlink): s/128/BUFSIZ/ avoid magic numbers.
@@ -2281,7 +2288,7 @@
 
        * 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>.)
+       (Reported by Paul Edwards <address@hidden>.)
 
 2003-10-31  Derek Price  <address@hidden>
 

Index: sanity.sh
===================================================================
RCS file: /cvsroot/cvs/ccvs/src/sanity.sh,v
retrieving revision 1.752.2.215
retrieving revision 1.752.2.216
diff -u -b -r1.752.2.215 -r1.752.2.216
--- sanity.sh   25 Jan 2008 00:11:30 -0000      1.752.2.215
+++ sanity.sh   29 Jan 2008 20:34:35 -0000      1.752.2.216
@@ -1172,7 +1172,7 @@
        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 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"
@@ -5469,9 +5469,10 @@
                fi
 
                # and join
-               dotest 95 "${testcvs} -q update -j HEAD" \
-"${PROG}"' update: file file1 has been modified, but has been removed in 
revision HEAD
-'"${PROG}"' update: file file3 exists, but has been added in revision HEAD'
+               dotest 95 "$testcvs -q update -j HEAD" \
+"$PROG update: file file1 is modified since GCA (1\.3), but has been removed 
in revision HEAD
+C file1
+$PROG update: file file3 exists, but has been added in revision HEAD"
 
                dotest_fail death-file4-7 "test -f file4" ''
 
@@ -9340,40 +9341,42 @@
          cd ../..
          mkdir 3
          cd 3
-         dotest join-16 "${testcvs} -q co -jT1 -jT2 first-dir" \
-'U first-dir/file1
+         dotest join-16 "$testcvs -q co -jT1 -jT2 first-dir" \
+"U first-dir/file1
 U first-dir/file2
-'"${PROG}"' checkout: file first-dir/file2 exists, but has been added in 
revision T2
+$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
+$PROG checkout: scheduling first-dir/file3 for removal
 U first-dir/file4
-'"${PROG}"' checkout: scheduling first-dir/file4 for removal
+$PROG checkout: file first-dir/file4 is modified since GCA (1\.1), but has 
been removed in revision T2
+C first-dir/file4
 U first-dir/file7
-'"${PROG}"' checkout: file first-dir/file9 does not exist, but is present in 
revision T2'
+$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" \
+         dotest_fail join-17 "$testcvs -q update" \
 'A file1
 R file3
-R file4'
+C file4'
 
          # Modify file4 locally, and do an update with a merge.
          cd ../../1/first-dir
          echo 'third revision of file4' > file4
-         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
+         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'
+$PROG update: file file4 is locally modified, but has been removed in revision 
T2
+C file4
+$PROG update: file file9 does not exist, but is present in revision T2"
 
          # Verify that the right changes have been scheduled.
-         dotest join-19 "${testcvs} -q update" \
+         dotest_fail join-19 "$testcvs -q update" \
 'A file1
 R file3
-M file4'
+C file4'
 
          # Do a checkout with a merge from a single revision.
 
@@ -9388,27 +9391,29 @@
          # on branches.
          cd ../../3
          rm -r first-dir
-         dotest join-20 "${testcvs} -q co -jbranch first-dir" \
+         dotest join-20 "$testcvs -q co -jbranch first-dir" \
 "U first-dir/file1
 U first-dir/file2
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
 retrieving revision 1\.1
 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
+$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
+$PROG checkout: file first-dir/file4 is modified since GCA (1\.1), but has 
been removed in revision branch
+C first-dir/file4
 U first-dir/file7
-${PROG} checkout: file first-dir/file9 does not exist, but is present in 
revision branch"
+$PROG checkout: file first-dir/file9 does not exist, but is present in 
revision branch"
 
          # Verify that the right changes have been scheduled.
          # The M file2 line is a bug; see above join-20.
          cd first-dir
-         dotest join-21 "${testcvs} -q update" \
+         dotest_fail join-21 "$testcvs -q update" \
 'A file1
 M file2
-R file3'
+R file3
+C file4'
 
          # Checkout the main line again.
          cd ../../1
@@ -9424,24 +9429,25 @@
          # The file2 handling is a bug; see above join-20.
          cd first-dir
          echo 'third revision of file4' > file4
-         dotest join-23 "${testcvs} -q update -jbranch ." \
+         dotest join-23 "$testcvs -q update -jbranch ." \
 "U file1
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
 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
+$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"
+$PROG update: file file4 is locally modified, but has been removed in revision 
branch
+C file4
+$PROG update: file file9 does not exist, but is present in revision branch"
 
          # Verify that the right changes have been scheduled.
          # The M file2 line is a bug; see above join-20
-         dotest join-24 "${testcvs} -q update" \
+         dotest_fail join-24 "$testcvs -q update" \
 'A file1
 M file2
 R file3
-M file4'
+C file4'
 
          cd ..
 
@@ -9467,21 +9473,23 @@
          # The handling of file8 and file9 here look fishy to me.  I don't
          # see why it should be different from the case where we merge to
          # the trunk (e.g. join-23).
-         dotest join-28 "${testcvs} -q update -j branch" \
+         dotest join-28 "$testcvs -q update -j branch" \
 "U file1
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-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
-${PROG} update: file file4 has been modified, but has been removed in revision 
branch
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
+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
+$PROG update: file file4 is modified since GCA (1\.1), but has been removed in 
revision branch
+C file4
 U file8
 U file9"
          # Verify that the right changes have been scheduled.
-         dotest join-29 "${testcvs} -q update" \
+         dotest_fail join-29 "$testcvs -q update" \
 "A file1
 M file2
 R file3
+C file4
 A file8
 A file9"
 
@@ -9499,28 +9507,30 @@
 U first-dir/file8
 U first-dir/file9'
          cd first-dir
-         dotest join-twobranch-2 "${testcvs} -q update -rbr2 -jbranch" \
-"${PROG} update: file1 is no longer in the repository
+         dotest join-twobranch-2 "$testcvs -q update -rbr2 -jbranch" \
+"$PROG update: file1 is no longer in the repository
 U file1
 U file2
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
 retrieving revision 1\.1
 retrieving revision 1\.1\.2\.2
 Merging differences between 1\.1 and 1\.1\.2\.2 into file2
 U file3
-${PROG} update: scheduling file3 for removal
+$PROG update: scheduling file3 for removal
 U file4
-${PROG} update: file file4 has been modified, but has been removed in revision 
branch
+$PROG update: file file4 is modified since GCA (1\.1), but has been removed in 
revision branch
+C file4
 U file7
-${PROG} update: file8 is no longer in the repository
+$PROG update: file8 is no longer in the repository
 U file8
-${PROG} update: file9 is no longer in the repository
+$PROG update: file9 is no longer in the repository
 U file9"
          # Verify that the right changes have been scheduled.
-         dotest join-twobranch-3 "${testcvs} -q update" \
+         dotest_fail join-twobranch-3 "$testcvs -q update" \
 "A file1
 M file2
 R file3
+C file4
 A file8
 A file9"
 
@@ -10023,27 +10033,28 @@
          # Modify file4 locally, and do an update with a merge.
          cd ../../1/first-dir
          echo 'third revision of file4' > file4
-         dotest join4-18 "${testcvs} -q update -jT1 -jT2 ." \
-'U file1
+         dotest join4-18 "$testcvs -q update -jT1 -jT2 ." \
+"U file1
 R file10
 A file2
-'"${PROG}"' update: file file2 exists, but has been added in revision T2
-'"${PROG}"' update: scheduling file3 for removal
+$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 file4 is locally modified, but has been removed in revision 
T2
+C file4
 R file6
 A file7
 R file8
 R file9
-'"${PROG}"' update: file file9 does not exist, but is present in revision T2'
+$PROG update: file file9 does not exist, but is present in revision T2"
 
          # Verify that the right changes have been scheduled.
-         dotest join4-19 "${testcvs} -q update" \
+         dotest_fail join4-19 "${testcvs} -q update" \
 'A file1
 R file10
 A file2
 R file3
-M file4
+C file4
 R file6
 A file7
 R file8
@@ -10368,6 +10379,128 @@
 
 
 
+        join8)
+         # In this test case, we have 2 projects, one called "pvcs" and one
+         # called "project".  The "pvcs" project has modified the file, while
+         # the "project" project has caused a deletion.  When "project" is
+         # merged into "pvcs", we expect CVS to detect a conflict.
+          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 project-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 is modified since GCA (1\.1), but has 
been removed in revision project-1
+C combine/file.txt
+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)
+         # In this test case, we have 2 projects, one called "pvcs" and one
+         # called "project".  The "pvcs" project has not modified the file,
+         # while the "project" project has caused a deletion.  When "project"
+         # is merged into "pvcs", we expect CVS to remove the file without
+         # fuss, as there is no conflict.
+          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: /cvsroot/cvs/ccvs/src/update.c,v
retrieving revision 1.202.4.30
retrieving revision 1.202.4.31
diff -u -b -r1.202.4.30 -r1.202.4.31
--- update.c    24 Aug 2006 17:33:26 -0000      1.202.4.30
+++ update.c    29 Jan 2008 20:34:37 -0000      1.202.4.31
@@ -1435,8 +1435,10 @@
            /* fix up the vers structure, in case it is used by join */
            if (join_rev1)
            {
-               /* FIXME: Throwing away the original revision info is almost
-                  certainly wrong -- what if join_rev1 is "BASE"?  */
+               /* FIXME: It seems like we should be preserving ts_user
+                * & ts_rcs here, but setting them causes problems in
+                * join_file().
+                */
                if (vers_ts->vn_user != NULL)
                    free (vers_ts->vn_user);
                if (vers_ts->vn_rcs != NULL)
@@ -2207,9 +2209,8 @@
     if (rev2 == NULL || RCS_isdead (vers->srcfile, rev2))
     {
        char *mrev;
-
-       if (rev2 != NULL)
-           free (rev2);
+       short conflict = 0;
+       char *modmsg = NULL;
 
        /* If the first revision doesn't exist either, then there is
            no change between the two revisions, so we don't do
@@ -2218,6 +2219,8 @@
        {
            if (rev1 != NULL)
                free (rev1);
+           if (rev2 != NULL)
+               free (rev2);
            return;
        }
 
@@ -2257,8 +2260,9 @@
            || vers->vn_user[0] == '-'
            || RCS_isdead (vers->srcfile, vers->vn_user))
        {
-           if (rev1 != NULL)
                free (rev1);
+           if (rev2 != NULL)
+               free (rev2);
            return;
        }
 
@@ -2267,55 +2271,113 @@
           resolve.  No_Difference will already have been called in
           this case, so comparing the timestamps is sufficient to
           determine whether the file is locally modified.  */
-       if (strcmp (vers->vn_user, "0") == 0
-           || (vers->ts_user != NULL
-               && strcmp (vers->ts_user, vers->ts_rcs) != 0))
+       if (/* added */ !strcmp (vers->vn_user, "0")
+           || /* locally modified */
+              vers->ts_user && strcmp (vers->ts_user, vers->ts_rcs))
+           conflict = 1;
+
+       if (!conflict
+           && /* may have changed */
+              strcmp (rev1, vers->vn_user))
+       {
+           /* The removal should happen if either the file has never changed
+            * on the destination or the file has changed to be identical to
+            * the first join revision.
+            *
+            * ------R-----------D
+            *       |
+            *       \----J1---J2-----S
+            *
+            * So:
+            *
+            * J2 is dead.
+            * D is destination.
+            * R is source branch root/GCA.
+            * if J1 == D       removal should happen
+            * if D == R        removal should happen
+            * otherwise, fail.
+            *
+            * (In the source, J2 = REV2, D = VN_USER, R = GCA computed below)
+            */
+           char *gca_rev1 = gca (rev1, vers->vn_user);
+           if (/* genuinely changed on destination branch */
+               RCS_cmp_file (vers->srcfile, gca_rev1, NULL,
+                             vers->vn_user, vers->options, finfo->file)
+               && /* genuinely different from REV1 */
+                  RCS_cmp_file (vers->srcfile, rev1, NULL,
+                                vers->vn_user, vers->options, finfo->file))
        {
-           if (jdate2 != NULL)
-               error (0, 0,
-                      "file %s is locally modified, but has been removed in 
revision %s as of %s",
-                      finfo->fullname, jrev2, jdate2);
-           else
-               error (0, 0,
-                      "file %s is locally modified, but has been removed in 
revision %s",
-                      finfo->fullname, jrev2);
+               conflict = 1;
+               modmsg = xmalloc (14 + strlen (gca_rev1));
+               sprintf (modmsg, " since GCA (%s)", gca_rev1);
+           }
+       }
 
-           /* FIXME: Should we arrange to return a non-zero exit
-               status?  */
+       if (conflict)
+       {
+           const char *locally;
+           char *cp;
 
-           if (rev1 != NULL)
-               free (rev1);
+           if (!modmsg)
+               modmsg = xstrdup ("");
 
-           return;
-       }
+           if (/* added */ !strcmp (vers->vn_user, "0")
+               || /* locally modified */
+                  vers->ts_user && strcmp (vers->ts_user, vers->ts_rcs))
+               locally = " locally";
+           else
+               locally = "";
 
-       /* If only one join tag was specified, and the user file has
-           been changed since the greatest common ancestor (rev1),
-           then there is a conflict we can not resolve.  See above for
-           the rationale.  */
-       if (join_rev2 == NULL
-           && strcmp (rev1, vers->vn_user) != 0)
-       {
-           if (jdate2 != NULL)
+           if (jdate2)
                error (0, 0,
-                      "file %s has been modified, but has been removed in 
revision %s as of %s",
-                      finfo->fullname, jrev2, jdate2);
+                      "file %s is%s modified%s, but has been removed in 
revision %s as of %s",
+                      finfo->fullname, locally, modmsg, jrev2, jdate2);
            else
                error (0, 0,
-                      "file %s has been modified, but has been removed in 
revision %s",
-                      finfo->fullname, jrev2);
+                      "file %s is%s modified%s, but has been removed in 
revision %s",
+                      finfo->fullname, locally, modmsg, jrev2);
+
+           /* Register the conflict with the client.  */
+           if (trace)
+               fprintf (stderr, "%s-> join_file: ts=%s, conflict=%s\n",
+                        CLIENT_SERVER_STR, vers->ts_user, vers->ts_conflict);
 
-           /* FIXME: Should we arrange to return a non-zero exit
-               status?  */
+           /* FIXME: vers->ts_user should always be set here but sometimes
+            * isn't, namely when checkout_file() has just created the file,
+            * but simply setting it in checkout_file() appears to cause other
+            * problems.
+            */
+           if (isfile (finfo->file))
+               cp = time_stamp (finfo->file);
+           else
+               cp = xstrdup (vers->ts_user);
 
-           if (rev1 != NULL)
+           Register (finfo->entries, finfo->file, vers->vn_user,
+                     "Result of merge", vers->options, vers->tag, vers->date,
+                     cp);
+           write_letter (finfo, 'C');
+           free (cp);
+
+#ifdef SERVER_SUPPORT
+           /* Abuse server_checked_in() to send the updated entry without
+            * needing to update the file.
+            */
+           if (server_active)
+               server_checked_in (finfo->file, finfo->update_dir,
+                                  finfo->repository);
+#endif
+
+           free (modmsg);
                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]