|
svn commit: r13144 - in trunk/subversion: clients/cmdline include libsvn_cl: msg#00321version-control.subversion.svn
Author: sussman Date: Thu Feb 24 18:13:51 2005 New Revision: 13144 Modified: trunk/subversion/clients/cmdline/info-cmd.c trunk/subversion/include/svn_client.h trunk/subversion/libsvn_client/info.c Log: Make 'svn info' work on URLs as well as working-copy items. * subversion/include/svn_client.h (svn_info_t): add new 'has_wc_info' boolean field. * subversion/libsvn_client/info.c (build_info_from_entry): set new boolean. (build_info_from_dirent): tweak signature, fill in. (push_dir_info): new func to recursively fetch & push URL dirents (svn_client_info): handle URLs. * subversion/clients/cmdline/info-cmd.c (print_info): notice new boolean field when printing. (svn_cl__info): allow URL targets, and parse peg-rev correctly. Modified: trunk/subversion/clients/cmdline/info-cmd.c Url: http://svn.collab.net/viewcvs/svn/trunk/subversion/clients/cmdline/info-cmd.c?view=diff&rev=13144&p1=trunk/subversion/clients/cmdline/info-cmd.c&r1=13143&p2=trunk/subversion/clients/cmdline/info-cmd.c&r2=13144 ============================================================================== --- trunk/subversion/clients/cmdline/info-cmd.c (original) +++ trunk/subversion/clients/cmdline/info-cmd.c Thu Feb 24 18:13:51 2005 @@ -66,7 +66,7 @@ SVN_ERR (svn_cmdline_printf (pool, _("URL: %s\n"), info->URL)); if (info->repos_root_URL) - SVN_ERR (svn_cmdline_printf (pool, _("Repository: %s\n"), + SVN_ERR (svn_cmdline_printf (pool, _("Repository Root: %s\n"), info->repos_root_URL)); if (info->repos_UUID) @@ -96,80 +96,88 @@ break; } - switch (info->schedule) + if (info->has_wc_info) { - case svn_wc_schedule_normal: - SVN_ERR (svn_cmdline_printf (pool, _("Schedule: normal\n"))); - break; - - case svn_wc_schedule_add: - SVN_ERR (svn_cmdline_printf (pool, _("Schedule: add\n"))); - break; - - case svn_wc_schedule_delete: - SVN_ERR (svn_cmdline_printf (pool, _("Schedule: delete\n"))); - break; - - case svn_wc_schedule_replace: - SVN_ERR (svn_cmdline_printf (pool, _("Schedule: replace\n"))); - break; + switch (info->schedule) + { + case svn_wc_schedule_normal: + SVN_ERR (svn_cmdline_printf (pool, _("Schedule: normal\n"))); + break; + + case svn_wc_schedule_add: + SVN_ERR (svn_cmdline_printf (pool, _("Schedule: add\n"))); + break; + + case svn_wc_schedule_delete: + SVN_ERR (svn_cmdline_printf (pool, _("Schedule: delete\n"))); + break; + + case svn_wc_schedule_replace: + SVN_ERR (svn_cmdline_printf (pool, _("Schedule: replace\n"))); + break; - default: - break; + default: + break; + } + + if (info->copyfrom_url) + SVN_ERR (svn_cmdline_printf (pool, _("Copied From URL: %s\n"), + info->copyfrom_url)); + + if (SVN_IS_VALID_REVNUM (info->copyfrom_rev)) + SVN_ERR (svn_cmdline_printf (pool, _("Copied From Rev: %ld\n"), + info->copyfrom_rev)); } - - if (info->copyfrom_url) - SVN_ERR (svn_cmdline_printf (pool, _("Copied From URL: %s\n"), - info->copyfrom_url)); - - if (SVN_IS_VALID_REVNUM (info->copyfrom_rev)) - SVN_ERR (svn_cmdline_printf (pool, _("Copied From Rev: %ld\n"), - info->copyfrom_rev)); - + if (info->last_changed_author) SVN_ERR (svn_cmdline_printf (pool, _("Last Changed Author: %s\n"), info->last_changed_author)); - + if (SVN_IS_VALID_REVNUM (info->last_changed_rev)) SVN_ERR (svn_cmdline_printf (pool, _("Last Changed Rev: %ld\n"), info->last_changed_rev)); - + if (info->last_changed_date) SVN_ERR (svn_cl__info_print_time (info->last_changed_date, _("Last Changed Date"), pool)); + + if (info->has_wc_info) + { + if (info->text_time) + SVN_ERR (svn_cl__info_print_time (info->text_time, + _("Text Last Updated"), pool)); + + if (info->prop_time) + SVN_ERR (svn_cl__info_print_time (info->prop_time, + _("Properties Last Updated"), pool)); + + if (info->checksum) + SVN_ERR (svn_cmdline_printf (pool, _("Checksum: %s\n"), + info->checksum)); + + if (info->conflict_old) + SVN_ERR (svn_cmdline_printf (pool, + _("Conflict Previous Base File: %s\n"), + svn_path_local_style (info->conflict_old, + pool))); + + if (info->conflict_wrk) + SVN_ERR (svn_cmdline_printf + (pool, _("Conflict Previous Working File: %s\n"), + svn_path_local_style (info->conflict_wrk, pool))); + + if (info->conflict_new) + SVN_ERR (svn_cmdline_printf (pool, + _("Conflict Current Base File: %s\n"), + svn_path_local_style (info->conflict_new, + pool))); + + if (info->prejfile) + SVN_ERR (svn_cmdline_printf (pool, _("Conflict Properties File: %s\n"), + svn_path_local_style (info->prejfile, + pool))); + } - if (info->text_time) - SVN_ERR (svn_cl__info_print_time (info->text_time, - _("Text Last Updated"), pool)); - - if (info->prop_time) - SVN_ERR (svn_cl__info_print_time (info->prop_time, - _("Properties Last Updated"), pool)); - - if (info->checksum) - SVN_ERR (svn_cmdline_printf (pool, _("Checksum: %s\n"), - info->checksum)); - - if (info->conflict_old) - SVN_ERR (svn_cmdline_printf (pool, _("Conflict Previous Base File: %s\n"), - svn_path_local_style (info->conflict_old, - pool))); - - if (info->conflict_wrk) - SVN_ERR (svn_cmdline_printf - (pool, _("Conflict Previous Working File: %s\n"), - svn_path_local_style (info->conflict_wrk, pool))); - - if (info->conflict_new) - SVN_ERR (svn_cmdline_printf (pool, _("Conflict Current Base File: %s\n"), - svn_path_local_style (info->conflict_new, - pool))); - - if (info->prejfile) - SVN_ERR (svn_cmdline_printf (pool, _("Conflict Properties File: %s\n"), - svn_path_local_style (info->prejfile, - pool))); - /* Print extra newline separator. */ SVN_ERR (svn_cmdline_printf (pool, "\n")); @@ -202,7 +210,7 @@ apr_pool_t *subpool = svn_pool_create (pool); int i; svn_error_t *err; - svn_opt_revision_t revision, peg_revision; + svn_opt_revision_t peg_revision; SVN_ERR (svn_opt_args_to_target_array2 (&targets, os, opt_state->targets, pool)); @@ -212,27 +220,22 @@ for (i = 0; i < targets->nelts; i++) { + const char *truepath; const char *target = ((const char **) (targets->elts))[i]; svn_pool_clear (subpool); SVN_ERR (svn_cl__check_cancel (ctx->cancel_baton)); - if (svn_path_is_url (target)) - { - /* ### remove this very, very soon. set the opt_revision - variables by parsing options. */ - return svn_error_create - (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("'svn info' only works on working copy paths, not URLs")); - } - else - { - revision.kind = svn_opt_revision_unspecified; - peg_revision.kind = svn_opt_revision_unspecified; - } + /* Get peg revisions. */ + SVN_ERR (svn_opt_parse_path (&peg_revision, &truepath, target, subpool)); + + /* If no peg-rev was attached to a URL target, then assume HEAD. */ + if ((svn_path_is_url (target)) + && (peg_revision.kind == svn_opt_revision_unspecified)) + peg_revision.kind = svn_opt_revision_head; - err = svn_client_info (target, - &peg_revision, &revision, + err = svn_client_info (truepath, + &peg_revision, &(opt_state->start_revision), info_receiver, NULL, opt_state->recursive, ctx, subpool); Modified: trunk/subversion/include/svn_client.h Url: http://svn.collab.net/viewcvs/svn/trunk/subversion/include/svn_client.h?view=diff&rev=13144&p1=trunk/subversion/include/svn_client.h&r1=13143&p2=trunk/subversion/include/svn_client.h&r2=13144 ============================================================================== --- trunk/subversion/include/svn_client.h (original) +++ trunk/subversion/include/svn_client.h Thu Feb 24 18:13:51 2005 @@ -1769,6 +1769,9 @@ /* The author of the last_changed_rev. */ const char *last_changed_author; + /* Whether or not to ignore the next 10 wc-specific fields. */ + svn_boolean_t has_wc_info; + /* The following things only apply to a working-copy path. See svn_wc_entry_t explanations. */ svn_wc_schedule_t schedule; Modified: trunk/subversion/libsvn_client/info.c Url: http://svn.collab.net/viewcvs/svn/trunk/subversion/libsvn_client/info.c?view=diff&rev=13144&p1=trunk/subversion/libsvn_client/info.c&r1=13143&p2=trunk/subversion/libsvn_client/info.c&r2=13144 ============================================================================== --- trunk/subversion/libsvn_client/info.c (original) +++ trunk/subversion/libsvn_client/info.c Thu Feb 24 18:13:51 2005 @@ -23,18 +23,35 @@ #include "client.h" #include "svn_client.h" #include "svn_wc.h" +#include "svn_pools.h" +#include "svn_path.h" #include "svn_private_config.h" -/* Helper: build an svn_info_t struct from an svn_dirent_t. */ +/* Helper: build an svn_info_t *INFO struct from svn_dirent_t DIRENT, + allocated in POOL. Pointer fields are copied by reference, not dup'd. */ static svn_error_t * build_info_from_dirent (svn_info_t **info, const svn_dirent_t *dirent, + const char *URL, + svn_revnum_t revision, + const char *repos_UUID, + const char *repos_root, apr_pool_t *pool) { - /* ### todo */ + svn_info_t *i = apr_pcalloc (pool, sizeof(*i)); + i->URL = URL; + i->rev = revision; + i->kind = dirent->kind; + i->repos_UUID = repos_UUID; + i->repos_root_URL = repos_root; + i->last_changed_rev = dirent->created_rev; + i->last_changed_date = dirent->time; + i->last_changed_author = dirent->last_author;; + + *info = i; return SVN_NO_ERROR; } @@ -57,6 +74,7 @@ i->last_changed_author = entry->cmt_author; /* entry-specific stuff */ + i->has_wc_info = TRUE; i->schedule = entry->schedule; i->copyfrom_url = entry->copyfrom_url; i->copyfrom_rev = entry->copyfrom_rev; @@ -73,6 +91,66 @@ } +/* Helper func for recursively fetching svn_dirent_t's from a remote + directory and pushing them at an info-receiver callback. */ +static svn_error_t * +push_dir_info (svn_ra_session_t *ra_session, + const char *session_URL, + const char *dir, + svn_revnum_t rev, + const char *repos_UUID, + const char *repos_root, + svn_info_receiver_t receiver, + void *receiver_baton, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + apr_hash_t *tmpdirents; + svn_dirent_t *the_ent; + svn_info_t *info; + apr_hash_index_t *hi; + apr_pool_t *subpool = svn_pool_create (pool); + + SVN_ERR (svn_ra_get_dir (ra_session, dir, rev, &tmpdirents, + NULL, NULL, pool)); + + for (hi = apr_hash_first (pool, tmpdirents); hi; hi = apr_hash_next (hi)) + { + const char *path, *URL; + const void *key; + void *val; + + svn_pool_clear (subpool); + + if (ctx->cancel_func) + SVN_ERR (ctx->cancel_func (ctx->cancel_baton)); + + apr_hash_this (hi, &key, NULL, &val); + the_ent = val; + + path = svn_path_join (dir, key, subpool); + URL = svn_path_url_add_component (session_URL, key, subpool); + + SVN_ERR (build_info_from_dirent (&info, the_ent, URL, rev, + repos_UUID, repos_root, subpool)); + + SVN_ERR (receiver (receiver_baton, path, info, subpool)); + + if (the_ent->kind == svn_node_dir) + SVN_ERR (push_dir_info (ra_session, URL, path, + rev, repos_UUID, repos_root, + receiver, receiver_baton, + ctx, subpool)); + } + + svn_pool_destroy (subpool); + + return SVN_NO_ERROR; +} + + + + /* Callback and baton for crawl_entries() walk over entries files. */ struct found_entry_baton { @@ -168,11 +246,16 @@ svn_client_ctx_t *ctx, apr_pool_t *pool) { - /* svn_ra_session_t *ra_session; - svn_revnum_t rev; - svn_node_kind_t url_kind; - const char *url; */ - + svn_ra_session_t *ra_session, *parent_ra_session; + svn_revnum_t rev; + const char *url; + svn_node_kind_t url_kind; + const char *repos_root_URL, *repos_UUID; + apr_hash_t *parent_ents; + const char *parent_url, *base_name; + svn_dirent_t *the_ent; + svn_info_t *info; + if ((revision == NULL || revision->kind == svn_opt_revision_unspecified) && (peg_revision == NULL @@ -186,11 +269,60 @@ /* Go repository digging instead. */ - /* Trace rename history and return RA session to the "final" path_or_url. */ - /* SVN_ERR (svn_client__ra_session_from_path (&ra_session, &rev, + /* Trace rename history (starting at path_or_url@peg_revision) and + return RA session to the possibly-renamed URL as it exists in REVISION. + The ra_session returned will be anchored on this "final" URL. */ + SVN_ERR (svn_client__ra_session_from_path (&ra_session, &rev, &url, path_or_url, peg_revision, - revision, ctx, pool));*/ + revision, ctx, pool)); + + SVN_ERR (svn_ra_get_repos_root (ra_session, &repos_root_URL, pool)); + SVN_ERR (svn_ra_get_uuid (ra_session, &repos_UUID, pool)); + SVN_ERR (svn_ra_check_path (ra_session, "", rev, &url_kind, pool)); + if (url_kind == svn_node_none) + return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL, + _("URL '%s' non-existent in revision '%ld'"), + url, rev); + + /* Step 1: find the dirent of the file or directory URL. */ + + /* Open a new RA session to the item's parent. */ + svn_path_split (url, &parent_url, &base_name, pool); + + /* 'base_name' is now the last component of an URL, but we want + to use it as a plain file name. Therefore, we must URI-decode + it. */ + base_name = svn_path_uri_decode(base_name, pool); + SVN_ERR (svn_client__open_ra_session (&parent_ra_session, parent_url, + NULL, + NULL, NULL, FALSE, TRUE, + ctx, pool)); + + /* Get all parent's entries, no props. */ + SVN_ERR (svn_ra_get_dir (parent_ra_session, "", rev, &parent_ents, + NULL, NULL, pool)); + + /* Find the item's own dirent and push it an the info receiver.*/ + the_ent = apr_hash_get (parent_ents, base_name, APR_HASH_KEY_STRING); + if (the_ent == NULL) + return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL, + _("URL '%s' non-existent in that revision"), + url); + + SVN_ERR (build_info_from_dirent (&info, the_ent, url, rev, + repos_UUID, repos_root_URL, pool)); + SVN_ERR (receiver (receiver_baton, base_name, info, pool)); + + /* Step 2: possibly recurse, using the original RA session. */ + + if (recurse && (url_kind == svn_node_dir)) + { + SVN_ERR (push_dir_info (ra_session, url, "", rev, + repos_UUID, repos_root_URL, + receiver, receiver_baton, + ctx, pool)); + } return SVN_NO_ERROR; } |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | svn commit: r13143 - trunk/notes/locking: 00321, fitz-jqHnx1hy4Dsdnm+yROfE0A |
|---|---|
| Next by Date: | svn commit: r13145 - trunk/subversion/libsvn_client: 00321, brane-jqHnx1hy4Dsdnm+yROfE0A |
| Previous by Thread: | svn commit: r13143 - trunk/notes/lockingi: 00321, fitz-jqHnx1hy4Dsdnm+yROfE0A |
| Next by Thread: | svn commit: r13145 - trunk/subversion/libsvn_client: 00321, brane-jqHnx1hy4Dsdnm+yROfE0A |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |