2 * status.c: the command-line's portion of the "svn status" command
4 * ====================================================================
5 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
19 /* ==================================================================== */
24 #include "svn_cmdline.h"
30 #include "svn_private_config.h"
32 /* Return the single character representation of STATUS */
34 generate_status_code(enum svn_wc_status_kind status
)
38 case svn_wc_status_none
: return ' ';
39 case svn_wc_status_normal
: return ' ';
40 case svn_wc_status_added
: return 'A';
41 case svn_wc_status_missing
: return '!';
42 case svn_wc_status_incomplete
: return '!';
43 case svn_wc_status_deleted
: return 'D';
44 case svn_wc_status_replaced
: return 'R';
45 case svn_wc_status_modified
: return 'M';
46 case svn_wc_status_merged
: return 'G';
47 case svn_wc_status_conflicted
: return 'C';
48 case svn_wc_status_obstructed
: return '~';
49 case svn_wc_status_ignored
: return 'I';
50 case svn_wc_status_external
: return 'X';
51 case svn_wc_status_unversioned
: return '?';
57 /* Return the detailed string representation of STATUS */
59 generate_status_desc(enum svn_wc_status_kind status
)
63 case svn_wc_status_none
: return "none";
64 case svn_wc_status_normal
: return "normal";
65 case svn_wc_status_added
: return "added";
66 case svn_wc_status_missing
: return "missing";
67 case svn_wc_status_incomplete
: return "incomplete";
68 case svn_wc_status_deleted
: return "deleted";
69 case svn_wc_status_replaced
: return "replaced";
70 case svn_wc_status_modified
: return "modified";
71 case svn_wc_status_merged
: return "merged";
72 case svn_wc_status_conflicted
: return "conflicted";
73 case svn_wc_status_obstructed
: return "obstructed";
74 case svn_wc_status_ignored
: return "ignored";
75 case svn_wc_status_external
: return "external";
76 case svn_wc_status_unversioned
: return "unversioned";
83 /* Print STATUS and PATH in a format determined by DETAILED and
84 SHOW_LAST_COMMITTED. */
86 print_status(const char *path
,
87 svn_boolean_t detailed
,
88 svn_boolean_t show_last_committed
,
89 svn_boolean_t repos_locks
,
90 svn_wc_status2_t
*status
,
95 char ood_status
, lock_status
;
96 const char *working_rev
;
100 else if (! SVN_IS_VALID_REVNUM(status
->entry
->revision
))
102 else if (status
->copied
)
105 working_rev
= apr_psprintf(pool
, "%ld", status
->entry
->revision
);
107 if (status
->repos_text_status
!= svn_wc_status_none
108 || status
->repos_prop_status
!= svn_wc_status_none
)
115 if (status
->repos_lock
)
117 if (status
->entry
&& status
->entry
->lock_token
)
119 if (strcmp(status
->repos_lock
->token
, status
->entry
->lock_token
)
128 else if (status
->entry
&& status
->entry
->lock_token
)
134 lock_status
= (status
->entry
&& status
->entry
->lock_token
) ? 'K' : ' ';
136 if (show_last_committed
)
138 const char *commit_rev
;
139 const char *commit_author
;
141 if (status
->entry
&& SVN_IS_VALID_REVNUM(status
->entry
->cmt_rev
))
142 commit_rev
= apr_psprintf(pool
, "%ld", status
->entry
->cmt_rev
);
143 else if (status
->entry
)
148 if (status
->entry
&& status
->entry
->cmt_author
)
149 commit_author
= status
->entry
->cmt_author
;
150 else if (status
->entry
)
151 commit_author
= " ? ";
156 (svn_cmdline_printf(pool
,
157 "%c%c%c%c%c%c %c %6s %6s %-12s %s\n",
158 generate_status_code(status
->text_status
),
159 generate_status_code(status
->prop_status
),
160 status
->locked
? 'L' : ' ',
161 status
->copied
? '+' : ' ',
162 status
->switched
? 'S' : ' ',
172 (svn_cmdline_printf(pool
, "%c%c%c%c%c%c %c %6s %s\n",
173 generate_status_code(status
->text_status
),
174 generate_status_code(status
->prop_status
),
175 status
->locked
? 'L' : ' ',
176 status
->copied
? '+' : ' ',
177 status
->switched
? 'S' : ' ',
185 (svn_cmdline_printf(pool
, "%c%c%c%c%c%c %s\n",
186 generate_status_code(status
->text_status
),
187 generate_status_code(status
->prop_status
),
188 status
->locked
? 'L' : ' ',
189 status
->copied
? '+' : ' ',
190 status
->switched
? 'S' : ' ',
191 ((status
->entry
&& status
->entry
->lock_token
)
195 SVN_ERR(svn_cmdline_fflush(stdout
));
202 svn_cl__print_status_xml(const char *path
,
203 svn_wc_status2_t
*status
,
206 svn_stringbuf_t
*sb
= svn_stringbuf_create("", pool
);
207 apr_hash_t
*att_hash
;
209 if (status
->text_status
== svn_wc_status_none
210 && status
->repos_text_status
== svn_wc_status_none
)
213 svn_xml_make_open_tag(&sb
, pool
, svn_xml_normal
, "entry",
214 "path", svn_path_local_style(path
, pool
), NULL
);
216 att_hash
= apr_hash_make(pool
);
217 apr_hash_set(att_hash
, "item", APR_HASH_KEY_STRING
,
218 generate_status_desc(status
->text_status
));
219 apr_hash_set(att_hash
, "props", APR_HASH_KEY_STRING
,
220 generate_status_desc(status
->prop_status
));
222 apr_hash_set(att_hash
, "wc-locked", APR_HASH_KEY_STRING
, "true");
224 apr_hash_set(att_hash
, "copied", APR_HASH_KEY_STRING
, "true");
225 if (status
->switched
)
226 apr_hash_set(att_hash
, "switched", APR_HASH_KEY_STRING
, "true");
227 if (status
->entry
&& ! status
->entry
->copied
)
228 apr_hash_set(att_hash
, "revision", APR_HASH_KEY_STRING
,
229 apr_psprintf(pool
, "%ld", status
->entry
->revision
));
230 svn_xml_make_open_tag_hash(&sb
, pool
, svn_xml_normal
, "wc-status",
233 if (status
->entry
&& SVN_IS_VALID_REVNUM(status
->entry
->cmt_rev
))
235 svn_cl__print_xml_commit(&sb
, status
->entry
->cmt_rev
,
236 status
->entry
->cmt_author
,
237 svn_time_to_cstring(status
->entry
->cmt_date
,
242 if (status
->entry
&& status
->entry
->lock_token
)
244 svn_xml_make_open_tag(&sb
, pool
, svn_xml_normal
, "lock", NULL
);
246 svn_cl__xml_tagged_cdata(&sb
, pool
, "token", status
->entry
->lock_token
);
248 /* If lock_owner is NULL, assume WC is corrupt. */
249 if (status
->entry
->lock_owner
)
250 svn_cl__xml_tagged_cdata(&sb
, pool
, "owner",
251 status
->entry
->lock_owner
);
253 return svn_error_createf(SVN_ERR_WC_CORRUPT
, NULL
,
254 _("'%s' has lock token, but no lock owner"),
255 svn_path_local_style(path
, pool
));
257 svn_cl__xml_tagged_cdata(&sb
, pool
, "comment",
258 status
->entry
->lock_comment
);
260 svn_cl__xml_tagged_cdata(&sb
, pool
, "created",
262 (status
->entry
->lock_creation_date
, pool
));
264 svn_xml_make_close_tag(&sb
, pool
, "lock");
267 svn_xml_make_close_tag(&sb
, pool
, "wc-status");
269 if (status
->repos_text_status
!= svn_wc_status_none
270 || status
->repos_prop_status
!= svn_wc_status_none
271 || status
->repos_lock
)
273 svn_xml_make_open_tag(&sb
, pool
, svn_xml_normal
, "repos-status",
275 generate_status_desc(status
->repos_text_status
),
277 generate_status_desc(status
->repos_prop_status
),
279 if (status
->repos_lock
)
281 svn_xml_make_open_tag(&sb
, pool
, svn_xml_normal
, "lock", NULL
);
283 svn_cl__xml_tagged_cdata(&sb
, pool
, "token",
284 status
->repos_lock
->token
);
286 svn_cl__xml_tagged_cdata(&sb
, pool
, "owner",
287 status
->repos_lock
->owner
);
289 svn_cl__xml_tagged_cdata(&sb
, pool
, "comment",
290 status
->repos_lock
->comment
);
292 svn_cl__xml_tagged_cdata(&sb
, pool
, "created",
294 (status
->repos_lock
->creation_date
,
297 if (status
->repos_lock
->expiration_date
!= 0)
299 svn_cl__xml_tagged_cdata(&sb
, pool
, "expires",
301 (status
->repos_lock
->expiration_date
,
305 svn_xml_make_close_tag(&sb
, pool
, "lock");
307 svn_xml_make_close_tag(&sb
, pool
, "repos-status");
310 svn_xml_make_close_tag(&sb
, pool
, "entry");
312 return svn_cl__error_checked_fputs(sb
->data
, stdout
);
315 /* Called by status-cmd.c */
317 svn_cl__print_status(const char *path
,
318 svn_wc_status2_t
*status
,
319 svn_boolean_t detailed
,
320 svn_boolean_t show_last_committed
,
321 svn_boolean_t skip_unrecognized
,
322 svn_boolean_t repos_locks
,
326 || (skip_unrecognized
&& ! status
->entry
)
327 || (status
->text_status
== svn_wc_status_none
328 && status
->repos_text_status
== svn_wc_status_none
))
331 return print_status(svn_path_local_style(path
, pool
),
332 detailed
, show_last_committed
, repos_locks
, status
,