logo       

svn commit: r13144 - in trunk/subversion: clients/cmdline include libsvn_cl: msg#00321

version-control.subversion.svn

Subject: svn commit: r13144 - in trunk/subversion: clients/cmdline include libsvn_client

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>
Google Custom Search

News | FAQ | advertise