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)
80 send_file_names (argc, argv, SEND_EXPAND_WILD);
82 /* For a while, we tried setting SEND_NO_CONTENTS here so this
83 could be a fast operation. That prevents the
84 server from updating our timestamp if the timestamp is
85 changed but the file is unmodified. Worse, it is user-visible
86 (shows "locally modified" instead of "up to date" if
87 timestamp is changed but file is not). And there is no good
88 workaround (you might not want to run "cvs update"; "cvs -n
89 update" doesn't update CVS/Entries; "cvs diff --brief" or
90 something perhaps could be made to work but somehow that
91 seems nonintuitive to me even if so). Given that timestamps
92 seem to have the potential to get munged for any number of
93 reasons, it seems better to not rely too much on them. */
95 send_files (argc, argv, local, 0, 0);
97 send_to_server ("status\012", 0);
98 err = get_responses_and_close ();
104 /* start the recursion processor */
105 err = start_recursion (status_fileproc, (FILESDONEPROC) NULL,
106 status_dirproc, (DIRLEAVEPROC) NULL, NULL,
108 W_LOCAL, 0, 1, (char *) NULL, 1);
114 * display the status of a file
118 status_fileproc (callerdat, finfo)
120 struct file_info *finfo;
126 status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL,
128 sstat = "Classify Error";
135 sstat = "Needs Checkout";
137 #ifdef SERVER_SUPPORT
139 sstat = "Needs Patch";
143 /* I _think_ that "unresolved" is correct; that if it has
144 been resolved then the status will change. But I'm not
146 sstat = "Unresolved Conflict";
149 sstat = "Locally Added";
152 sstat = "Locally Removed";
155 if (vers->ts_conflict)
156 sstat = "File had conflicts on merge";
158 sstat = "Locally Modified";
161 sstat = "Entry Invalid";
164 sstat = "Up-to-date";
167 sstat = "Needs Merge";
170 /* I don't think this case can occur here. Just print
176 ===================================================================\n", 0);
177 if (vers->ts_user == NULL)
179 cvs_output ("File: no file ", 0);
180 cvs_output (finfo->file, 0);
181 cvs_output ("\t\tStatus: ", 0);
182 cvs_output (sstat, 0);
183 cvs_output ("\n\n", 0);
188 buf = xmalloc (strlen (finfo->file) + strlen (sstat) + 80);
189 sprintf (buf, "File: %-17s\tStatus: %s\n\n", finfo->file, sstat);
194 if (vers->vn_user == NULL)
196 cvs_output (" Working revision:\tNo entry for ", 0);
197 cvs_output (finfo->file, 0);
198 cvs_output ("\n", 0);
200 else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
201 cvs_output (" Working revision:\tNew file!\n", 0);
202 #ifdef SERVER_SUPPORT
203 else if (server_active)
205 cvs_output (" Working revision:\t", 0);
206 cvs_output (vers->vn_user, 0);
207 cvs_output ("\n", 0);
212 cvs_output (" Working revision:\t", 0);
213 cvs_output (vers->vn_user, 0);
214 cvs_output ("\t", 0);
215 cvs_output (vers->ts_rcs, 0);
216 cvs_output ("\n", 0);
219 if (vers->vn_rcs == NULL)
220 cvs_output (" Repository revision:\tNo revision control file\n", 0);
223 cvs_output (" Repository revision:\t", 0);
224 cvs_output (vers->vn_rcs, 0);
225 cvs_output ("\t", 0);
226 cvs_output (vers->srcfile->path, 0);
227 cvs_output ("\n", 0);
234 edata = vers->entdata;
237 if (vers->vn_rcs == NULL)
239 cvs_output (" Sticky Tag:\t\t", 0);
240 cvs_output (edata->tag, 0);
241 cvs_output (" - MISSING from RCS file!\n", 0);
245 if (isdigit (edata->tag[0]))
247 cvs_output (" Sticky Tag:\t\t", 0);
248 cvs_output (edata->tag, 0);
249 cvs_output ("\n", 0);
255 if (RCS_nodeisbranch (finfo->rcs, edata->tag))
256 branch = RCS_whatbranch(finfo->rcs, edata->tag);
258 cvs_output (" Sticky Tag:\t\t", 0);
259 cvs_output (edata->tag, 0);
260 cvs_output (" (", 0);
261 cvs_output (branch ? "branch" : "revision", 0);
262 cvs_output (": ", 0);
263 cvs_output (branch ? branch : vers->vn_rcs, 0);
264 cvs_output (")\n", 0);
271 else if (!really_quiet)
272 cvs_output (" Sticky Tag:\t\t(none)\n", 0);
276 cvs_output (" Sticky Date:\t\t", 0);
277 cvs_output (edata->date, 0);
278 cvs_output ("\n", 0);
280 else if (!really_quiet)
281 cvs_output (" Sticky Date:\t\t(none)\n", 0);
283 if (edata->options && edata->options[0])
285 cvs_output (" Sticky Options:\t", 0);
286 cvs_output (edata->options, 0);
287 cvs_output ("\n", 0);
289 else if (!really_quiet)
290 cvs_output (" Sticky Options:\t(none)\n", 0);
292 if (long_format && vers->srcfile)
294 List *symbols = RCS_symbols(vers->srcfile);
296 cvs_output ("\n Existing Tags:\n", 0);
299 xrcsnode = finfo->rcs;
300 (void) walklist (symbols, tag_list_proc, NULL);
303 cvs_output ("\tNo Tags Exist\n", 0);
307 cvs_output ("\n", 0);
313 * Print a warm fuzzy message
317 status_dirproc (callerdat, dir, repos, update_dir, entries)
325 error (0, 0, "Examining %s", update_dir);
330 * Print out a tag and its type
333 tag_list_proc (p, closure)
340 if (RCS_nodeisbranch (xrcsnode, p->key))
341 branch = RCS_whatbranch(xrcsnode, p->key) ;
343 buf = xmalloc (80 + strlen (p->key)
344 + (branch ? strlen (branch) : strlen (p->data)));
345 sprintf (buf, "\t%-25s\t(%s: %s)\n", p->key,
346 branch ? "branch" : "revision",
347 branch ? branch : p->data);