From: Vadik Timchenko Date: Wed, 30 Oct 96 22:56:45 +0200 To: bug-cvs@prep.ai.mit.edu Subject: Secondary importing of wrapped files is broken. [seems plausible but needs a test case -kingdon] >Submitter-Id: net >Originator: Vadik Timchenko >Organization: net >Confidential: no >Synopsis: Secondary importing of wrapped files is broken. >Severity: serious >Priority: low >Category: cvs >Class: sw-bug >Release: cvs-1.9 >Environment: NEXTSTEP-3.3 on Intel 486 RCS version 5.7 diff - GNU diffutils version 2.7 >Description: I have found a bug in handling wrapped files. The first import of such files works well. But when I try to import file which already exists in repository, the error is arisen. The cause of the problem is incorrect command line for ci. The line looks like: ci /tmp/temp_wrapped_file /repository/wrapped_file,v Difference between names of incoming file and repository (RCS) file caused error, because ci can't properly handle such situation. Ci handles the command line as two different files. >How-To-Repeat: My .cvswrappers file *.nib -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s' *.rtfd -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s' *.draw -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s' *.tiff -m 'COPY' Here is trace log: ~/Sources/cvs-1.9/src/a$ mkdir a ~/Sources/cvs-1.9/src/a$ cd a ~/Sources/cvs-1.9/src/a$ mkdir a.rtfd ~/Sources/cvs-1.9/src/a$ touch a.rtfd/a ~/Sources/cvs-1.9/src/a$ ../cvs -t import -m "test 1" a vadik start N a/a.rtfd -> system('/LocalDeveloper/CVSMaster/CVSROOT/wrap' 'a.rtfd' '/tmp/cvs001693') -> unlink_file_dir(/tmp/cvs001693) No conflicts created by this import -> ParseInfo(/LocalDeveloper/CVSMaster/CVSROOT/loginfo, a, ALL) ~/Sources/cvs-1.9/src/a$ touch a.rtfd/a ~/Sources/cvs-1.9/src/a$ ../cvs -t import -m "test 2" a vadik start1 -> checkout (/LocalDeveloper/CVSMaster/a/a.rtfd,v, 1.1.1.1, -ko, /tmp/cvs-imp1700) -> system('/LocalDeveloper/CVSMaster/CVSROOT/wrap' 'a.rtfd' '/tmp/cvs001700') -> unlink_file_dir(/tmp/cvs001700) -> unlink(/tmp/cvs-imp1700) -> system('/usr/gnu/bin/rcs' '-x,v/' '-q' '-l1.1.1' '/LocalDeveloper/CVSMaster/a/a.rtfd,v') -> system('/LocalDeveloper/CVSMaster/CVSROOT/wrap' 'a.rtfd' '/tmp/cvs001700') -> system('/usr/gnu/bin/ci' '-x,v/' '-f' '-r1.1.1' '-q' '-mtest 2 ' '/tmp/cvs001700' '/LocalDeveloper/CVSMaster/a/a.rtfd,v') ci: /tmp/cvs001700,v: Branch point doesn't exist for revision 1.1.1. ci: `a.rtfd' is not a regular file ci: a.rtfd: Invalid argument -> unlink_file_dir(/tmp/cvs001700) cvs import: ERROR: Check-in of /LocalDeveloper/CVSMaster/a/a.rtfd,v failed -> system('/usr/gnu/bin/rcs' '-x,v/' '-q' '-u1.1.1' '/LocalDeveloper/CVSMaster/a/a.rtfd,v') No conflicts created by this import -> ParseInfo(/LocalDeveloper/CVSMaster/CVSROOT/loginfo, a, ALL) ~/Sources/cvs-1.9/src/a$ >Fix: Little changes should be made in src/import.c: *** src/import.c.orig Wed Oct 30 22:40:49 1996 --- src/import.c Wed Oct 30 22:40:53 1996 *************** *** 628,631 **** --- 628,636 ---- } } + } else { + /* For wrapped files. RCS command line should look like: + rcs [parameters] filename [path]filename,v */ + rename_file (vfile, FILE_HOLDER); + rename_file (tocvsPath, vfile); } *************** *** 636,644 **** ierrno = errno; ! if (tocvsPath == NULL) ! rename_file (FILE_HOLDER, vfile); ! else ! if (unlink_file_dir (tocvsPath) < 0) ! error (0, errno, "cannot remove %s", tocvsPath); if (status) --- 641,645 ---- ierrno = errno; ! rename_file (FILE_HOLDER, vfile); if (status) Now all work for me. -- Best regards Vadim From: tom@basil.icce.rug.nl Date: Fri, 15 Nov 96 15:59:42 +0100 To: bug-cvs@prep.ai.mit.edu Subject: BUG: checkin does not restore original of cvswrapped files on error. [ChangeLog entry from Tom Hageman * import.c (update_rcs_file): Compare just checked-out file with cvswrapped file, if any, instead of original. (add_rev): Work around ci smartness: move cvswrapped file in place of original before checkin, and restore original afterward. ] >Submitter-Id: net >Originator: Tom Hageman >Organization: net >Confidential: no >Synopsis: BUG: checkin does not restore original of cvswrapped files on error. >Severity: serious >Priority: high >Category: cvs >Class: sw-bug >Release: cvs-1.9 >Environment: m68k i386 hppa sparc, NEXTSTEP 3.x / OPENSTEP 4.x, target-independent. >Description: "cvs checkin", "cvs commit" do not restore original of cvswrapped files if an error occurs. >How-To-Repeat: >Fix: Squirrel away the original file/directory instead of blithely replacing it with its wrapped representation. *** cvs-1.9/src/%checkin.c Wed Oct 2 08:03:56 1996 --- cvs-1.9/src/checkin.c Sun Nov 10 18:02:08 1996 *************** Checkin (type, finfo, rcs, rev, tag, opt *** 50,57 **** if (tocvsPath) { ! copy_file (tocvsPath, fname); ! if (unlink_file_dir (finfo->file) < 0) if (! existence_error (errno)) ! error (1, errno, "cannot remove %s", finfo->fullname); copy_file (tocvsPath, finfo->file); } --- 50,59 ---- if (tocvsPath) { ! /* Backup the current version of the file. */ ! if (unlink_file_dir (fname) < 0) if (! existence_error (errno)) ! error (1, errno, "cannot remove %s", fname); ! rename_file (finfo->file, fname); ! /* Copy the wrapped file to the current directory then go to work */ copy_file (tocvsPath, finfo->file); } *************** Checkin (type, finfo, rcs, rev, tag, opt *** 62,65 **** --- 64,68 ---- } + /* ??? [TRH] do we really go ahead even if noexec is set? */ switch (RCS_checkin (rcs, NULL, message, rev, 0)) { *************** Checkin (type, finfo, rcs, rev, tag, opt *** 89,94 **** xchmod (finfo->file, 1); ! if (xcmp (finfo->file, fname) == 0) { rename_file (fname, finfo->file); /* the time was correct, so leave it alone */ --- 92,103 ---- xchmod (finfo->file, 1); ! ! /* [TRH] FIXME: what if noexec? */ ! if (xcmp (finfo->file, tocvsPath ? tocvsPath : fname) == 0) { + /* Cannot rename directory back over existing file. */ + if (unlink_file_dir (finfo->file) < 0) + if (! existence_error (errno)) + error (1, errno, "cannot remove %s", finfo->file); rename_file (fname, finfo->file); /* the time was correct, so leave it alone */ *************** Checkin (type, finfo, rcs, rev, tag, opt *** 97,108 **** else { ! if (unlink_file (fname) < 0) ! error (0, errno, "cannot remove %s", fname); /* sync up with the time from the RCS file */ set_time = 1; } - wrap_fromcvs_process_file (finfo->file); - /* * If we want read-only files, muck the permissions here, before --- 106,118 ---- else { ! wrap_fromcvs_process_file (finfo->file); ! ! if (unlink_file_dir (fname) < 0) ! if (! existence_error (errno)) ! error (0, errno, "cannot remove %s", fname); /* sync up with the time from the RCS file */ set_time = 1; } /* * If we want read-only files, muck the permissions here, before *************** Checkin (type, finfo, rcs, rev, tag, opt *** 133,138 **** --- 143,151 ---- if (!noexec) + { + rename_file (fname, finfo->file); error (1, errno, "could not check in %s -- fork failed", finfo->fullname); + } return (1); From: tom@basil.icce.rug.nl Date: Fri, 15 Nov 96 15:50:49 +0100 To: bug-cvs@prep.ai.mit.edu Subject: BUG: import does not handle wrapped files correctly. [ChangeLog entry from Tom Hageman * checkin.c (Checkin): Backup original of cvswrapped file, and restore it in case of no differences due to checkin, or on error. ] >Submitter-Id: net >Originator: Tom Hageman >Organization: net >Confidential: no >Synopsis: import does not handle wrapped files correctly. >Severity: serious >Priority: high >Category: cvs >Class: sw-bug >Release: cvs-1.9 >Environment: m68k i386 hppa sparc, NEXTSTEP 3.3 / OPENSTEP 4.x >Description: "cvs import" refuses to import a cvswrapped file if it is already present in the repository. >How-To-Repeat: -- The following are defined in $CVSROOT/CVSROOT/cvswrappers: *.nib -k 'b' -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s' *.rtfd -k 'b' -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s' (wrap and unwrap are the sample scripts that were included as examples a few cvs releases ago.) -- Initial import: tom@basil 66) cvs import -d -m "Carl Edman's EnhanceMail bundle." EnhanceMail CEdman release1_3 N EnhanceMail/.gdbinit [...] cvs import: Importing /usr/local/sources/CVS/EnhanceMail/English.lproj N EnhanceMail/English.lproj/EnhancePreferences.nib N EnhanceMail/English.lproj/Localizable.strings [...] No conflicts created by this import -- Subsequent import of updated sources: tom@basil 67) cd /private/tmp/O_EnhanceMail.2.0b4.NIHS_bs/EnhanceMail tom@basil 68) cvs import -d -m "Carl Edman's EnhanceMail bundle (OPENSTEP-only)." EnhanceMail CEdman release2_0b4 U EnhanceMail/.gdbinit [...] cvs import: Importing /usr/local/sources/CVS/EnhanceMail/English.lproj N EnhanceMail/English.lproj/EnhancePGPPanel.nib ci: /tmp/cvs003767,v: Branch point doesn't exist for revision 1.1.1. ci: `EnhancePreferences.nib' is not a regular file ci: EnhancePreferences.nib: Invalid argument cvs import: ERROR: Check-in of /usr/local/sources/CVS/EnhanceMail/English.lproj/EnhancePreferences.nib,v failed U EnhanceMail/English.lproj/Localizable.strings [...] No conflicts created by this import >Fix: *** cvs-1.9/src/%import.c Wed Oct 2 08:04:00 1996 --- cvs-1.9/src/import.c Fri Nov 8 22:26:14 1996 *************** update_rcs_file (message, vfile, vtag, t *** 532,536 **** tocvsPath = wrap_tocvs_process_file (vfile); ! different = xcmp (xtmpfile, vfile); if (tocvsPath) if (unlink_file_dir (tocvsPath) < 0) --- 532,536 ---- tocvsPath = wrap_tocvs_process_file (vfile); ! different = xcmp (xtmpfile, (tocvsPath ? tocvsPath : vfile)); if (tocvsPath) if (unlink_file_dir (tocvsPath) < 0) *************** add_rev (message, rcs, vfile, vers) *** 590,593 **** --- 590,594 ---- int locked, status, ierrno; char *tocvsPath; + char backup[PATH_MAX]; if (noexec) *************** add_rev (message, rcs, vfile, vers) *** 629,637 **** } } ! status = RCS_checkin (rcs->path, tocvsPath == NULL ? vfile : tocvsPath, message, vbranch, (RCS_FLAGS_QUIET | (use_file_modtime ? RCS_FLAGS_MODTIME : 0))); ierrno = errno; --- 630,662 ---- } } ! #if 0 ! /* [TRH 8-Nov-96] This soes not work for wrapped files since RCS ci ! is too smart for its own good and refuses to check in the temporary ! file into the given repository name. Sigh... ! So the correct (although cumbersome) way to do it is like in diff.c, ! by temporary moving the original file out of the way and copying ! the temporary into its place, and restoring afterwards. */ status = RCS_checkin (rcs->path, tocvsPath == NULL ? vfile : tocvsPath, message, vbranch, (RCS_FLAGS_QUIET | (use_file_modtime ? RCS_FLAGS_MODTIME : 0))); + #endif + else /* (tocvsPath != NULL) */ + { + /* Backup the current version of the file to ,,filename */ + sprintf(backup,"%s%s", CVSPREFIX, vfile); + if (unlink_file_dir (backup) < 0) + if (! existence_error (errno)) + error (1, errno, "cannot remove %s", backup); + rename_file (vfile, backup); + /* XXX should check that rename succeeded... */ + /* Copy the wrapped file to the current directory then go to work */ + copy_file (tocvsPath, vfile); + } + + status = RCS_checkin (rcs->path, vfile, + message, vbranch, + (RCS_FLAGS_QUIET + | (use_file_modtime ? RCS_FLAGS_MODTIME : 0))); ierrno = errno; *************** add_rev (message, rcs, vfile, vers) *** 639,645 **** rename_file (FILE_HOLDER, vfile); else if (unlink_file_dir (tocvsPath) < 0) error (0, errno, "cannot remove %s", tocvsPath); ! if (status) { --- 664,676 ---- rename_file (FILE_HOLDER, vfile); else + { + if (unlink_file_dir (vfile) < 0) + if (! existence_error (errno)) + error (1, errno, "cannot remove %s", vfile); + + rename_file (backup, vfile); if (unlink_file_dir (tocvsPath) < 0) error (0, errno, "cannot remove %s", tocvsPath); ! } if (status) { From: tom@lpsg.demon.co.uk Date: Fri, 14 Feb 1997 16:31:49 GMT To: bug-cvs@prep.ai.mit.edu Subject: Request for option to clear all wrappers >Submitter-Id: net >Originator: Tom Lees >Organization: net >Confidential: no >Synopsis: Feature request >Severity: non-critical >Priority: low >Category: cvs >Class: change-request >Release: 1.9 >Environment: System: Linux debian 2.1.24 #29 Tue Feb 4 23:10:28 GMT 1997 i486 Architecture: i486 >Description: CVS doesn't currently have a way to clear the list of wrappers and start, or to cancel some wrappers. Here is a forwarded report from the Debian bugs list:- I don't know if you use the wrappers functionality in CVS, but I spent the afternoon figuring out that they're broken. Fortunately, I was also able to come up with a q-n-d fix. The "real" problem, IMHO, is that the global wrapper specifications aren't sufficiently flexible. The patterns you specify are only checked against the basename of files, instead of a full regex against the repository path, which would seem to me to be the "right" way to do it. I didn't fix this. The smaller problem is that there isn't a damn way to turn the things off, which is something you would like to be able to do selectively. Unfortunately, -W entries on the command line and/or .cvswrapper entries just _add_ to the existing wrapper entries. >How-To-Repeat: >Fix: Here is a patch to wrapper.c (relative to 1.9) to support this extension:- --- wrapper.c.orig Fri Aug 23 16:30:21 1996 +++ wrapper.c Fri Feb 14 16:28:16 1997 @@ -227,6 +227,12 @@ if (!line || line[0] == '#') return; + /* Allows user to declare all wrappers null and void */ + if ( line[0] == '!') { + wrap_kill ( ); + return; + } + memset (&e, 0, sizeof(e)); /* Search for the wild card */ To: bug-cvs@prep.ai.mit.edu Subject: [1.9] Wrapper bugs Date: Fri, 28 Mar 1997 11:08:06 -0500 From: Vince Del Vecchio [would be nice to add a testcase. Haven't looked at the patch with any care yet. also see patch from Vadik Timchenko regarding the import problem checkin.c patch already checked in by Kiesel -kingdon, 1997] I have been trying to use the cvswrappers support and have discovered a couple of problems. The most noticeable one is that during a commit, for any items in subdirectories which are committed, a full relative pathname is passed to the wrapper program, even though the wd has been set to the path containing the item. Also, imports don't seem to work at all. The item gets wrapped into a temp file, and then 'ci ,v ' is executed. Since and look completely different ( being a mktemp name), RCS thinks that it is supposed to check in two entirely different files. Patches are attached. -Vince Del Vecchio vince.delvecchio@analog.com Index: src/ChangeLog =================================================================== RCS file: /home/gcc/cvs/src/ChangeLog,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -c -r1.1.1.1 -r1.2 *** ChangeLog 1997/03/26 20:26:25 1.1.1.1 --- ChangeLog 1997/03/28 15:46:04 1.2 *************** *** 1,3 **** --- 1,16 ---- + Thu Mar 27 13:55:09 1997 Vince Del Vecchio + + * checkin.c (Checkin): In calling wrap_tocvs_process_file, pass + short filename; we are already in the directory with the file. + + * import.c (update_rcs_file): xcmp should compare against wrapped + file if there is one. Defer deleting the wrapped file, so that + add_rev can use it. + (add_rev): Add `wrapped' parameter, the already wrapped file. + Make sure that has the same name as the RCS file (renaming if + necessary) so that ci doesn't think it and the RCS file are + completely unrelated. + Fri Oct 4 15:11:46 1996 Jim Kingdon * server.c (server_cleanup): Temporarily clear noexec when calling Index: src/checkin.c =================================================================== RCS file: /home/gcc/cvs/src/checkin.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -c -r1.1.1.1 -r1.2 *** checkin.c 1997/03/26 20:26:26 1.1.1.1 --- checkin.c 1997/03/27 19:10:44 1.2 *************** *** 43,49 **** * for the checkin and checkout. */ ! tocvsPath = wrap_tocvs_process_file (finfo->fullname); if (!noexec) { --- 43,49 ---- * for the checkin and checkout. */ ! tocvsPath = wrap_tocvs_process_file (finfo->file); if (!noexec) { Index: src/import.c =================================================================== RCS file: /home/gcc/cvs/src/import.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -c -r1.1.1.1 -r1.2 *** import.c 1997/03/26 20:26:27 1.1.1.1 --- import.c 1997/03/27 19:11:55 1.2 *************** *** 26,32 **** int targc, char *targv[])); static int expand_at_signs PROTO((char *buf, off_t size, FILE *fp)); static int add_rev PROTO((char *message, RCSNode *rcs, char *vfile, ! char *vers)); static int add_tags PROTO((RCSNode *rcs, char *vfile, char *vtag, int targc, char *targv[])); static int import_descend PROTO((char *message, char *vtag, int targc, char *targv[])); --- 26,32 ---- int targc, char *targv[])); static int expand_at_signs PROTO((char *buf, off_t size, FILE *fp)); static int add_rev PROTO((char *message, RCSNode *rcs, char *vfile, ! char *wrapped, char *vers)); static int add_tags PROTO((RCSNode *rcs, char *vfile, char *vtag, int targc, char *targv[])); static int import_descend PROTO((char *message, char *vtag, int targc, char *targv[])); *************** *** 531,540 **** } tocvsPath = wrap_tocvs_process_file (vfile); ! different = xcmp (xtmpfile, vfile); ! if (tocvsPath) ! if (unlink_file_dir (tocvsPath) < 0) ! error (0, errno, "cannot remove %s", tocvsPath); (void) unlink_file (xtmpfile); if (!different) --- 531,537 ---- } tocvsPath = wrap_tocvs_process_file (vfile); ! different = xcmp (xtmpfile, tocvsPath == NULL ? vfile : tocvsPath); (void) unlink_file (xtmpfile); if (!different) *************** *** 546,564 **** * "U", signifying that the file has changed, but needs no * attention, and we're done. */ if (add_tags (vers->srcfile, vfile, vtag, targc, targv)) retval = 1; add_log ('U', vfile); freevers_ts (&vers); return (retval); } } /* We may have failed to parse the RCS file; check just in case */ if (vers->srcfile == NULL || ! add_rev (message, vers->srcfile, vfile, vers->vn_rcs) || add_tags (vers->srcfile, vfile, vtag, targc, targv)) { freevers_ts (&vers); return (1); } --- 543,578 ---- * "U", signifying that the file has changed, but needs no * attention, and we're done. */ + if (tocvsPath) + { + (void) unlink_file (tocvsPath); + free (tocvsPath); + } if (add_tags (vers->srcfile, vfile, vtag, targc, targv)) retval = 1; add_log ('U', vfile); freevers_ts (&vers); return (retval); } + } else { + if (!noexec && vers->srcfile != NULL) + tocvsPath = wrap_tocvs_process_file (vfile); + else + tocvsPath = NULL; } /* We may have failed to parse the RCS file; check just in case */ if (vers->srcfile == NULL || ! add_rev (message, vers->srcfile, vfile, tocvsPath, vers->vn_rcs) || add_tags (vers->srcfile, vfile, vtag, targc, targv)) { + if (tocvsPath) + { + if (unlink_file_dir (tocvsPath) < 0) + if (! existence_error (errno)) + error (0, errno, "cannot remove %s", tocvsPath); + free (tocvsPath); + } freevers_ts (&vers); return (1); } *************** *** 573,578 **** --- 587,594 ---- letter = 'U'; add_log (letter, vfile); + if (tocvsPath) + free (tocvsPath); freevers_ts (&vers); return (0); } *************** *** 581,594 **** * Add the revision to the vendor branch */ static int ! add_rev (message, rcs, vfile, vers) char *message; RCSNode *rcs; char *vfile; char *vers; { int locked, status, ierrno; ! char *tocvsPath; if (noexec) return (0); --- 597,612 ---- * Add the revision to the vendor branch */ static int ! add_rev (message, rcs, vfile, wrapped, vers) char *message; RCSNode *rcs; char *vfile; + char *wrapped; char *vers; { int locked, status, ierrno; ! char *tocvsTmpDir = NULL; ! char *tocvsPath = NULL; if (noexec) return (0); *************** *** 606,613 **** } locked = 1; } ! tocvsPath = wrap_tocvs_process_file (vfile); ! if (tocvsPath == NULL) { /* We play with hard links rather than passing -u to ci to avoid expanding RCS keywords (see test 106.5 in sanity.sh). */ --- 624,630 ---- } locked = 1; } ! if (wrapped == NULL) { /* We play with hard links rather than passing -u to ci to avoid expanding RCS keywords (see test 106.5 in sanity.sh). */ *************** *** 627,645 **** return (1); } } } ! status = RCS_checkin (rcs->path, tocvsPath == NULL ? vfile : tocvsPath, message, vbranch, (RCS_FLAGS_QUIET | (use_file_modtime ? RCS_FLAGS_MODTIME : 0))); ierrno = errno; ! if (tocvsPath == NULL) rename_file (FILE_HOLDER, vfile); else ! if (unlink_file_dir (tocvsPath) < 0) ! error (0, errno, "cannot remove %s", tocvsPath); if (status) { --- 644,682 ---- return (1); } } + } else { + /* The wrapped file need to have the same name as the RCS file + in order for RCS to associate them. */ + tocvsTmpDir = cvs_temp_name (); + if (CVS_MKDIR (tocvsTmpDir, 0777) < 0) + { + ierrno = errno; + fperror (logfp, 0, ierrno, + "ERROR: cannot mkdir %s", tocvsTmpDir); + error (0, ierrno, "cannot mkdir %s", tocvsTmpDir); + return (1); + } + + tocvsPath = xmalloc (strlen (tocvsTmpDir) + strlen (vfile) + 2); + sprintf (tocvsPath, "%s/%s", tocvsTmpDir, vfile); + rename_file (wrapped, tocvsPath); } ! status = RCS_checkin (rcs->path, wrapped == NULL ? vfile : tocvsPath, message, vbranch, (RCS_FLAGS_QUIET | (use_file_modtime ? RCS_FLAGS_MODTIME : 0))); ierrno = errno; ! if (wrapped == NULL) rename_file (FILE_HOLDER, vfile); else ! { ! if (unlink_file_dir (tocvsTmpDir) < 0) ! error (0, errno, "cannot remove %s", tocvsTmpDir); ! free (tocvsPath); ! free (tocvsTmpDir); ! } if (status) { To: bug-cvs@prep.ai.mit.edu Subject: bug with the cvs wrappers functionality Date: Thu, 10 Apr 1997 02:17:03 PDT From: "Alec Wolman" I'm using cvs v1.7, and have run accros the following problem. I use the wrappers functionality to modify each line of a text file in the repository, before checkin and after checkout. The problem is as follows: the cvs update mechanism does not invoke the wrappers properly, so that if I have local changes, then the merge will fail - it will tell me that the entire file is a conflict. In other words, rcsmerge is invoked with the two versions specified by -r do not have the wrapper applied, but the checked out version that has local changes does have the wrapper applied. Therefore, rcsmerge gets confused and tells me that my local changes affect the entire file. I copied over the latest version of cvs (v1.9.6), tested that the same problem still exists, and then hacked up the following patch to fix it. Since I'm not at all familiar with cvs internals, I may have solved this problem in the wrong way, so feel free to throw this code away and fix it another way. However, this code does seem to solve the problem for me. Alec Wolman wolman@cs.washington.edu *** update.c~ Sat Mar 8 21:07:06 1997 --- update.c Thu Apr 10 01:56:04 1997 *************** *** 1458,1463 **** --- 1458,1464 ---- int status; int retcode = 0; int retval; + char *tocvsPath; /* * The users currently modified file is moved to a backup file name *************** *** 1507,1512 **** --- 1508,1520 ---- goto out; } + /* AW - wrapper fix part 1 - apply the to wrapper before merge */ + tocvsPath = wrap_tocvs_process_file(finfo->file); + if (tocvsPath) { + /* Copy the wrapped file to the current directory then go to work */ + copy_file (tocvsPath, finfo->file); + } + status = RCS_merge(vers->srcfile->path, vers->options, vers->vn_user, vers->vn_rcs); if (status != 0 && status != 1) *************** *** 1518,1523 **** --- 1526,1536 ---- rename_file (backup, finfo->file); retval = 1; goto out; + } + + /* AW - wrapper fix part 2 - apply the from wrapper after the merge */ + if (tocvsPath) { + wrap_fromcvs_process_file (finfo->file); } if (strcmp (vers->options, "-V4") == 0) Date: Tue, 1 Jul 1997 14:32:02 +0300 To: bug-cvs@prep.ai.mit.edu Subject: CVS cvswrappers documentation error From: Petri.Virkkula@ntc.nokia.com [At first glance he would seem to have a point -kingdon] >Submitter-Id: net >Originator: Petri Virkkula >Organization: net >Confidential: no >Synopsis: bad documentation of cvswrappers >Severity: non-critical >Priority: low >Category: doc >Class: doc-bug >Release: cvs-1.9 >Environment: PC Linux 2.0.29 CVS version 1.9 System: Linux pc-gripenberg 2.0.29 #12 Mon Jun 2 09:04:12 EEST 1997 i686 Architecture: i686 >Description: The CVS documentation for wrappers specified in cvswrappers file is no adequate or CVS behaves erronously. Documentation says (quote from info file): The `-t' filter is called with two arguments, the first is the name of the file/directory to filter and the second is the pathname to where the resulting filtered file should be placed. The first path is not relative to the current working directory of cvs, it is relative to the directory where cvs was run. >How-To-Repeat: --- quote from $CVSROOT/CVSROOT/cvswrappers --- *.a -k 'b' -f '/scripts/cvs_out %s' -t '/scripts/cvs_in %s %s' -m 'COPY' --- quote from $CVSROOT/CVSROOT/cvswrappers --- --- /scripts/cvs_in --- #!/bin/sh echo "$$(`/bin/pwd`): $0 $1 $2" gzip -c $1 > $2 --- /scripts/cvs_in --- When I run "cvs commit" in the root directory of the module I am working on, and there is modified file lib/Linux/libell.a (path is relative to the module root), then I get following echo output: 2269(/tmp/cvs-serv2254/lib/Linux): /tmp/scripts/cvs_in lib/Linux/libell.a /var/tmp/faaa000ZF $CVSROOT is "pvirkkul@tnsu27:/opt/ttd/cvsroot" >Fix: I fixed the problem by modifying the cvs_in script to following: --- /scripts/cvs_in --- #!/bin/sh gzip -c `basename $1` > $2 --- /scripts/cvs_in --- I think however that the CVS should be modified to give the first argument relative to the working directory of the wrapper script or/and the documentation should be clearer. From: Marcel Waldvogel Date: Wed, 9 Jul 97 23:51:02 +0200 To: bug-cvs@prep.ai.mit.edu Subject: CVS 1.9: Fix for wrapper code [need testcases. - kingdon] Hi! First of all, I'd like to thank all CVS developers for the great tool they have created! I started using CVS on a directory tree with a lot of wrappers, some of them containing blanks in the file name. I found (and fixed) two bugs related to them: - The wrapper's names cannot contain spaces or tabs - A "cvs commit" in a higher level directory could not add any wrapper that was just added with "cvs add". This even trashes the original source file. Both bugs can and do trash the original source file (at least when the wrapper calls something like GNU tar, which is pretty common). Therefore I think these five lines of code should go into the next release. ChangeLog entry: --------------------- Cut here ------------------------------- Wed Jul 9 22:59:26 1997 Marcel Waldvogel * checkin.c: Now it can commit new wrappers that were added in subdirectories. Previously trashed the original file. * wrapper.c: Changed to allow for whitespace in wrapper names. * NEWS, cvs.texinfo: Documented how to allow whitespace in wrapper names. --------------------- and here ------------------------------- NEWS entry: --------------------- Cut here ------------------------------- * cvswrappers: If the "to" or "from" filter do not contain percent (%) signs, the file name(s) are added to the end of the argument list. When specified with this method, the filename may contain any character, especially spaces. The old method is still supported for backward compatibility. --------------------- and here ------------------------------- Patches for cvs.texinfo, wrapper.c, and checkin.c: --------------------- Cut here ------------------------------- diff -u -r old/doc/cvs.texinfo new/doc/cvs.texinfo --- old/doc/cvs.texinfo Wed Jul 9 23:36:04 1997 +++ new/doc/cvs.texinfo Wed Jul 9 23:44:22 1997 @@ -7629,8 +7629,8 @@ @end example @example -*.nib -f 'unwrap %s' -t 'wrap %s %s' -m 'COPY' -*.c -t 'indent %s %s' +*.nib -f 'unwrap' -t 'wrap -9' -m 'COPY' +*.c -t 'indent -bad' @end example @noindent @@ -7655,16 +7655,29 @@ example no filtering of the @code{*.c} file is done when it is checked out of the repository. @noindent -The @code{-t} filter is called with two arguments, +The @code{-t} filter can specify any number of arguments. +It is called with two more arguments, the first is the name of the file/directory to filter and the second is the pathname to where the resulting filtered file should be placed. @noindent -The @code{-f} filter is called with one argument, +The @code{-f} filter is called with one additional argument, which is the name of the file to filter from. The end result of this filter will be a file in the users directory that they can work on as they normally would. + +For backward compatibility, the @code{-t} and @code{-f} +filters may also contain two or one, respectively, +@code{%s} placeholders, allowing the file name(s) +to be placed anywhere in the argument list. +The argument order for @code{-t} of course needs to be +maintained. This variation is deprecated because it +will cause file names with spaces to be split into +multiple arguments. Depending on the wrapper program +being executed, in extreme cases, this can cause your +source file to be overwritten. +@c This is true, but do we want to state this? For another example, the following command imports a directory, treating files whose name ends in diff -u -r old/src/checkin.c new/src/checkin.c --- old/src/checkin.c Wed Jul 9 23:36:44 1997 +++ new/src/checkin.c Wed Jul 9 23:36:24 1997 @@ -43,7 +43,7 @@ * for the checkin and checkout. */ - tocvsPath = wrap_tocvs_process_file (finfo->fullname); + tocvsPath = wrap_tocvs_process_file (finfo->file); if (!noexec) { diff -u -r old/src/wrapper.c new/src/wrapper.c --- old/src/wrapper.c Wed Jul 9 23:36:33 1997 +++ new/src/wrapper.c Wed Jul 9 23:36:24 1997 @@ -431,6 +431,11 @@ buf = cvs_temp_name (); run_setup(e->tocvsFilter,fileName,buf); + if (strchr(e->tocvsFilter, '%') == NULL) + { + run_arg(fileName); + run_arg(buf); + } run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY ); return buf; @@ -458,6 +463,8 @@ return NULL; run_setup(e->fromcvsFilter,fileName); + if (strchr(e->fromcvsFilter, '%') == NULL) + run_arg(fileName); run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL ); return buf; } --------------------- and here ------------------------------- -Marcel