You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/01/29 22:52:36 UTC
svn commit: r1655872 - in /subversion/branches/pin-externals/subversion:
libsvn_client/copy.c tests/cmdline/externals_tests.py
Author: stsp
Date: Thu Jan 29 21:52:36 2015
New Revision: 1655872
URL: http://svn.apache.org/r1655872
Log:
On the pin-externals branch, make WC->WC copies offline operations notI
contact the reposiory even if --pin-externals is active.
Suggested by: brane
rhuijben
* subversion/libsvn_client/copy.c
(pin_externals_prop): Rewrite this function such that externals are
never implicitly pinned with -rN (where N is the last-changed revision).
A peg revision suffices. If the copy source is a WC determine the peg
revision of externals from the checked out external (file or dir) and
error out if the external isn't checked out. Stop resolving -r{DATE}
style operative and peg revisions to a revision number and pin such
externals to a dated revision instead.
* subversion/tests/cmdline/externals_tests.py
(copy_pin_externals): Adjust expected output. Fix a problem in this test
where some externals were unversioned after a parent directory was moved.
Modified:
subversion/branches/pin-externals/subversion/libsvn_client/copy.c
subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py
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=1655872&r1=1655871&r2=1655872&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_client/copy.c Thu Jan 29 21:52:36 2015
@@ -179,7 +179,7 @@ get_copy_pair_ancestors(const apr_array_
/* Pin all externals listed in EXTERNALS_PROP_VAL to their last-changed
* revision. Return a new property value in *PINNED_EXTERNALS allocated
- * in RESULT_POOL. LOCAL_ABSPATH_OR_URL is the path defining the
+ * in RESULT_POOL. LOCAL_ABSPATH_OR_URL is the path or URL defining the
* svn:externals property. Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
@@ -193,7 +193,6 @@ pin_externals_prop(svn_string_t **pinned
{
svn_stringbuf_t *buf;
apr_array_header_t *external_items;
- const char *session_url;
int i;
apr_pool_t *iterpool;
@@ -208,95 +207,110 @@ pin_externals_prop(svn_string_t **pinned
for (i = 0; i < external_items->nelts; i++)
{
svn_wc_external_item2_t *item;
+ svn_opt_revision_t external_pegrev;
const char *pinned_desc;
- const char *resolved_url;
- const char *defining_url;
- svn_ra_session_t *external_ra_session;
- svn_revnum_t external_youngest_rev;
- svn_dirent_t *dirent;
+ const char *rev_str;
+ const char *peg_rev_str;
svn_pool_clear(iterpool);
- if (!svn_path_is_url(local_abspath_or_url))
- SVN_ERR(svn_wc__node_get_url(&defining_url, ctx->wc_ctx,
- local_abspath_or_url,
- iterpool, iterpool));
- else
- defining_url = local_abspath_or_url;
-
item = APR_ARRAY_IDX(external_items, i, svn_wc_external_item2_t *);
- SVN_ERR(svn_wc__resolve_relative_external_url(&resolved_url, item,
- repos_root_url,
- defining_url,
- iterpool,
- iterpool));
- SVN_ERR(svn_client__open_ra_session_internal(&external_ra_session,
- NULL, resolved_url,
- NULL, NULL, FALSE, FALSE,
- ctx, iterpool,
- iterpool));
- SVN_ERR(svn_ra_get_session_url(external_ra_session, &session_url, scratch_pool));
- if (item->peg_revision.kind == svn_opt_revision_unspecified ||
- item->peg_revision.kind == svn_opt_revision_head)
+
+ if (item->peg_revision.kind == svn_opt_revision_date)
+ {
+ external_pegrev.kind = svn_opt_revision_date;
+ external_pegrev.value.date = item->peg_revision.value.date;
+ }
+ else if (item->peg_revision.kind == svn_opt_revision_number)
{
- SVN_ERR(svn_ra_get_latest_revnum(external_ra_session,
- &external_youngest_rev,
- iterpool));
+ external_pegrev.kind = svn_opt_revision_number;
+ external_pegrev.value.number = item->peg_revision.value.number;
}
else
{
- if (item->peg_revision.kind == svn_opt_revision_date)
+ SVN_ERR_ASSERT(
+ item->peg_revision.kind == svn_opt_revision_head ||
+ item->peg_revision.kind == svn_opt_revision_unspecified);
+
+ if (svn_path_is_url(local_abspath_or_url))
{
- item->peg_revision.kind = svn_opt_revision_number;
- SVN_ERR(svn_ra_get_dated_revision(external_ra_session,
- &item->peg_revision.value.number,
- item->peg_revision.value.date,
- iterpool));
+ const char *resolved_url;
+ svn_ra_session_t *external_ra_session;
+ svn_revnum_t latest_revnum;
+
+ SVN_ERR(svn_wc__resolve_relative_external_url(
+ &resolved_url, item, repos_root_url,
+ local_abspath_or_url, iterpool, iterpool));
+ SVN_ERR(svn_client__open_ra_session_internal(&external_ra_session,
+ NULL, resolved_url,
+ NULL, NULL, FALSE,
+ FALSE, ctx,
+ iterpool,
+ iterpool));
+ SVN_ERR(svn_ra_get_latest_revnum(external_ra_session,
+ &latest_revnum,
+ iterpool));
+
+ external_pegrev.kind = svn_opt_revision_number;
+ external_pegrev.value.number = latest_revnum;
}
+ else
+ {
+ const char *external_abspath;
+ svn_node_kind_t external_kind;
- SVN_ERR_ASSERT(item->peg_revision.kind == svn_opt_revision_number);
- external_youngest_rev = item->peg_revision.value.number;
+ external_abspath = svn_dirent_join(local_abspath_or_url,
+ item->target_dir,
+ iterpool);
+ SVN_ERR(svn_wc__read_external_info(&external_kind, NULL, NULL,
+ NULL, NULL, ctx->wc_ctx,
+ local_abspath_or_url,
+ external_abspath, TRUE,
+ iterpool,
+ iterpool));
+ if (external_kind == svn_node_none)
+ return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
+ NULL,
+ _("Cannot pin external '%s' defined "
+ "in %s at '%s' because it is not "
+ "checked out in the working copy "
+ "at '%s'"),
+ item->url, SVN_PROP_EXTERNALS,
+ svn_dirent_local_style(
+ local_abspath_or_url, iterpool),
+ svn_dirent_local_style(
+ external_abspath, iterpool));
+
+ external_pegrev.kind = svn_opt_revision_number;
+ SVN_ERR(svn_wc__node_get_repos_info(&external_pegrev.value.number,
+ NULL, NULL, NULL,
+ ctx->wc_ctx, external_abspath,
+ iterpool, iterpool));
+ }
}
-
- SVN_ERR(svn_ra_stat(external_ra_session, "",
- external_youngest_rev,
- &dirent,
- iterpool));
- if (dirent == NULL)
- return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
- _("Cannot pin external URL '%s' since it "
- "does not exist at revision %lu"),
- resolved_url, external_youngest_rev);
if (item->revision.kind == svn_opt_revision_date)
- {
- item->revision.kind = svn_opt_revision_number;
- SVN_ERR(svn_ra_get_dated_revision(external_ra_session,
- &item->revision.value.number,
- item->revision.value.date,
- iterpool));
- }
+ 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 = "";
- if (item->revision.kind != svn_opt_revision_number)
- {
- item->revision.kind = svn_opt_revision_number;
- item->revision.value.number = dirent->created_rev;
- }
+ 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);
- if (item->peg_revision.kind != svn_opt_revision_number)
- {
- item->peg_revision.kind = svn_opt_revision_number;
- item->peg_revision.value.number = dirent->created_rev;
- }
-
- SVN_ERR_ASSERT(item->revision.kind == svn_opt_revision_number);
- SVN_ERR_ASSERT(item->peg_revision.kind == svn_opt_revision_number);
-
- pinned_desc = apr_psprintf(iterpool, "-r%lu %s@%lu %s\n",
- item->revision.value.number,
- item->url,
- external_youngest_rev,
- item->target_dir);
+ pinned_desc = apr_psprintf(iterpool, "%s%s%s %s\n", rev_str, item->url,
+ peg_rev_str, item->target_dir);
svn_stringbuf_appendcstr(buf, pinned_desc);
}
svn_pool_destroy(iterpool);
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=1655872&r1=1655871&r2=1655872&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py Thu Jan 29 21:52:36 2015
@@ -3571,13 +3571,11 @@ def copy_pin_externals(sbox):
# Verify that externals have been pinned.
last_changed_rev_gamma = 1
- last_changed_rev_A = 5
A_copy_D_path = 'A_copy/D'
def verify_pinned_externals(base_path_or_url):
expected_output = [
- '-r%d %s@%d gamma\n' % (last_changed_rev_gamma,
- external_url_for["A/B/gamma"],
- external_youngest_rev),
+ '%s@%d gamma\n' % (external_url_for["A/B/gamma"],
+ external_youngest_rev),
'\n',
]
if svntest.sandbox.is_url(base_path_or_url):
@@ -3588,8 +3586,8 @@ def copy_pin_externals(sbox):
'propget', 'svn:externals',
target)
expected_output = [
- '-r3 %s@%d exdir_G\n' % (external_url_for["A/C/exdir_G"],
- other_external_youngest_rev),
+ '%s@%d exdir_G\n' % (external_url_for["A/C/exdir_G"],
+ other_external_youngest_rev),
# 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"],
@@ -3603,14 +3601,13 @@ def copy_pin_externals(sbox):
'propget', 'svn:externals',
target)
expected_output = [
- '-r%d %s@%d exdir_A\n' % (last_changed_rev_A,
- external_url_for["A/D/exdir_A"],
- other_external_youngest_rev),
- '-r3 %s@%d exdir_A/G\n' % (external_url_for["A/D/exdir_A/G/"],
- other_external_youngest_rev),
+ '%s@%d exdir_A\n' % (external_url_for["A/D/exdir_A"],
+ other_external_youngest_rev),
+ '%s@%d exdir_A/G\n' % (external_url_for["A/D/exdir_A/G/"],
+ other_external_youngest_rev),
'-r1 %s@1 exdir_A/H\n' % external_url_for["A/D/exdir_A/H"],
- '-r4 %s@%d x/y/z/blah\n' % (external_url_for["A/D/x/y/z/blah"],
- other_external_youngest_rev),
+ '%s@%d x/y/z/blah\n' % (external_url_for["A/D/x/y/z/blah"],
+ other_external_youngest_rev),
'\n',
]
if svntest.sandbox.is_url(base_path_or_url):
@@ -3663,6 +3660,7 @@ def copy_pin_externals(sbox):
# Perform a wc->wc copy, pinning externals
external_youngest_rev = svntest.main.youngest(repo_dir)
+ sbox.simple_update()
svntest.actions.run_and_verify_svn(None, None, [],
'copy',
os.path.join(wc_dir, 'A'),
@@ -3701,7 +3699,10 @@ def copy_pin_externals(sbox):
sbox.simple_move('A/D', 'A/D-moved')
change_external(sbox.ospath('A/B'), '^/A/D-moved/gamma-moved gamma', commit=False)
sbox.simple_commit()
- sbox.simple_update()
+ # remove externals which are now considered unversioned obstructions...
+ svntest.main.safe_rmtree(sbox.ospath('A/D-moved/exdir_A'))
+ svntest.main.safe_rmtree(sbox.ospath('A/D-moved/x'))
+ sbox.simple_update() # pull above externals back in
external_youngest_rev = svntest.main.youngest(repo_dir)
svntest.actions.run_and_verify_svn(None, None, [],
'copy',
@@ -3732,7 +3733,6 @@ def copy_pin_externals(sbox):
os.path.join(wc_dir, 'A'),
os.path.join(wc_dir, 'A_copy'),
'--pin-externals')
- last_changed_rev_A = 6
verify_pinned_externals(wc_dir)
# Clean up.