Author: stsp
Date: Tue Feb 3 17:50:43 2015
New Revision: 1656845
URL: http://svn.apache.org/r1656845
Log:
On the pin-externals branch, preserve the strings used to specify peg and
operative revisions of already pinned externals.
This keeps revisions such as "-r{2015-02-04}" intact instead of expanding
them to longer strings such as "-r{2015-02-03T23:00:00.000000Z}".
Suggested by: brane
julianfoad
* subversion/include/private/svn_wc_private.h
(svn_wc__externals_parser_info_t): New. Contains extended information
about lines parsed from svn:externals properties.
(svn_wc__parse_externals_description): New output parameter parser_infos_p.
* subversion/libsvn_client/copy.c
(pin_externals_prop): Use extended information returned by the parser to
keep pinned externals pinned as the user would expect.
* subversion/libsvn_wc/externals.c
(find_and_remove_externals_revision): Return the original revision string.
(svn_wc__parse_externals_description): Return additional information about
the parsed external, including the syntax format, operational revisions,
and peg revisions.
* subversion/tests/cmdline/externals_tests.py
(copy_pin_externals): The above changes fix a bug where an operative
revision was added unnecessarily when pinning. Adjust expected output.
Modified:
subversion/branches/pin-externals/subversion/include/private/svn_wc_private.h
subversion/branches/pin-externals/subversion/libsvn_client/copy.c
subversion/branches/pin-externals/subversion/libsvn_wc/externals.c
subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py
Modified:
subversion/branches/pin-externals/subversion/include/private/svn_wc_private.h
URL:
http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/include/private/svn_wc_private.h?rev=1656845&r1=1656844&r2=1656845&view=diff
==============================================================================
---
subversion/branches/pin-externals/subversion/include/private/svn_wc_private.h
(original)
+++
subversion/branches/pin-externals/subversion/include/private/svn_wc_private.h
Tue Feb 3 17:50:43 2015
@@ -1268,14 +1268,31 @@ typedef enum svn_wc__external_descriptio
svn_wc__external_description_format_2
} svn_wc__external_description_format_t;
+/* Additional information about what the external's parser has parsed. */
+typedef struct svn_wc__externals_parser_info_t
+{
+ /* The syntax format used by the external description. */
+ svn_wc__external_description_format_t format;
+
+ /* The string used for defining the operative revision, i.e.
+ "-rN", "-rHEAD", or "-r{DATE}".
+ NULL if revision was not given. */
+ const char *rev_str;
+
+ /* The string used for defining the peg revision (equals rev_str in
+ format 1, is "@N", or "@HEAD" or "@{DATE}" in format 2).
+ NULL if peg revision was not given. */
+ const char *peg_rev_str;
+
+} svn_wc__externals_parser_info_t;
+
/* Like svn_wc_parse_externals_description3() but returns an additional array
- * with elements of type svn_wc__external_description_format_t. Each element
- * of which indicates the format of the syntax used to define the corresponding
- * external. @a description_formats_p may be NULL if not required by the
caller.
+ * with elements of type svn_wc__externals_parser_info_t in @a *parser_infos_p.
+ * @a parser_infos_p may be NULL if not required by the caller.
*/
svn_error_t *
svn_wc__parse_externals_description(apr_array_header_t **externals_p,
- apr_array_header_t **description_formats_p,
+ apr_array_header_t **parser_infos_p,
const char *defining_directory,
const char *desc,
svn_boolean_t canonicalize_url,
Modified: subversion/branches/pin-externals/subversion/libsvn_client/copy.c
URL:
http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_client/copy.c?rev=1656845&r1=1656844&r2=1656845&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_client/copy.c Tue Feb
3 17:50:43 2015
@@ -193,12 +193,12 @@ pin_externals_prop(svn_string_t **pinned
{
svn_stringbuf_t *buf;
apr_array_header_t *external_items;
- apr_array_header_t *description_formats;
+ apr_array_header_t *parser_infos;
int i;
apr_pool_t *iterpool;
SVN_ERR(svn_wc__parse_externals_description(&external_items,
- &description_formats,
+ &parser_infos,
local_abspath_or_url,
externals_prop_val->data,
FALSE /* canonicalize_url */,
@@ -209,7 +209,7 @@ pin_externals_prop(svn_string_t **pinned
for (i = 0; i < external_items->nelts; i++)
{
svn_wc_external_item2_t *item;
- svn_wc__external_description_format_t format;
+ svn_wc__externals_parser_info_t *info;
svn_opt_revision_t external_pegrev;
const char *pinned_desc;
const char *rev_str;
@@ -218,8 +218,7 @@ pin_externals_prop(svn_string_t **pinned
svn_pool_clear(iterpool);
item = APR_ARRAY_IDX(external_items, i, svn_wc_external_item2_t *);
- format = APR_ARRAY_IDX(description_formats, i,
- svn_wc__external_description_format_t);
+ info = APR_ARRAY_IDX(parser_infos, i, svn_wc__externals_parser_info_t *);
if (item->peg_revision.kind == svn_opt_revision_date)
{
@@ -294,37 +293,40 @@ pin_externals_prop(svn_string_t **pinned
}
}
- if (item->revision.kind == svn_opt_revision_date)
- rev_str = apr_psprintf(iterpool, "-r{%s} ",
- svn_time_to_cstring(item->revision.value.date,
- iterpool));
- else if (item->revision.kind == svn_opt_revision_number)
- rev_str = apr_psprintf(iterpool, "-r%ld ",
item->revision.value.number);
- else
- rev_str = "";
-
SVN_ERR_ASSERT(external_pegrev.kind == svn_opt_revision_date ||
external_pegrev.kind == svn_opt_revision_number);
- if (external_pegrev.kind == svn_opt_revision_date)
- peg_rev_str = apr_psprintf(iterpool, "@{%s}",
- svn_time_to_cstring(
- external_pegrev.value.date,
- iterpool));
- else
- peg_rev_str = apr_psprintf(iterpool, "@%ld",
- external_pegrev.value.number);
- switch (format)
+ switch (info->format)
{
case svn_wc__external_description_format_1:
- if (rev_str[0] == '\0')
- rev_str = apr_psprintf(iterpool, "-r%ld ",
- external_pegrev.value.number);
+ if (info->rev_str && item->revision.kind != svn_opt_revision_head)
+ rev_str = apr_psprintf(iterpool, "%s ", info->rev_str);
+ else
+ {
+ SVN_ERR_ASSERT(external_pegrev.kind ==
svn_opt_revision_number);
+ rev_str = apr_psprintf(iterpool, "-r%ld ",
+ external_pegrev.value.number);
+ }
+
pinned_desc = apr_psprintf(iterpool, "%s %s%s\n", item->target_dir,
rev_str, item->url);
break;
case svn_wc__external_description_format_2:
+ if (info->rev_str && item->revision.kind != svn_opt_revision_head)
+ rev_str = apr_psprintf(iterpool, "%s ", info->rev_str);
+ else
+ rev_str = "";
+
+ if (info->peg_rev_str &&
+ item->peg_revision.kind != svn_opt_revision_head)
+ peg_rev_str = info->peg_rev_str;
+ else
+ {
+ SVN_ERR_ASSERT(external_pegrev.kind ==
svn_opt_revision_number);
+ peg_rev_str = apr_psprintf(iterpool, "@%ld",
+ external_pegrev.value.number);
+ }
pinned_desc = apr_psprintf(iterpool, "%s%s%s %s\n", rev_str,
item->url,
peg_rev_str, item->target_dir);
break;
Modified: subversion/branches/pin-externals/subversion/libsvn_wc/externals.c
URL:
http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_wc/externals.c?rev=1656845&r1=1656844&r2=1656845&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_wc/externals.c
(original)
+++ subversion/branches/pin-externals/subversion/libsvn_wc/externals.c Tue Feb
3 17:50:43 2015
@@ -68,6 +68,7 @@
* the revision if the revision is found. Set REV_IDX to the index in
* LINE_PARTS where the revision specification starts. Remove from
* LINE_PARTS the element(s) that specify the revision.
+ * Set REV_STR to the element that specifies the revision.
* PARENT_DIRECTORY_DISPLAY and LINE are given to return a nice error
* string.
*
@@ -76,6 +77,7 @@
*/
static svn_error_t *
find_and_remove_externals_revision(int *rev_idx,
+ const char **rev_str,
const char **line_parts,
int num_line_parts,
svn_wc_external_item2_t *item,
@@ -137,6 +139,8 @@ find_and_remove_externals_revision(int *
line_parts[j] = line_parts[j+shift_count];
line_parts[num_line_parts-shift_count] = NULL;
+ *rev_str = apr_psprintf(pool, "-r%s", digits_ptr);
+
/* Found the revision, so leave the function immediately, do
* not continue looking for additional revisions. */
return SVN_NO_ERROR;
@@ -159,7 +163,7 @@ find_and_remove_externals_revision(int *
svn_error_t *
svn_wc__parse_externals_description(apr_array_header_t **externals_p,
- apr_array_header_t **description_formats_p,
+ apr_array_header_t **parser_infos_p,
const char *defining_directory,
const char *desc,
svn_boolean_t canonicalize_url,
@@ -167,7 +171,7 @@ svn_wc__parse_externals_description(apr_
{
int i;
apr_array_header_t *externals = NULL;
- apr_array_header_t *description_formats = NULL;
+ apr_array_header_t *parser_infos = NULL;
apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool);
const char *defining_directory_display = svn_path_is_url(defining_directory)
?
defining_directory : svn_dirent_local_style(defining_directory, pool);
@@ -177,9 +181,9 @@ svn_wc__parse_externals_description(apr_
if (externals_p)
externals = apr_array_make(pool, 1, sizeof(svn_wc_external_item2_t *));
- if (description_formats_p)
- description_formats =
- apr_array_make(pool, 1, sizeof(svn_wc__external_description_format_t));
+ if (parser_infos_p)
+ parser_infos =
+ apr_array_make(pool, 1, sizeof(svn_wc__externals_parser_info_t *));
for (i = 0; i < lines->nelts; i++)
{
@@ -192,11 +196,12 @@ svn_wc__parse_externals_description(apr_
const char *token1;
svn_boolean_t token0_is_url;
svn_boolean_t token1_is_url;
- svn_wc__external_description_format_t format;
+ svn_wc__externals_parser_info_t *info = NULL;
/* Index into line_parts where the revision specification
started. */
int rev_idx = -1;
+ const char *rev_str = NULL;
if ((! line) || (line[0] == '#'))
continue;
@@ -216,6 +221,9 @@ svn_wc__parse_externals_description(apr_
item->revision.kind = svn_opt_revision_unspecified;
item->peg_revision.kind = svn_opt_revision_unspecified;
+ if (parser_infos)
+ info = apr_pcalloc(pool, sizeof(*info));
+
/*
* There are six different formats of externals:
*
@@ -247,6 +255,7 @@ svn_wc__parse_externals_description(apr_
set item->revision to the parsed revision. */
/* ### ugh. stupid cast. */
SVN_ERR(find_and_remove_externals_revision(&rev_idx,
+ &rev_str,
(const char **)line_parts,
num_line_parts, item,
defining_directory_display,
@@ -297,14 +306,34 @@ svn_wc__parse_externals_description(apr_
SVN_ERR(svn_opt_parse_path(&item->peg_revision, &item->url,
token0, pool));
item->target_dir = token1;
- format = svn_wc__external_description_format_2;
+
+ if (info)
+ {
+ info->format = svn_wc__external_description_format_2;
+
+ if (rev_str)
+ info->rev_str = apr_pstrdup(pool, rev_str);
+
+ if (item->peg_revision.kind != svn_opt_revision_unspecified)
+ info->peg_rev_str = strrchr(token0, '@');
+ }
}
else
{
item->target_dir = token0;
item->url = token1;
item->peg_revision = item->revision;
- format = svn_wc__external_description_format_1;
+
+ if (info)
+ {
+ info->format = svn_wc__external_description_format_1;
+
+ if (rev_str)
+ {
+ info->rev_str = apr_pstrdup(pool, rev_str);
+ info->peg_rev_str = info->rev_str;
+ }
+ }
}
SVN_ERR(svn_opt_resolve_revisions(&item->peg_revision,
@@ -342,15 +371,14 @@ svn_wc__parse_externals_description(apr_
if (externals)
APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item;
- if (description_formats)
- APR_ARRAY_PUSH(description_formats,
- svn_wc__external_description_format_t) = format;
+ if (parser_infos)
+ APR_ARRAY_PUSH(parser_infos, svn_wc__externals_parser_info_t *) = info;
}
if (externals_p)
*externals_p = externals;
- if (description_formats_p)
- *description_formats_p = description_formats;
+ if (parser_infos_p)
+ *parser_infos_p = parser_infos;
return SVN_NO_ERROR;
}
Modified:
subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py
URL:
http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py?rev=1656845&r1=1656844&r2=1656845&view=diff
==============================================================================
---
subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py
(original)
+++
subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py
Tue Feb 3 17:50:43 2015
@@ -3588,9 +3588,7 @@ def copy_pin_externals(sbox):
expected_output = [
'exdir_G -r%d %s\n' % (other_external_youngest_rev,
external_url_for["A/C/exdir_G"]),
- # Note: A/D/H was last changed in r5, but exdir_H's external
- # definition's URL is already pinned to r1.
- '-r1 %s exdir_H\n' % external_url_for["A/C/exdir_H"],
+ '%s exdir_H\n' % external_url_for["A/C/exdir_H"],
'\n',
]
if svntest.sandbox.is_url(base_path_or_url):