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.
18 static Dtype status_dirproc PROTO ((void *callerdat, const char *dir,
19 const char *repos, const char *update_dir,
21 static int status_fileproc PROTO ((void *callerdat, struct file_info *finfo));
22 static int tag_list_proc PROTO((Node * p, void *closure));
25 static int long_format = 0;
26 static RCSNode *xrcsnode;
28 static const char *const status_usage[] =
30 "Usage: %s %s [-vlR] [files...]\n",
31 "\t-v\tVerbose format; includes tag information for the file\n",
32 "\t-l\tProcess this directory only (not recursive).\n",
33 "\t-R\tProcess directories recursively.\n",
34 "(Specify the --help global option for a list of other help options)\n",
39 cvsstatus (argc, argv)
50 while ((c = getopt (argc, argv, "+vlR")) != -1)
75 if (current_parsed_root->isremote)
87 /* For a while, we tried setting SEND_NO_CONTENTS here so this
88 could be a fast operation. That prevents the
89 server from updating our timestamp if the timestamp is
90 changed but the file is unmodified. Worse, it is user-visible
91 (shows "locally modified" instead of "up to date" if
92 timestamp is changed but file is not). And there is no good
93 workaround (you might not want to run "cvs update"; "cvs -n
94 update" doesn't update CVS/Entries; "cvs diff --brief" or
95 something perhaps could be made to work but somehow that
96 seems nonintuitive to me even if so). Given that timestamps
97 seem to have the potential to get munged for any number of
98 reasons, it seems better to not rely too much on them. */
100 send_files (argc, argv, local, 0, 0);
102 send_file_names (argc, argv, SEND_EXPAND_WILD);
104 send_to_server ("status\012", 0);
105 err = get_responses_and_close ();
111 /* start the recursion processor */
112 err = start_recursion (status_fileproc, (FILESDONEPROC) NULL,
113 status_dirproc, (DIRLEAVEPROC) NULL, NULL,
115 W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1,
122 * display the status of a file
126 status_fileproc (callerdat, finfo)
128 struct file_info *finfo;
134 status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL,
136 sstat = "Classify Error";
143 sstat = "Needs Checkout";
146 sstat = "Needs Patch";
149 sstat = "Unresolved Conflict";
152 sstat = "Locally Added";
155 sstat = "Locally Removed";
158 if (file_has_markers (finfo))
159 sstat = "File had conflicts on merge";
161 /* Note that we do not re Register() the file when we spot
162 * a resolved conflict like update_fileproc() does on the
163 * premise that status should not alter the sandbox.
165 sstat = "Locally Modified";
168 sstat = "Entry Invalid";
171 sstat = "Up-to-date";
174 sstat = "Needs Merge";
177 /* I don't think this case can occur here. Just print
183 ===================================================================\n", 0);
184 if (vers->ts_user == NULL)
186 cvs_output ("File: no file ", 0);
187 cvs_output (finfo->file, 0);
188 cvs_output ("\t\tStatus: ", 0);
189 cvs_output (sstat, 0);
190 cvs_output ("\n\n", 0);
195 buf = xmalloc (strlen (finfo->file) + strlen (sstat) + 80);
196 sprintf (buf, "File: %-17s\tStatus: %s\n\n", finfo->file, sstat);
201 if (vers->vn_user == NULL)
203 cvs_output (" Working revision:\tNo entry for ", 0);
204 cvs_output (finfo->file, 0);
205 cvs_output ("\n", 0);
207 else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
208 cvs_output (" Working revision:\tNew file!\n", 0);
211 cvs_output (" Working revision:\t", 0);
212 cvs_output (vers->vn_user, 0);
215 cvs_output ("\t", 0);
216 cvs_output (vers->ts_rcs, 0);
218 cvs_output ("\n", 0);
221 if (vers->vn_rcs == NULL)
222 cvs_output (" Repository revision:\tNo revision control file\n", 0);
225 cvs_output (" Repository revision:\t", 0);
226 cvs_output (vers->vn_rcs, 0);
227 cvs_output ("\t", 0);
228 cvs_output (vers->srcfile->path, 0);
229 cvs_output ("\n", 0);
236 edata = vers->entdata;
239 if (vers->vn_rcs == NULL)
241 cvs_output (" Sticky Tag:\t\t", 0);
242 cvs_output (edata->tag, 0);
243 cvs_output (" - MISSING from RCS file!\n", 0);
247 if (isdigit ((unsigned char) edata->tag[0]))
249 cvs_output (" Sticky Tag:\t\t", 0);
250 cvs_output (edata->tag, 0);
251 cvs_output ("\n", 0);
257 if (RCS_nodeisbranch (finfo->rcs, edata->tag))
258 branch = RCS_whatbranch(finfo->rcs, edata->tag);
260 cvs_output (" Sticky Tag:\t\t", 0);
261 cvs_output (edata->tag, 0);
262 cvs_output (" (", 0);
263 cvs_output (branch ? "branch" : "revision", 0);
264 cvs_output (": ", 0);
265 cvs_output (branch ? branch : vers->vn_rcs, 0);
266 cvs_output (")\n", 0);
273 else if (!really_quiet)
274 cvs_output (" Sticky Tag:\t\t(none)\n", 0);
278 cvs_output (" Sticky Date:\t\t", 0);
279 cvs_output (edata->date, 0);
280 cvs_output ("\n", 0);
282 else if (!really_quiet)
283 cvs_output (" Sticky Date:\t\t(none)\n", 0);
285 if (edata->options && edata->options[0])
287 cvs_output (" Sticky Options:\t", 0);
288 cvs_output (edata->options, 0);
289 cvs_output ("\n", 0);
291 else if (!really_quiet)
292 cvs_output (" Sticky Options:\t(none)\n", 0);
295 if (long_format && vers->srcfile)
297 List *symbols = RCS_symbols(vers->srcfile);
299 cvs_output ("\n Existing Tags:\n", 0);
302 xrcsnode = finfo->rcs;
303 (void) walklist (symbols, tag_list_proc, NULL);
306 cvs_output ("\tNo Tags Exist\n", 0);
309 cvs_output ("\n", 0);
315 * Print a warm fuzzy message
319 status_dirproc (callerdat, dir, repos, update_dir, entries)
323 const char *update_dir;
327 error (0, 0, "Examining %s", update_dir);
332 * Print out a tag and its type
335 tag_list_proc (p, closure)
342 if (RCS_nodeisbranch (xrcsnode, p->key))
343 branch = RCS_whatbranch(xrcsnode, p->key) ;
345 buf = xmalloc (80 + strlen (p->key)
346 + (branch ? strlen (branch) : strlen (p->data)));
347 sprintf (buf, "\t%-25s\t(%s: %s)\n", p->key,
348 branch ? "branch" : "revision",
349 branch ? branch : (char *)p->data);