summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/checkin.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/checkin.c')
-rw-r--r--contrib/cvs/src/checkin.c85
1 files changed, 36 insertions, 49 deletions
diff --git a/contrib/cvs/src/checkin.c b/contrib/cvs/src/checkin.c
index 1d89ae1..70fb74c 100644
--- a/contrib/cvs/src/checkin.c
+++ b/contrib/cvs/src/checkin.c
@@ -29,7 +29,6 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
char *options;
char *message;
{
- char *fname;
Vers_TS *vers;
int set_time;
char *tocvsPath = NULL;
@@ -42,69 +41,63 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
cvs_output (finfo->fullname, 0);
cvs_output (";\n", 0);
- fname = xmalloc (strlen (finfo->file) + 80);
- (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
-
- /*
- * Move the user file to a backup file, so as to preserve its
- * modification times, then place a copy back in the original file name
- * for the checkin and checkout.
- */
-
tocvsPath = wrap_tocvs_process_file (finfo->file);
-
if (!noexec)
{
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);
- }
- else
- {
- copy_file (finfo->file, fname);
+ rename_file (tocvsPath, finfo->file);
}
}
if (finfo->rcs == NULL)
finfo->rcs = RCS_parse (finfo->file, finfo->repository);
- switch (RCS_checkin (finfo->rcs, NULL, message, rev, 0))
+ switch (RCS_checkin (finfo->rcs, NULL, message, rev, RCS_FLAGS_KEEPFILE))
{
case 0: /* everything normal */
- /*
- * The checkin succeeded, so now check the new file back out and
- * see if it matches exactly with the one we checked in. If it
- * does, just move the original user file back, thus preserving
- * the modes; otherwise, we have no recourse but to leave the
- * newly checkout file as the user file and remove the old
- * original user file.
- */
+ /* The checkin succeeded. If checking the file out again
+ would not cause any changes, we are done. Otherwise,
+ we need to check out the file, which will change the
+ modification time of the file.
+
+ The only way checking out the file could cause any
+ changes is if the file contains RCS keywords. So we if
+ we are not expanding RCS keywords, we are done. */
if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */
options[0] = '\0';
- /* FIXME: should be checking for errors. */
- (void) RCS_checkout (finfo->rcs, finfo->file, rev,
- (char *) NULL, options, RUN_TTY,
- (RCSCHECKOUTPROC) NULL, (void *) NULL);
-
- xchmod (finfo->file, 1);
- if (xcmp (finfo->file, fname) == 0)
+ /* FIXME: If PreservePermissions is on, RCS_cmp_file is
+ going to call RCS_checkout into a temporary file
+ anyhow. In that case, it would be more efficient to
+ call RCS_checkout here, compare the resulting files
+ using xcmp, and rename if necessary. I think this
+ should be fixed in RCS_cmp_file. */
+ if ((! preserve_perms
+ && options != NULL
+ && (strcmp (options, "-ko") == 0
+ || strcmp (options, "-kb") == 0))
+ || RCS_cmp_file (finfo->rcs, rev, options, finfo->file) == 0)
{
- rename_file (fname, finfo->file);
- /* the time was correct, so leave it alone */
+ /* The existing file is correct. We don't have to do
+ anything. */
set_time = 0;
}
else
{
- if (unlink_file (fname) < 0)
- error (0, errno, "cannot remove %s", fname);
- /* sync up with the time from the RCS file */
+ /* The existing file is incorrect. We need to check
+ out the correct file contents. */
+ if (RCS_checkout (finfo->rcs, finfo->file, rev, (char *) NULL,
+ options, RUN_TTY, (RCSCHECKOUTPROC) NULL,
+ (void *) NULL) != 0)
+ error (1, 0, "failed when checking out new copy of %s",
+ finfo->fullname);
+ xchmod (finfo->file, 1);
set_time = 1;
}
@@ -140,25 +133,19 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
if (!noexec)
error (1, errno, "could not check in %s -- fork failed",
finfo->fullname);
- free (fname);
return (1);
default: /* ci failed */
- /*
- * The checkin failed, for some unknown reason, so we restore the
- * original user file, print an error, and return an error
- */
+ /* The checkin failed, for some unknown reason, so we
+ print an error, and return an error. We assume that
+ the original file has not been touched. */
if (tocvsPath)
if (unlink_file_dir (tocvsPath) < 0)
error (0, errno, "cannot remove %s", tocvsPath);
if (!noexec)
- {
- rename_file (fname, finfo->file);
error (0, 0, "could not check in %s", finfo->fullname);
- }
- free (fname);
return (1);
}
@@ -179,7 +166,8 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
if (set_time)
/* Need to update the checked out file on the client side. */
server_updated (finfo, vers, SERVER_UPDATED,
- NULL, NULL);
+ (mode_t) -1, (unsigned char *) NULL,
+ (struct buffer *) NULL);
else
server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
}
@@ -188,6 +176,5 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
mark_up_to_date (finfo->file);
freevers_ts (&vers);
- free (fname);
return (0);
}
OpenPOWER on IntegriCloud