Author: julianfoad
Date: Thu Aug 20 16:56:11 2015
New Revision: 1696816
URL: http://svn.apache.org/r1696816
Log:
On the 'move-tracking-2' branch: Implement '^B<branch-id>/path' syntax for
svnmover path inputs.
The full syntax is
[^B<branch-id>/]relpath[@rev]
When BRANCH-ID is given, this means the relative path RELPATH within the
branch. When branches are nested, this may identify an element in a branch
that is nested inside branch <branch-id>; in case of multiple nesting, the
most deeply nested branch is found.
When the '^B<branch-id>/' prefix is not given, look inside the same branch
id as the WC base branch when a revision number is given, and look inside
the WC working branch when a revision number is not given.
* subversion/include/private/svn_branch.h,
subversion/libsvn_delta/branch.c
(svn_branch_repos_find_el_rev_by_path_rev): Take an arbitrary branch id
and a branch-relative path instead of a top-level branch number and a
repository-relative path.
(svn_branch_find_nested_branch_element_by_relpath): Rename from
svn_branch_find_nested_branch_element_by_rrpath. Take a branch-relative
path instead of a repository-relative path.
(svn_branch_repos_get_branch_by_id): New.
(svn_branch_repos_find_el_rev_by_id): Simplify by using
svn_branch_repos_get_branch_by_id; this also means it will throw an
error instead of crashing if the branch is not found.
* subversion/libsvn_delta/compat3e.c
(drive_changes_r,
drive_changes_branch): Track the change to
svn_branch_repos_find_el_rev_by_path_rev(), by identifying the top-level
branch by its branch-id rather than its top-level branch number.
* subversion/svnmover/svnmover.h
(svnmover_wc_t): Remove the 'top_branch_num' field.
* subversion/svnmover/svnmover.c
(wc_create): Remove initialization of the obsolete 'top_branch_num' field.
(action_t): Add a 'branch_id' field.
(find_el_rev_by_rrpath_rev): Look up the path in a given branch, defaulting
to the base branch when looking in a given revision or the working branch
otherwise.
(execute): Pass on the branch id when looking up a path. Remove a
re-initialization of the obsolete 'top_branch_num' field.
(parse_actions): Parse "^B<branch-id>/path" syntax.
(sub_main): No longer pass the obsolete 'top_branch_num' parameter to
wc_create().
Modified:
subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h
Modified:
subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h?rev=1696816&r1=1696815&r2=1696816&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
(original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
Thu Aug 20 16:56:11 2015
@@ -144,6 +144,16 @@ svn_branch_repos_get_root_branch(const s
svn_revnum_t revnum,
int top_branch_num);
+/* Set *BRANCH_P to the branch found in REPOS : REVNUM : BRANCH_ID.
+ *
+ * Return an error if REVNUM or BRANCH_ID is not found.
+ */
+svn_error_t *
+svn_branch_repos_get_branch_by_id(svn_branch_state_t **branch_p,
+ const svn_branch_repos_t *repos,
+ svn_revnum_t revnum,
+ const char *branch_id,
+ apr_pool_t *scratch_pool);
/* Set *EL_REV_P to the el-rev-id of the element at branch id BRANCH_ID,
* element id EID, in revision REVNUM in REPOS.
*
@@ -163,8 +173,8 @@ svn_branch_repos_find_el_rev_by_id(svn_b
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Set *EL_REV_P to the el-rev-id of the element at repos-relpath RRPATH
- * in revision REVNUM in REPOS.
+/* Set *EL_REV_P to the el-rev-id of the element at relative path RELPATH
+ * anywhere in or under branch BRANCH_ID in revision REVNUM in REPOS.
*
* If there is no element there, set *EL_REV_P to point to an id in which
* the BRANCH field is the nearest enclosing branch of RRPATH and the EID
@@ -177,10 +187,10 @@ svn_branch_repos_find_el_rev_by_id(svn_b
*/
svn_error_t *
svn_branch_repos_find_el_rev_by_path_rev(svn_branch_el_rev_id_t **el_rev_p,
- const char *rrpath,
- int top_branch_num,
- svn_revnum_t revnum,
const svn_branch_repos_t *repos,
+ svn_revnum_t revnum,
+ const char *branch_id,
+ const char *relpath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -701,27 +711,27 @@ svn_branch_get_eid_by_rrpath(svn_branch_
const char *rrpath,
apr_pool_t *scratch_pool);
-/* Find the (deepest) branch of which the path RRPATH is either the root
+/* Find the (deepest) branch of which the path RELPATH is either the root
* path or a normal, non-sub-branch path. An element need not exist at
- * RRPATH.
+ * RELPATH.
*
* Set *BRANCH_P to the deepest branch within ROOT_BRANCH (recursively,
- * including itself) that contains the path RRPATH.
+ * including itself) that contains the path RELPATH.
*
- * If EID_P is not null then set *EID_P to the element id of RRPATH in
- * *BRANCH_P, or to -1 if no element exists at RRPATH in that branch.
+ * If EID_P is not null then set *EID_P to the element id of RELPATH in
+ * *BRANCH_P, or to -1 if no element exists at RELPATH in that branch.
*
- * If RRPATH is not within any branch in ROOT_BRANCH, set *BRANCH_P to
+ * If RELPATH is not within any branch in ROOT_BRANCH, set *BRANCH_P to
* NULL and (if EID_P is not null) *EID_P to -1.
*
* ### TODO: Clarify sequencing requirements.
*/
void
-svn_branch_find_nested_branch_element_by_rrpath(
+svn_branch_find_nested_branch_element_by_relpath(
svn_branch_state_t **branch_p,
int *eid_p,
svn_branch_state_t *root_branch,
- const char *rrpath,
+ const char *relpath,
apr_pool_t *scratch_pool);
/* Get the default branching metadata for r0 of a new repository.
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c?rev=1696816&r1=1696815&r2=1696816&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c Thu
Aug 20 16:56:11 2015
@@ -1217,51 +1217,74 @@ svn_branch_revision_root_serialize(svn_s
*/
void
-svn_branch_find_nested_branch_element_by_rrpath(
+svn_branch_find_nested_branch_element_by_relpath(
svn_branch_state_t **branch_p,
int *eid_p,
svn_branch_state_t *root_branch,
- const char *rrpath,
+ const char *relpath,
apr_pool_t *scratch_pool)
{
- const char *branch_root_path = svn_branch_get_root_rrpath(root_branch,
- scratch_pool);
- SVN_ITER_T(svn_branch_state_t) *bi;
-
- if (! svn_relpath_skip_ancestor(branch_root_path, rrpath))
- {
- /* The path we're looking for is not (path-wise) in this branch. */
- *branch_p = NULL;
- if (eid_p)
- *eid_p = -1;
- return;
- }
-
/* The path we're looking for is (path-wise) in this branch. See if it
- is also in a sub-branch (recursively). */
- for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
- root_branch, scratch_pool, scratch_pool),
- scratch_pool))
+ is also in a sub-branch. */
+ while (TRUE)
{
- svn_branch_state_t *subbranch;
- int subbranch_eid;
+ SVN_ITER_T(svn_branch_state_t) *bi;
+ svn_boolean_t found = FALSE;
- svn_branch_find_nested_branch_element_by_rrpath(&subbranch,
- &subbranch_eid,
- bi->val, rrpath,
- bi->iterpool);
- if (subbranch)
+ for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
+ root_branch, scratch_pool, scratch_pool),
+ scratch_pool))
{
- *branch_p = subbranch;
- if (eid_p)
- *eid_p = subbranch_eid;
- return;
- }
+ svn_branch_state_t *subbranch = bi->val;
+ const char *relpath_to_subbranch;
+ const char *relpath_in_subbranch;
+
+ relpath_to_subbranch
+ = svn_branch_get_path_by_eid(root_branch, subbranch->outer_eid,
+ scratch_pool);
+
+ relpath_in_subbranch
+ = svn_relpath_skip_ancestor(relpath_to_subbranch, relpath);
+ if (relpath_in_subbranch)
+ {
+ root_branch = subbranch;
+ relpath = relpath_in_subbranch;
+ found = TRUE;
+ break;
+ }
+ }
+ if (! found)
+ {
+ break;
+ }
}
*branch_p = root_branch;
if (eid_p)
- *eid_p = svn_branch_get_eid_by_rrpath(root_branch, rrpath, scratch_pool);
+ *eid_p = svn_branch_get_eid_by_path(root_branch, relpath, scratch_pool);
+}
+
+svn_error_t *
+svn_branch_repos_get_branch_by_id(svn_branch_state_t **branch_p,
+ const svn_branch_repos_t *repos,
+ svn_revnum_t revnum,
+ const char *branch_id,
+ apr_pool_t *scratch_pool)
+{
+ svn_branch_revision_root_t *rev_root;
+
+ if (revnum < 0 || revnum >= repos->rev_roots->nelts)
+ return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+ _("No such revision %ld"), revnum);
+
+ rev_root = svn_branch_repos_get_revision(repos, revnum);
+ *branch_p = svn_branch_revision_root_get_branch_by_id(rev_root, branch_id,
+ scratch_pool);
+ if (! *branch_p)
+ return svn_error_createf(SVN_ERR_BRANCHING, NULL,
+ _("Branch %s not found in r%ld"),
+ branch_id, revnum);
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -1274,17 +1297,11 @@ svn_branch_repos_find_el_rev_by_id(svn_b
apr_pool_t *scratch_pool)
{
svn_branch_el_rev_id_t *el_rev = apr_palloc(result_pool, sizeof(*el_rev));
- const svn_branch_revision_root_t *rev_root;
- if (revnum < 0 || revnum >= repos->rev_roots->nelts)
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), revnum);
-
- rev_root = svn_branch_repos_get_revision(repos, revnum);
el_rev->rev = revnum;
- el_rev->branch
- = svn_branch_revision_root_get_branch_by_id(rev_root, branch_id,
- scratch_pool);
+ SVN_ERR(svn_branch_repos_get_branch_by_id(&el_rev->branch,
+ repos, revnum, branch_id,
+ scratch_pool));
if (svn_branch_get_element(el_rev->branch, eid))
{
el_rev->eid = eid;
@@ -1299,31 +1316,26 @@ svn_branch_repos_find_el_rev_by_id(svn_b
svn_error_t *
svn_branch_repos_find_el_rev_by_path_rev(svn_branch_el_rev_id_t **el_rev_p,
- const char *rrpath,
- int top_branch_num,
- svn_revnum_t revnum,
const svn_branch_repos_t *repos,
+ svn_revnum_t revnum,
+ const char *branch_id,
+ const char *relpath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_branch_el_rev_id_t *el_rev = apr_palloc(result_pool, sizeof(*el_rev));
- svn_branch_state_t *root_branch;
+ svn_branch_state_t *branch;
- if (revnum < 0 || revnum >= repos->rev_roots->nelts)
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), revnum);
-
- root_branch = svn_branch_repos_get_root_branch(repos, revnum,
top_branch_num);
- if (! root_branch)
- return svn_error_createf(SVN_ERR_BRANCHING, NULL,
- _("Top-level branch B%d not found in r%ld"),
- top_branch_num, revnum);
+ SVN_ERR(svn_branch_repos_get_branch_by_id(&branch,
+ repos, revnum, branch_id,
+ scratch_pool));
el_rev->rev = revnum;
- svn_branch_find_nested_branch_element_by_rrpath(&el_rev->branch,
&el_rev->eid,
- root_branch, rrpath,
- scratch_pool);
+ svn_branch_find_nested_branch_element_by_relpath(&el_rev->branch,
+ &el_rev->eid,
+ branch, relpath,
+ scratch_pool);
- /* Any path must at least be within the repository root branch */
+ /* Any relpath must at least be within the originally given branch */
SVN_ERR_ASSERT_NO_RETURN(el_rev->branch);
*el_rev_p = el_rev;
return SVN_NO_ERROR;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c?rev=1696816&r1=1696815&r2=1696816&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c Thu
Aug 20 16:56:11 2015
@@ -1489,7 +1489,7 @@ static svn_error_t *
drive_changes_r(const char *rrpath,
svn_pathrev_t *pred_loc,
apr_hash_t *paths_final,
- int top_branch_num,
+ const char *top_branch_id,
ev3_from_delta_baton_t *eb,
apr_pool_t *scratch_pool)
{
@@ -1540,12 +1540,11 @@ drive_changes_r(const char *rrpath,
{
svn_branch_el_rev_id_t *pred_el_rev;
- SVN_ERR(svn_branch_repos_find_el_rev_by_path_rev(
- &pred_el_rev,
- pred_loc->relpath,
- top_branch_num,
- pred_loc->rev,
+ SVN_ERR(svn_branch_repos_find_el_rev_by_path_rev(&pred_el_rev,
eb->edited_rev_root->repos,
+ pred_loc->rev,
+ top_branch_id,
+ pred_loc->relpath,
scratch_pool, scratch_pool));
succession = (pred_el_rev->eid == final_el_rev->eid);
@@ -1702,7 +1701,7 @@ drive_changes_r(const char *rrpath,
SVN_ERR(drive_changes_r(this_rrpath,
child_pred,
- paths_final, top_branch_num,
+ paths_final, top_branch_id,
eb, scratch_pool));
}
}
@@ -1762,7 +1761,8 @@ drive_changes_branch(ev3_from_delta_bato
}
SVN_ERR(drive_changes_r(top_path, ¤t,
- paths_final, root_branch->outer_eid,
+ paths_final, svn_branch_get_id(root_branch,
+ scratch_pool),
eb, scratch_pool));
}
Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1696816&r1=1696815&r2=1696816&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
(original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Thu Aug
20 16:56:11 2015
@@ -234,7 +234,6 @@ static svn_error_t *
wc_create(svnmover_wc_t **wc_p,
const char *anchor_url,
svn_revnum_t base_revision,
- int top_branch_num,
const char *base_branch_id,
svn_client_ctx_t *ctx,
apr_pool_t *result_pool,
@@ -243,7 +242,6 @@ wc_create(svnmover_wc_t **wc_p,
apr_pool_t *wc_pool = svn_pool_create(result_pool);
svnmover_wc_t *wc = apr_pcalloc(wc_pool, sizeof(*wc));
- wc->top_branch_num = top_branch_num;
wc->pool = wc_pool;
wc->ctx = ctx;
@@ -659,22 +657,27 @@ typedef struct action_t {
/* argument revisions */
svn_opt_revision_t rev_spec[3];
+ const char *branch_id[3];
+
/* argument paths */
const char *relpath[3];
} action_t;
/* ====================================================================== */
-/* Find the deepest branch in the repository of which REVNUM:RRPATH is
- * either the root element or a normal, non-sub-branch element.
+/* Find the deepest branch in the repository of which REVNUM:BRANCH_ID:RELPATH
+ * is either the root element or a normal, non-sub-branch element.
*
- * RRPATH is a repository-relative path. REVNUM is a revision number, or
+ * RELPATH is a repository-relative path. REVNUM is a revision number, or
* SVN_INVALID_REVNUM meaning the current txn.
*
* Return the location of the element in that branch, or with
* EID=-1 if no element exists there.
*
- * Return an error if B<TOP_BRANCH_NUM> does not exist in r<REVNUM>; otherwise,
+ * If BRANCH_ID is null, the default is the WC base branch when REVNUM is
+ * specified, and the WC working branch when REVNUM is SVN_INVALID_REVNUM.
+ *
+ * Return an error if branch BRANCH_ID does not exist in r<REVNUM>; otherwise,
* the result will never be NULL, as every path is within at least the root
* branch.
*/
@@ -682,7 +685,8 @@ static svn_error_t *
find_el_rev_by_rrpath_rev(svn_branch_el_rev_id_t **el_rev_p,
svnmover_wc_t *wc,
svn_revnum_t revnum,
- const char *rrpath,
+ const char *branch_id,
+ const char *relpath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -690,21 +694,30 @@ find_el_rev_by_rrpath_rev(svn_branch_el_
{
const svn_branch_repos_t *repos = wc->working->branch->rev_root->repos;
- SVN_ERR(svn_branch_repos_find_el_rev_by_path_rev(el_rev_p,
- rrpath,
- wc->top_branch_num,
- revnum, repos,
+ if (! branch_id)
+ branch_id = wc->base->branch_id;
+ SVN_ERR(svn_branch_repos_find_el_rev_by_path_rev(el_rev_p, repos,
+ revnum,
+ branch_id,
+ relpath,
result_pool,
scratch_pool));
}
else
{
+ svn_branch_state_t *branch
+ = branch_id ? svn_branch_revision_root_get_branch_by_id(
+ wc->working->branch->rev_root, branch_id, scratch_pool)
+ : wc->working->branch;
svn_branch_el_rev_id_t *el_rev = apr_palloc(result_pool,
sizeof(*el_rev));
- svn_branch_find_nested_branch_element_by_rrpath(
+ if (! branch)
+ return svn_error_createf(SVN_ERR_BRANCHING, NULL,
+ _("Branch %s not found in working state"),
+ branch_id);
+ svn_branch_find_nested_branch_element_by_relpath(
&el_rev->branch, &el_rev->eid,
- wc->working->branch,
- rrpath, scratch_pool);
+ branch, relpath, scratch_pool);
el_rev->rev = SVN_INVALID_REVNUM;
*el_rev_p = el_rev;
}
@@ -2654,10 +2667,14 @@ execute(svnmover_wc_t *wc,
arg[j]->path_name = svn_relpath_basename(rrpath, NULL);
SVN_ERR(find_el_rev_by_rrpath_rev(&arg[j]->el_rev, wc,
- arg[j]->revnum, rrpath,
+ arg[j]->revnum,
+ action->branch_id[j],
+ rrpath,
iterpool, iterpool));
SVN_ERR(find_el_rev_by_rrpath_rev(&arg[j]->parent_el_rev, wc,
- arg[j]->revnum, parent_rrpath,
+ arg[j]->revnum,
+ action->branch_id[j],
+ parent_rrpath,
iterpool, iterpool));
}
}
@@ -2778,7 +2795,6 @@ execute(svnmover_wc_t *wc,
notify_v("A+ %s",
branch_str(new_branch, iterpool));
/* Switch the WC working state to this new branch */
- wc->top_branch_num = new_branch->outer_eid;
wc->working->branch_id = svn_branch_get_id(new_branch, wc->pool);
wc->working->branch = new_branch;
}
@@ -3322,6 +3338,16 @@ parse_actions(apr_array_header_t **actio
"Argument '%s' is a URL; use "
"--root-url (-U) instead", path);
}
+ /* Parse "^B<branch-id>/path" syntax. */
+ if (strncmp("^B", path, 2) == 0)
+ {
+ const char *slash = strchr(path, '/');
+
+ action->branch_id[k]
+ = slash ? apr_pstrndup(pool, path + 1, slash - (path + 1))
+ : path + 1;
+ path = slash ? slash + 1 : "";
+ }
/* These args must be relpaths, except for the 'local file' arg
of a 'put' command. */
if (! svn_relpath_is_canonical(path)
@@ -3731,7 +3757,7 @@ sub_main(int *exit_code, int argc, const
SVN_ERR(wc_create(&wc,
anchor_url, base_revision,
- atoi(branch_id + 1) /*top_branch_num*/, branch_id,
+ branch_id,
ctx, pool, pool));
do
Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h?rev=1696816&r1=1696815&r2=1696816&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h
(original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h Thu Aug
20 16:56:11 2015
@@ -54,7 +54,6 @@ typedef struct svnmover_wc_t
svn_ra_session_t *ra_session;
svn_editor3_t *editor;
- int top_branch_num;
/* Base and working versions. */
svnmover_wc_version_t *base, *working;