2 * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
4 * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
7 * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8 * Portions Copyright (C) 1989-1992, Brian Berliner
10 * You may distribute under the terms of the GNU General Public License as
11 * specified in the README file that comes with the CVS source distribution.
15 * Does a very careful checkin of the file "user", and tries not to spoil its
16 * modification time (to avoid needless recompilations). When RCS ID keywords
17 * get expanded on checkout, however, the modification time is updated and
18 * there is no good way to get around this.
20 * Returns non-zero on error.
29 Checkin (type, finfo, rev, tag, options, message)
31 struct file_info *finfo;
39 char *tocvsPath = NULL;
41 /* Hmm. This message goes to stdout and the "foo,v <-- foo"
42 message from "ci" goes to stderr. This doesn't make a whole
43 lot of sense, but making everything go to stdout can only be
44 gracefully achieved once RCS_checkin is librarified. */
45 cvs_output ("Checking in ", 0);
46 cvs_output (finfo->fullname, 0);
47 cvs_output (";\n", 0);
49 tocvsPath = wrap_tocvs_process_file (finfo->file);
54 if (unlink_file_dir (finfo->file) < 0)
55 if (! existence_error (errno))
56 error (1, errno, "cannot remove %s", finfo->fullname);
57 rename_file (tocvsPath, finfo->file);
61 /* There use to be a check for finfo->rcs == NULL here and then a
62 * call to RCS_parse when necessary, but Checkin() isn't called
63 * if the RCS file hasn't already been parsed in one of the
66 assert (finfo->rcs != NULL);
68 switch (RCS_checkin (finfo->rcs, finfo->file, message, rev, 0,
71 case 0: /* everything normal */
73 /* The checkin succeeded. If checking the file out again
74 would not cause any changes, we are done. Otherwise,
75 we need to check out the file, which will change the
76 modification time of the file.
78 The only way checking out the file could cause any
79 changes is if the file contains RCS keywords. So we if
80 we are not expanding RCS keywords, we are done. */
83 && strcmp (options, "-V4") == 0) /* upgrade to V5 now */
86 /* FIXME: If PreservePermissions is on, RCS_cmp_file is
87 going to call RCS_checkout into a temporary file
88 anyhow. In that case, it would be more efficient to
89 call RCS_checkout here, compare the resulting files
90 using xcmp, and rename if necessary. I think this
91 should be fixed in RCS_cmp_file. */
92 if( ( ! preserve_perms
94 && ( strcmp( options, "-ko" ) == 0
95 || strcmp( options, "-kb" ) == 0 ) )
96 || RCS_cmp_file( finfo->rcs, rev, (char **)NULL, (char *)NULL,
97 options, finfo->file ) == 0 )
99 /* The existing file is correct. We don't have to do
105 /* The existing file is incorrect. We need to check
106 out the correct file contents. */
107 if (RCS_checkout (finfo->rcs, finfo->file, rev, (char *) NULL,
108 options, RUN_TTY, (RCSCHECKOUTPROC) NULL,
110 error (1, 0, "failed when checking out new copy of %s",
112 xchmod (finfo->file, 1);
116 wrap_fromcvs_process_file (finfo->file);
119 * If we want read-only files, muck the permissions here, before
120 * getting the file time-stamp.
122 if (!cvswrite || fileattr_get (finfo->file, "_watched"))
123 xchmod (finfo->file, 0);
125 /* Re-register with the new data. */
126 vers = Version_TS (finfo, NULL, tag, NULL, 1, set_time);
127 if (strcmp (vers->options, "-V4") == 0)
128 vers->options[0] = '\0';
129 Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_user,
130 vers->options, vers->tag, vers->date, (char *) 0);
131 history_write (type, NULL, vers->vn_rcs,
132 finfo->file, finfo->repository);
135 if (unlink_file_dir (tocvsPath) < 0)
136 error (0, errno, "cannot remove %s", tocvsPath);
140 case -1: /* fork failed */
142 if (unlink_file_dir (tocvsPath) < 0)
143 error (0, errno, "cannot remove %s", tocvsPath);
146 error (1, errno, "could not check in %s -- fork failed",
150 default: /* ci failed */
152 /* The checkin failed, for some unknown reason, so we
153 print an error, and return an error. We assume that
154 the original file has not been touched. */
156 if (unlink_file_dir (tocvsPath) < 0)
157 error (0, errno, "cannot remove %s", tocvsPath);
160 error (0, 0, "could not check in %s", finfo->fullname);
165 * When checking in a specific revision, we may have locked the wrong
166 * branch, so to be sure, we do an extra unlock here before
171 (void) RCS_unlock (finfo->rcs, NULL, 1);
172 RCS_rewrite (finfo->rcs, NULL, NULL);
175 #ifdef SERVER_SUPPORT
179 /* Need to update the checked out file on the client side. */
180 server_updated (finfo, vers, SERVER_UPDATED,
181 (mode_t) -1, (unsigned char *) NULL,
182 (struct buffer *) NULL);
184 server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
188 mark_up_to_date (finfo->file);