[Top][All Lists]
[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
- [Cvs-cvs] ccvs/src ChangeLog sanity.sh update.c [cvs1-11-x-branch],
Derek Robert Price <=