Newsgroups: comp.sources.bugs Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!zaphod.mps.ohio-state.edu!van-bc!ubc-cs!uw-beaver!fluke!lowell From: lowell@tc.fluke.COM (Lowell Skoog) Subject: CVS 1.2 bug: CVS update doesn't handle merge correctly Message-ID: <1991May23.220032.1602@tc.fluke.COM> Organization: John Fluke Mfg. Co., Inc., Everett, WA Date: Thu, 23 May 91 22:00:32 GMT Symptom: When you run CVS update to merge changes that have been committed to the repository with changes made in your working file, the command bails out if there are any conflicts during the merge. It does not register that the update took place. If you resolve the conflicts and attempt to commit the working file, the CVS commit command will tell you that the file needs to be updated first. It is vicious cycle. Work-around: Save your original working file by renaming it. Run CVS update to get an updated copy. Perform the merge by hand. Then commit your changes. Cause: In RCS 5.5, rcsmerge returns a status similar to diff(1). (0 = no conflicts, 1 = conflicts, 2 = trouble) CVS 1.0 was written for an older version of rcsmerge. (CVS 1.2 failed to correct this.) It assumed that the return status would be 0 when there were conflicts. In that case it would grep for a "<<<<<<" string in the merged working file to determine whether there had been any conflicts. When rcsmerge version 5.5 returns a status of 1, CVS assumes that there was a fatal error. Instead, it should treat this as a successful merge, with conflicts. Solution: Revise src/update.c to use the status values returned by rcsmerge version 5.5. A patch file (produced by CVS, of course) is attached below. I have sent a copy of this message to berliner@sun.com. ---------------------------------------------------------------------- Lowell Skoog M/S 223B lowell@tc.fluke.COM John Fluke Mfg. Co. Inc. {uunet,uw-beaver,microsoft,sun}!fluke!lowell P.O. Box 9090 Everett, WA, USA 98206-9090 (206) 356-5283 ---------------------------------------------------------------------- diff -c cvs/src/update.c:1.1.1.1 cvs/src/update.c:1.2 *** cvs/src/update.c:1.1.1.1 Thu May 23 14:46:19 1991 --- cvs/src/update.c Thu May 23 14:46:20 1991 *************** *** 1,5 **** #ifndef lint ! static char rcsid[] = "$Id: update.c,v 1.1.1.1 1991/02/22 16:35:34 lowell Exp $"; #endif !lint /* --- 1,5 ---- #ifndef lint ! static char rcsid[] = "$Id: update.c,v 1.2 1991/05/23 19:43:53 lowell Exp $"; #endif !lint /* *************** *** 53,58 **** --- 53,59 ---- #include #include #include + #include /* UNOFFICIAL - bug fix */ #include #include "cvs.h" *************** *** 182,187 **** --- 183,189 ---- FILE *fp; char *cp; int update_Files = 0, err = 0; + int status; /* UNOFFICIAL - bug fix */ /* * Wlist is the "remove entry" list. *************** *** 293,299 **** --- 295,312 ---- xchmod(User, 1); (void) sprintf(prog, "%s/%s -r%s %s", Rcsbin, RCS_MERGE, VN_User, Rcs); + /* UNOFFICIAL CHANGE - original code commented out if (system(prog) != 0) { + */ + /* UNOFFICIAL - start of bug fix + * rcsmerge now provides a return status similar to diff(1). + * If there were conflicts, the return status is 1. It + * appears that this version of CVS was written assuming that + * rcsmerge returned 0 in this case. + */ + status = system(prog); + if (WEXITSTATUS(status) == 2) { + /* UNOFFICIAL - end of bug fix */ warn(0, "could not merge revision %s of %s", VN_User, User); warn(0, "backup file for %s is in %s", User, backup); *************** *** 301,308 **** --- 314,324 ---- continue; } Register(User, VN_Rcs, TS_Rcs); + /* UNOFFICIAL CHANGE - original code commented out (void) sprintf(prog, "%s -s '%s' %s", GREP, RCS_MERGE_PAT, User); if (system(prog) == 0) { + */ + if (WEXITSTATUS(status) == 1) { /* UNOFFICIAL - bug fix */ warn(0, "conflicts found in %s", User); if (!really_quiet) { if (update_dir[0])