2 * Copyright (c) 1992, Brian Berliner and Jeff Polk
3 * Copyright (c) 1989-1992, Brian Berliner
5 * You may distribute under the terms of the GNU General Public License as
6 * specified in the README file that comes with the CVS source distribution.
13 static Dtype status_dirproc PROTO ((void *callerdat, char *dir,
14 char *repos, char *update_dir,
16 static int status_fileproc PROTO ((void *callerdat, struct file_info *finfo));
17 static int tag_list_proc PROTO((Node * p, void *closure));
20 static int long_format = 0;
21 static RCSNode *xrcsnode;
23 static const char *const status_usage[] =
25 "Usage: %s %s [-vlR] [files...]\n",
26 "\t-v\tVerbose format; includes tag information for the file\n",
27 "\t-l\tProcess this directory only (not recursive).\n",
28 "\t-R\tProcess directories recursively.\n",
29 "(Specify the --help global option for a list of other help options)\n",
34 cvsstatus (argc, argv)
45 while ((c = getopt (argc, argv, "+vlR")) != -1)
81 /* For a while, we tried setting SEND_NO_CONTENTS here so this
82 could be a fast operation. That prevents the
83 server from updating our timestamp if the timestamp is
84 changed but the file is unmodified. Worse, it is user-visible
85 (shows "locally modified" instead of "up to date" if
86 timestamp is changed but file is not). And there is no good
87 workaround (you might not want to run "cvs update"; "cvs -n
88 update" doesn't update CVS/Entries; "cvs diff --brief" or
89 something perhaps could be made to work but somehow that
90 seems nonintuitive to me even if so). Given that timestamps
91 seem to have the potential to get munged for any number of
92 reasons, it seems better to not rely too much on them. */
94 send_files (argc, argv, local, 0, 0);
96 send_file_names (argc, argv, SEND_EXPAND_WILD);
98 send_to_server ("status\012", 0);
99 err = get_responses_and_close ();
105 /* start the recursion processor */
106 err = start_recursion (status_fileproc, (FILESDONEPROC) NULL,
107 status_dirproc, (DIRLEAVEPROC) NULL, NULL,
109 W_LOCAL, 0, 1, (char *) NULL, 1);
115 * display the status of a file
119 status_fileproc (callerdat, finfo)
121 struct file_info *finfo;
127 status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL,
129 sstat = "Classify Error";
136 sstat = "Needs Checkout";
138 #ifdef SERVER_SUPPORT
140 sstat = "Needs Patch";
144 /* I _think_ that "unresolved" is correct; that if it has
145 been resolved then the status will change. But I'm not
147 sstat = "Unresolved Conflict";
150 sstat = "Locally Added";
153 sstat = "Locally Removed";
156 if (vers->ts_conflict)
157 sstat = "File had conflicts on merge";
159 sstat = "Locally Modified";
162 sstat = "Entry Invalid";
165 sstat = "Up-to-date";
168 sstat = "Needs Merge";
171 /* I don't think this case can occur here. Just print
177 ===================================================================\n", 0);
178 if (vers->ts_user == NULL)
180 cvs_output ("File: no file ", 0);
181 cvs_output (finfo->file, 0);
182 cvs_output ("\t\tStatus: ", 0);
183 cvs_output (sstat, 0);
184 cvs_output ("\n\n", 0);
189 buf = xmalloc (strlen (finfo->file) + strlen (sstat) + 80);
190 sprintf (buf, "File: %-17s\tStatus: %s\n\n", finfo->file, sstat);
195 if (vers->vn_user == NULL)
197 cvs_output (" Working revision:\tNo entry for ", 0);
198 cvs_output (finfo->file, 0);
199 cvs_output ("\n", 0);
201 else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
202 cvs_output (" Working revision:\tNew file!\n", 0);
203 #ifdef SERVER_SUPPORT
204 else if (server_active)
206 cvs_output (" Working revision:\t", 0);
207 cvs_output (vers->vn_user, 0);
208 cvs_output ("\n", 0);
213 cvs_output (" Working revision:\t", 0);
214 cvs_output (vers->vn_user, 0);
215 cvs_output ("\t", 0);
216 cvs_output (vers->ts_rcs, 0);
217 cvs_output ("\n", 0);
220 if (vers->vn_rcs == NULL)
221 cvs_output (" Repository revision:\tNo revision control file\n", 0);
224 cvs_output (" Repository revision:\t", 0);
225 cvs_output (vers->vn_rcs, 0);
226 cvs_output ("\t", 0);
227 cvs_output (vers->srcfile->path, 0);
228 cvs_output ("\n", 0);
235 edata = vers->entdata;
238 if (vers->vn_rcs == NULL)
240 cvs_output (" Sticky Tag:\t\t", 0);
241 cvs_output (edata->tag, 0);
242 cvs_output (" - MISSING from RCS file!\n", 0);
246 if (isdigit ((unsigned char) edata->tag[0]))
248 cvs_output (" Sticky Tag:\t\t", 0);
249 cvs_output (edata->tag, 0);
250 cvs_output ("\n", 0);
256 if (RCS_nodeisbranch (finfo->rcs, edata->tag))
257 branch = RCS_whatbranch(finfo->rcs, edata->tag);
259 cvs_output (" Sticky Tag:\t\t", 0);
260 cvs_output (edata->tag, 0);
261 cvs_output (" (", 0);
262 cvs_output (branch ? "branch" : "revision", 0);
263 cvs_output (": ", 0);
264 cvs_output (branch ? branch : vers->vn_rcs, 0);
265 cvs_output (")\n", 0);
272 else if (!really_quiet)
273 cvs_output (" Sticky Tag:\t\t(none)\n", 0);
277 cvs_output (" Sticky Date:\t\t", 0);
278 cvs_output (edata->date, 0);
279 cvs_output ("\n", 0);
281 else if (!really_quiet)
282 cvs_output (" Sticky Date:\t\t(none)\n", 0);
284 if (edata->options && edata->options[0])
286 cvs_output (" Sticky Options:\t", 0);
287 cvs_output (edata->options, 0);
288 cvs_output ("\n", 0);
290 else if (!really_quiet)
291 cvs_output (" Sticky Options:\t(none)\n", 0);
294 if (long_format && vers->srcfile)
296 List *symbols = RCS_symbols(vers->srcfile);
298 cvs_output ("\n Existing Tags:\n", 0);
301 xrcsnode = finfo->rcs;
302 (void) walklist (symbols, tag_list_proc, NULL);
305 cvs_output ("\tNo Tags Exist\n", 0);
308 cvs_output ("\n", 0);
314 * Print a warm fuzzy message
318 status_dirproc (callerdat, dir, repos, update_dir, entries)
326 error (0, 0, "Examining %s", update_dir);
331 * Print out a tag and its type
334 tag_list_proc (p, closure)
341 if (RCS_nodeisbranch (xrcsnode, p->key))
342 branch = RCS_whatbranch(xrcsnode, p->key) ;
344 buf = xmalloc (80 + strlen (p->key)
345 + (branch ? strlen (branch) : strlen (p->data)));
346 sprintf (buf, "\t%-25s\t(%s: %s)\n", p->key,
347 branch ? "branch" : "revision",
348 branch ? branch : p->data);