Author: brane
Date: Sun Nov 25 22:27:07 2018
New Revision: 1847441
URL: http://svn.apache.org/viewvc?rev=1847441&view=rev
Log:
Show in-repository sizes of files with 'svn info'.
The file size is only displayed if the target of 'svn info' is a file URL.
With --show-item=repo-size, an error is returned if the target is a single
local path. However, if there are multiple local targets (e.g., in recursive
mode), nothing at all will be printed, since there are no valid results.
* subversion/libsvn_client/info.c
(DIRENT_FIELDS): Add SVN_DIRENT_SIZE to the mask, otherwise recursive
queries do not return file sizes, which is inconsistent with the
non-recursive or single-target case.
* subversion/svn/info-cmd.c
(info_item_t): Add new enumeration, info_item_repos_size.
(info_item_map): Map "repos-size" to info_item_repos_size.
(print_info_xml): If the file size is available, add a "size"
attribute to the <entry/> node.
(print_info): Print the file size if it's available.
(print_info_item): Handle info_item_repos_size.
* subversion/svn/svn.c (svn_cl__options): Describe --show-item=repos-size.
* subversion/tests/cmdline/info_tests.py
(info_item_size_wc_recursive,
info_item_size_repos,
info_item_size_repos_recursive) New test cases.
(info_item_failures): Test the size-of-WC-target failure mode.
Modified:
subversion/trunk/subversion/libsvn_client/info.c
subversion/trunk/subversion/svn/info-cmd.c
subversion/trunk/subversion/svn/svn.c
subversion/trunk/subversion/tests/cmdline/info_tests.py
Modified: subversion/trunk/subversion/libsvn_client/info.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/info.c?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/info.c (original)
+++ subversion/trunk/subversion/libsvn_client/info.c Sun Nov 25 22:27:07 2018
@@ -167,7 +167,8 @@ build_info_from_dirent(svn_client_info2_
#define DIRENT_FIELDS (SVN_DIRENT_KIND | \
SVN_DIRENT_CREATED_REV | \
SVN_DIRENT_TIME | \
- SVN_DIRENT_LAST_AUTHOR)
+ SVN_DIRENT_LAST_AUTHOR | \
+ SVN_DIRENT_SIZE)
/* Helper func for recursively fetching svn_dirent_t's from a remote
Modified: subversion/trunk/subversion/svn/info-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/info-cmd.c?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/info-cmd.c (original)
+++ subversion/trunk/subversion/svn/info-cmd.c Sun Nov 25 22:27:07 2018
@@ -352,6 +352,7 @@ typedef enum
info_item_relative_url,
info_item_repos_root_url,
info_item_repos_uuid,
+ info_item_repos_size,
/* Working copy revision or repository HEAD revision */
info_item_revision,
@@ -382,6 +383,7 @@ static const info_item_map_t info_item_m
{ MAKE_STRING("relative-url"), info_item_relative_url },
{ MAKE_STRING("repos-root-url"), info_item_repos_root_url },
{ MAKE_STRING("repos-uuid"), info_item_repos_uuid },
+ { MAKE_STRING("repos-size"), info_item_repos_size },
{ MAKE_STRING("revision"), info_item_revision },
{ MAKE_STRING("last-changed-revision"),
info_item_last_changed_rev },
@@ -507,21 +509,38 @@ print_info_xml(void *baton,
apr_pool_t *pool)
{
svn_stringbuf_t *sb = svn_stringbuf_create_empty(pool);
- const char *rev_str;
print_info_baton_t *const receiver_baton = baton;
- if (SVN_IS_VALID_REVNUM(info->rev))
- rev_str = apr_psprintf(pool, "%ld", info->rev);
- else
- rev_str = apr_pstrdup(pool, _("Resource is not under version control."));
+ const char *const path_str =
+ svn_cl__local_style_skip_ancestor(
+ receiver_baton->path_prefix, target, pool);
+ const char *const kind_str = svn_cl__node_kind_str_xml(info->kind);
+ const char *const rev_str =
+ (SVN_IS_VALID_REVNUM(info->rev)
+ ? apr_psprintf(pool, "%ld", info->rev)
+ : apr_pstrdup(pool, _("Resource is not under version control.")));
/* "<entry ...>" */
- svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
- "path", svn_cl__local_style_skip_ancestor(
- receiver_baton->path_prefix, target, pool),
- "kind", svn_cl__node_kind_str_xml(info->kind),
- "revision", rev_str,
- SVN_VA_NULL);
+ if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
+ {
+ const char *const size_str =
+ apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size);
+
+ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
+ "path", path_str,
+ "kind", kind_str,
+ "revision", rev_str,
+ "size", size_str,
+ SVN_VA_NULL);
+ }
+ else
+ {
+ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
+ "path", path_str,
+ "kind", kind_str,
+ "revision", rev_str,
+ SVN_VA_NULL);
+ }
/* "<url> xx </url>" */
svn_cl__xml_tagged_cdata(&sb, pool, "url", info->URL);
@@ -743,6 +762,11 @@ print_info(void *baton,
break;
}
+ if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
+ SVN_ERR(svn_cmdline_printf(pool, _("Size in Repository: %s\n"),
+ apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT,
+ info->size)));
+
if (info->wc_info)
{
switch (info->wc_info->schedule)
@@ -1083,11 +1107,12 @@ print_info_item(void *baton,
apr_pool_t *pool)
{
print_info_baton_t *const receiver_baton = baton;
+ const char *const actual_target_path =
+ (!receiver_baton->target_is_path ? info->URL
+ : svn_cl__local_style_skip_ancestor(
+ receiver_baton->path_prefix, target, pool));
const char *const target_path =
- (!receiver_baton->multiple_targets ? NULL
- : (!receiver_baton->target_is_path ? info->URL
- : svn_cl__local_style_skip_ancestor(
- receiver_baton->path_prefix, target, pool)));
+ (receiver_baton->multiple_targets ? actual_target_path : NULL);
if (receiver_baton->start_new_line)
SVN_ERR(svn_cmdline_fputs("\n", stdout, pool));
@@ -1116,6 +1141,32 @@ print_info_item(void *baton,
SVN_ERR(print_info_item_string(info->repos_UUID, target_path, pool));
break;
+ case info_item_repos_size:
+ if (info->kind != svn_node_file)
+ {
+ receiver_baton->start_new_line = FALSE;
+ return SVN_NO_ERROR;
+ }
+
+ if (info->size == SVN_INVALID_FILESIZE)
+ {
+ if (receiver_baton->multiple_targets)
+ {
+ receiver_baton->start_new_line = FALSE;
+ return SVN_NO_ERROR;
+ }
+
+ return svn_error_createf(
+ SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+ _("can't show in-repository size of working copy file '%s'"),
+ actual_target_path);
+ }
+
+ SVN_ERR(print_info_item_string(
+ apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size),
+ target_path, pool));
+ break;
+
case info_item_revision:
SVN_ERR(print_info_item_revision(info->rev, target_path, pool));
break;
Modified: subversion/trunk/subversion/svn/svn.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Sun Nov 25 22:27:07 2018
@@ -444,6 +444,10 @@ const apr_getopt_option_t svn_cl__option
" "
" 'repos-uuid' UUID of repository\n"
" "
+ " 'repos-size' for files, the size of TARGET\n"
+ " "
+ " in the repository\n"
+ " "
" 'revision' specified or implied revision\n"
" "
" 'last-changed-revision'\n"
Modified: subversion/trunk/subversion/tests/cmdline/info_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/info_tests.py?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/info_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/info_tests.py Sun Nov 25 22:27:07
2018
@@ -716,6 +716,59 @@ def info_item_uncommmitted(sbox):
sbox.ospath('newfile'), sbox.ospath('newdir'))
+def info_item_size_wc_recursive(sbox):
+ "recursive '--show-item=repos-size' on local path"
+
+ sbox.build(read_only=True)
+
+ svntest.actions.run_and_verify_svn(
+ [], [],
+ 'info', '--show-item=repos-size', '--recursive',
+ sbox.ospath(''))
+
+
+def info_item_size_repos(sbox):
+ "non-recursive '--show-item=repos-size' on file URL"
+
+ sbox.build(read_only=True)
+
+ svntest.actions.run_and_verify_svn(
+ "25\n", [],
+ 'info', '--show-item=repos-size',
+ sbox.repo_url + "/iota")
+
+ svntest.actions.run_and_verify_svn(
+ "25", [],
+ 'info', '--show-item=repos-size', '--no-newline',
+ sbox.repo_url + "/iota")
+
+
+def info_item_size_repos_recursive(sbox):
+ "recursive '--show-item=repos-size' on dir URL"
+
+ sbox.build(read_only=True)
+
+ expected_output = svntest.verify.UnorderedOutput([
+ "25 " + sbox.repo_url + "/iota\n",
+ "27 " + sbox.repo_url + "/A/B/lambda\n",
+ "25 " + sbox.repo_url + "/A/B/E/beta\n",
+ "26 " + sbox.repo_url + "/A/B/E/alpha\n",
+ "23 " + sbox.repo_url + "/A/mu\n",
+ "26 " + sbox.repo_url + "/A/D/gamma\n",
+ "23 " + sbox.repo_url + "/A/D/G/pi\n",
+ "24 " + sbox.repo_url + "/A/D/G/rho\n",
+ "24 " + sbox.repo_url + "/A/D/G/tau\n",
+ "26 " + sbox.repo_url + "/A/D/H/omega\n",
+ "24 " + sbox.repo_url + "/A/D/H/psi\n",
+ "24 " + sbox.repo_url + "/A/D/H/chi\n",
+ ])
+
+ svntest.actions.run_and_verify_svn(
+ expected_output, [],
+ 'info', '--show-item=repos-size', '--recursive',
+ sbox.repo_url)
+
+
def info_item_failures(sbox):
"failure modes of 'svn info --show-item'"
@@ -746,6 +799,11 @@ def info_item_failures(sbox):
'info', '--show-item=revision', '--no-newline',
sbox.ospath('A'), sbox.ospath('iota'))
+ svntest.actions.run_and_verify_svn(
+ None, (r".*E200007: can't show in-repository size.*"),
+ 'info', '--show-item=repos-size',
+ sbox.ospath('iota'))
+
########################################################################
# Run the tests
@@ -767,6 +825,9 @@ test_list = [ None,
info_item_simple_multiple,
info_item_url,
info_item_uncommmitted,
+ info_item_size_wc_recursive,
+ info_item_size_repos,
+ info_item_size_repos_recursive,
info_item_failures,
]