Index: subversion/include/svn_types.h
===================================================================
--- subversion/include/svn_types.h (revision 15177)
+++ subversion/include/svn_types.h (working copy)
@@ -188,7 +188,45 @@
svn_recursive
};
+/** Added loc information with exiting directory entry. */
+typedef struct svn_dirent2_t
+{
+ /** node kind */
+ svn_node_kind_t kind;
+ /** length of file text, or 0 for directories */
+ svn_filesize_t size;
+
+ /** does the node have props? */
+ svn_boolean_t has_props;
+
+ /** last rev in which this node changed */
+ svn_revnum_t created_rev;
+
+ /** time of created_rev (mod-time) */
+ apr_time_t time;
+
+ /** author of created_rev */
+ const char *last_author;
+
+ /** lock token or NULL if path not locked in this REPOS */
+ const char *lock_token;
+
+ /** lock owner, or NULL if not locked in this REPOS */
+ const char *lock_owner;
+
+ /** lock comment or NULL if not locked in this REPOS or no comment */
+ const char *lock_comment;
+
+ /** Lock creation date or 0 if not locked in this REPOS */
+ apr_time_t lock_creation_date;
+
+ /** Lock expiration date or 0 if not locked in this REPOS */
+ apr_time_t lock_expiration_date;
+
+} svn_dirent2_t;
+
+
/** A general subversion directory entry. */
typedef struct svn_dirent_t
{
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 15177)
+++ subversion/include/svn_client.h (working copy)
@@ -1797,31 +1797,46 @@
svn_client_ctx_t *ctx,
apr_pool_t *pool);
-
/**
- * Set @a *dirents to a newly allocated hash of entries for @a
- * path_or_url at @a revision. The actual node revision selected is
+ * Set @a *dirents to a newly allocated hash of entries with lock information
+ * for @a path_or_url at @a revision. The actual node revision selected is
* determined by the path as it exists in @a peg_revision. If @a
* peg_revision is @c svn_opt_revision_unspecified, then it defaults
* to @c svn_opt_revision_head for URLs or @c svn_opt_revision_working
* for WC targets.
*
* If @a path_or_url is a directory, return all dirents in the hash. If
- * @a path_or_url is a file, return only the dirent for the file. If @a
- * path_or_url is non-existent, return @c SVN_ERR_FS_NOT_FOUND.
+ * @a path_or_url is a file, return the dirent and lock details for the file.
+ * If @a path_or_url is non-existent, return @c SVN_ERR_FS_NOT_FOUND.
*
- * The hash maps entry names (const char *) to @c svn_dirent_t *'s.
+ * The hash maps entry names (const char *) to @c svn_dirent2_t *'s.
* Do all allocation in @a pool.
*
- * Use authentication baton cached in @a ctx to authenticate against the
+ * Use authentication baton cached in @a ctx to authenticate against the
* repository.
*
* If @a recurse is true (and @a path_or_url is a directory) this will
* be a recursive operation.
*
- * @since New in 1.2.
+ * @since New in 1.3.
*/
svn_error_t *
+svn_client_ls3 (apr_hash_t **dirents,
+ const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_boolean_t recurse,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_ls3() except that the allocated hash of entries
+ * will contain only dirent and the hash maps entry names
+ * (const char *) to @c svn_dirent_t *'s.
+ *
+ * @deprecated Provided for backward compatibility with the 1.2 API.
+ */
+svn_error_t *
svn_client_ls2 (apr_hash_t **dirents,
const char *path_or_url,
const svn_opt_revision_t *peg_revision,
Index: subversion/libsvn_client/ls.c
===================================================================
--- subversion/libsvn_client/ls.c (revision 15177)
+++ subversion/libsvn_client/ls.c (working copy)
@@ -36,7 +36,6 @@
apr_pool_t *pool)
{
apr_hash_t *tmpdirents;
- svn_dirent_t *the_ent;
apr_hash_index_t *hi;
/* Get the directory's entries, but not its props. */
@@ -53,16 +52,29 @@
const char *path;
const void *key;
void *val;
+ svn_lock_t *lock;
+ svn_dirent2_t *lsent = apr_pcalloc (pool, sizeof(svn_dirent2_t));
apr_hash_this (hi, &key, NULL, &val);
- the_ent = val;
+ memcpy (lsent, val, sizeof (svn_dirent_t));
+
+ /* Get base name lock information. */
+ SVN_ERR (svn_ra_get_lock (ra_session, &lock, key, pool));
+ if (lock)
+ {
+ lsent->lock_token = lock->token;
+ lsent->lock_owner = lock->owner;
+ lsent->lock_comment = lock->comment;
+ lsent->lock_creation_date = lock->creation_date;
+ lsent->lock_expiration_date = lock->expiration_date;
+ }
path = svn_path_join (dir, key, pool);
- apr_hash_set (dirents, path, APR_HASH_KEY_STRING, val);
+ apr_hash_set (dirents, path, APR_HASH_KEY_STRING, lsent);
- if (recurse && the_ent->kind == svn_node_dir)
+ if (recurse && lsent->kind == svn_node_dir)
SVN_ERR (get_dir_contents (dirents, path, rev, ra_session,
recurse, ctx, pool));
}
@@ -71,6 +83,87 @@
}
svn_error_t *
+svn_client_ls3 (apr_hash_t **dirents,
+ const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_boolean_t recurse,
+ 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;
+
+ /* Get an RA plugin for this filesystem object. */
+ SVN_ERR (svn_client__ra_session_from_path (&ra_session, &rev,
+ &url, path_or_url, peg_revision,
+ revision, ctx, pool));
+
+ /* Decide if the URL is a file or directory. */
+ SVN_ERR (svn_ra_check_path (ra_session, "", rev, &url_kind, pool));
+
+ if (url_kind == svn_node_dir)
+ {
+ *dirents = apr_hash_make (pool);
+
+ SVN_ERR (get_dir_contents (*dirents, "", rev, ra_session, recurse,
+ ctx, pool));
+ }
+ else if (url_kind == svn_node_file)
+ {
+ apr_hash_t *parent_ents;
+ const char *parent_url, *base_name;
+ svn_dirent_t *the_ent;
+ svn_dirent2_t *ls_ent = apr_pcalloc (pool, sizeof(svn_dirent2_t));
+ svn_lock_t *lock;
+
+ /* Re-open the session to the file's parent instead. */
+ 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_internal (&ra_session, parent_url,
+ NULL, NULL, NULL, FALSE,
+ TRUE, ctx, pool));
+
+ /* Get all parent's entries, no props. */
+ SVN_ERR (svn_ra_get_dir (ra_session, "", rev, &parent_ents,
+ NULL, NULL, pool));
+
+ /* Get base name lock information. */
+ SVN_ERR (svn_ra_get_lock (ra_session, &lock, base_name, pool));
+
+ /* Copy the relevant entry into the caller's hash. */
+ *dirents = apr_hash_make (pool);
+ the_ent = apr_hash_get (parent_ents, base_name, APR_HASH_KEY_STRING);
+ if (the_ent == NULL)
+ return svn_error_createf (SVN_ERR_FS_NOT_FOUND, NULL,
+ _("URL '%s' non-existent in that revision"),
+ url);
+ memcpy (ls_ent, the_ent, sizeof (svn_dirent_t));
+ if (lock)
+ {
+ ls_ent->lock_token = lock->token;
+ ls_ent->lock_owner = lock->owner;
+ ls_ent->lock_comment = lock->comment;
+ ls_ent->lock_creation_date = lock->creation_date;
+ ls_ent->lock_expiration_date = lock->expiration_date;
+ }
+
+ apr_hash_set (*dirents, base_name, APR_HASH_KEY_STRING, ls_ent);
+ }
+ else
+ return svn_error_createf (SVN_ERR_FS_NOT_FOUND, NULL,
+ _("URL '%s' non-existent in that revision"),
+ url);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_client_ls2 (apr_hash_t **dirents,
const char *path_or_url,
const svn_opt_revision_t *peg_revision,
Index: subversion/clients/cmdline/ls-cmd.c
===================================================================
--- subversion/clients/cmdline/ls-cmd.c (revision 15177)
+++ subversion/clients/cmdline/ls-cmd.c (working copy)
@@ -50,7 +50,7 @@
for (i = 0; i < array->nelts; ++i)
{
const char *utf8_entryname;
- svn_dirent_t *dirent;
+ svn_dirent2_t *dirent;
svn_sort__item_t *item;
svn_pool_clear (subpool);
@@ -70,8 +70,8 @@
apr_time_exp_t exp_time;
apr_status_t apr_err;
apr_size_t size;
- char timestr[20];
- const char *sizestr, *utf8_timestr;
+ char timestr[20], lock_timestr[20];
+ const char *sizestr, *utf8_timestr, *utf8_lock_timestr;
/* svn_time_to_human_cstring gives us something *way* too long
to use for this, so we have to roll our own. We include
@@ -98,13 +98,42 @@
sizestr = apr_psprintf (subpool, "%" SVN_FILESIZE_T_FMT,
dirent->size);
+ if (dirent->lock_owner)
+ {
+ apr_time_exp_lt (&exp_time, dirent->lock_creation_date);
+ if (apr_time_sec
+ (now - dirent->lock_creation_date) < (365 * 86400 / 2)
+ && apr_time_sec
+ (dirent->lock_creation_date - now) < (365 * 86400 / 2))
+ {
+ apr_err = apr_strftime (lock_timestr, &size,
+ sizeof (lock_timestr),
+ "%b %d %H:%M", &exp_time);
+ }
+ else
+ {
+ apr_err = apr_strftime (lock_timestr, &size,
+ sizeof (timestr),
+ "%b %d %Y", &exp_time);
+ }
+ /* if that failed, just zero out the string and print nothing */
+ if (apr_err)
+ lock_timestr[0] = '\0';
+
+ /* we need it in UTF-8. */
+ SVN_ERR (svn_utf_cstring_to_utf8
+ (&utf8_lock_timestr, lock_timestr, subpool));
+ }
+
SVN_ERR (svn_cmdline_printf
- (subpool, "%7ld %-8.8s %10s %12s %s%s\n",
+ (subpool, "%7ld %-12s %10s %12s %12s %-12s %s%s\n",
dirent->created_rev,
dirent->last_author ? dirent->last_author : " ? ",
(dirent->kind == svn_node_file) ? sizestr : "",
utf8_timestr,
+ dirent->lock_owner ? utf8_lock_timestr : "",
+ dirent->lock_owner ? dirent->lock_owner : "",
utf8_entryname,
(dirent->kind == svn_node_dir) ? "/" : ""));
}
@@ -322,7 +351,7 @@
/* Get peg revisions. */
SVN_ERR (svn_opt_parse_path (&peg_revision, &truepath, target,
subpool));
- SVN_ERR (svn_client_ls2 (&dirents, truepath, &peg_revision,
+ SVN_ERR (svn_client_ls3 (&dirents, truepath, &peg_revision,
&(opt_state->start_revision),
opt_state->recursive, ctx, subpool));
Index: subversion/clients/cmdline/main.c
===================================================================
--- subversion/clients/cmdline/main.c (revision 15177)
+++ subversion/clients/cmdline/main.c (working copy)
@@ -379,12 +379,14 @@
"current\n"
" working directory.\n"
"\n"
- " With --verbose, the following fields show the status of the item:\n"
+ " With --verbose, the following fields will be shown for each item:\n"
"\n"
" Revision number of the last commit\n"
" Author of the last commit\n"
" Size (in bytes)\n"
- " Date and time of the last commit\n"),
+ " Date and time of the last commit\n"
+ " Date and time of the lock creation\n"
+ " Owner of the lock\n"),
{'r', 'v', 'R', svn_cl__incremental_opt, svn_cl__xml_opt,
SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },