You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/10/14 08:38:16 UTC

svn commit: r1708550 [1/2] - in /subversion/branches/move-tracking-2/subversion: include/private/ libsvn_delta/ svnmover/ tests/cmdline/ tests/cmdline/svntest/

Author: julianfoad
Date: Wed Oct 14 06:38:16 2015
New Revision: 1708550

URL: http://svn.apache.org/viewvc?rev=1708550&view=rev
Log:
On the 'move-tracking-2' branch: Disentangle the concept of nested branches
from the basic concept of branches.

* subversion/include/private/svn_branch.h,
  subversion/libsvn_delta/branch.c
  (svn_branch_state_t,
   svn_branch_state_create,
   svn_branch_add_new_branch): Add a branch-id field, and delete the outer-
    branch and outer-eid fields.
  (svn_branch_get_element): Remove an assertion which need not be true, and
    which with the new code is not always true.
  Move some functions to svn_branch_nested.h and branch_nested.c.

* subversion/include/private/svn_branch_repos.h,
  subversion/libsvn_delta/branch_repos.c
  Move some functions to svn_branch_nested.h and branch_nested.c.

* subversion/include/private/svn_branch_nested.h,
  subversion/libsvn_delta/branch_nested.c
  New files.

* subversion/libsvn_delta/compat3e.c
  (branch_get_top_num): Delete.
  (branch_get_storage_root_rrpath,
   editor3_open_branch,
   editor3_branch,
   drive_changes,
   editor3_sequence_point): Adjust accordingly.

* subversion/svnmover/svnmover.c
  (branch_id_str,
   do_branch_into,
   point_to_outer_element_instead,
   execute): Adjust accordingly.

* subversion/tests/cmdline/svnmover_tests.py
  (merge_swap_abc,
   move_to_related_branch_2): Adjust expected outputs of the '--ui=serial'
    listing to account for branch root paths no longer being included in the
    serialization format.

* subversion/tests/cmdline/svntest/wc.py
  (_re_parse_eid_branch,
   State.from_eids): Adjust to account for branch root paths no longer being
    included in the serialization format.

Added:
    subversion/branches/move-tracking-2/subversion/include/private/svn_branch_nested.h
      - copied, changed from r1708080, subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_nested.c
      - copied, changed from r1708080, subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
Modified:
    subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
    subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.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/tests/cmdline/svnmover_tests.py
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py

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=1708550&r1=1708549&r2=1708550&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 Wed Oct 14 06:38:16 2015
@@ -161,14 +161,6 @@ svn_branch_revision_root_create(svn_bran
                                 svn_revnum_t base_rev,
                                 apr_pool_t *result_pool);
 
-/* Return the top-level branch numbered TOP_BRANCH_NUM in REV_ROOT.
- *
- * Return null if there is no such branch.
- */
-svn_branch_state_t *
-svn_branch_revision_root_get_root_branch(svn_branch_revision_root_t *rev_root,
-                                         int top_branch_num);
-
 /* Return all the branches in REV_ROOT.
  *
  * Return an empty array if there are none.
@@ -235,7 +227,8 @@ svn_branch_txn_finalize_eids(svn_branch_
  */
 struct svn_branch_state_t
 {
-  /* --- Identity of this object --- */
+  /* The branch identifier (starting with 'B') */
+  const char *bid;
 
   /* The previous location in the lifeline of this branch. */
   /* (REV = -1 means "in this txn") */
@@ -247,16 +240,6 @@ struct svn_branch_state_t
   /* The revision to which this branch state belongs */
   svn_branch_revision_root_t *rev_root;
 
-  /* The outer branch state that contains the subbranch
-     root element of this branch. Null if this is a root branch. */
-  struct svn_branch_state_t *outer_branch;
-
-  /* The subbranch-root element in OUTER_BRANCH of the root of this branch.
-   * The top branch id if this is a root branch. */
-  int outer_eid;
-
-  /* --- Contents of this object --- */
-
   /* EID -> svn_branch_el_rev_content_t mapping. */
   /* ### TODO: This should use an svn_branch_subtree_t instead of E_MAP and
    *     ROOT_EID. And the immediate subbranches would be directly in there,
@@ -270,11 +253,10 @@ struct svn_branch_state_t
  * element).
  */
 svn_branch_state_t *
-svn_branch_state_create(svn_branch_rev_bid_t *predecessor,
+svn_branch_state_create(const char *bid,
+                        svn_branch_rev_bid_t *predecessor,
                         int root_eid,
                         svn_branch_revision_root_t *rev_root,
-                        svn_branch_state_t *outer_branch,
-                        int outer_eid,
                         apr_pool_t *result_pool);
 
 /* Get the full id of branch BRANCH.
@@ -335,36 +317,18 @@ svn_branch_id_unnest(const char **outer_
  * Set the root element to ROOT_EID.
  */
 svn_branch_state_t *
-svn_branch_add_new_branch(svn_branch_revision_root_t *rev_root,
+svn_branch_add_new_branch(const char *bid,
+                          svn_branch_revision_root_t *rev_root,
                           svn_branch_rev_bid_t *predecessor,
-                          svn_branch_state_t *outer_branch,
-                          int outer_eid,
                           int root_eid,
                           apr_pool_t *scratch_pool);
 
-/* Delete the branch BRANCH, and any subbranches recursively.
- *
- * Do not require that a subbranch root element exists in its outer branch,
- * nor delete it if it does exist.
+/* Remove branch BRANCH from the list of branches in REV_ROOT.
  */
 void
-svn_branch_delete_branch_r(svn_branch_state_t *branch,
-                           apr_pool_t *scratch_pool);
-
-/* Return an array of pointers to the branches that are immediate
- * sub-branches of BRANCH.
- */
-apr_array_header_t *
-svn_branch_get_immediate_subbranches(const svn_branch_state_t *branch,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool);
-
-/* Return the subbranch rooted at BRANCH:EID, or NULL if that is
- * not a subbranch root.
- */
-svn_branch_state_t *
-svn_branch_get_subbranch_at_eid(svn_branch_state_t *branch,
-                                int eid,
+svn_branch_revision_root_delete_branch(
+                                svn_branch_revision_root_t *rev_root,
+                                svn_branch_state_t *branch,
                                 apr_pool_t *scratch_pool);
 
 /* element */
@@ -531,16 +495,15 @@ svn_branch_subtree_get_subbranch_at_eid(
                                         apr_pool_t *result_pool);
 
 /* Return the subtree of BRANCH rooted at EID.
- * Recursive: includes subbranches.
  *
  * The result is limited by the lifetime of BRANCH. It includes a shallow
- * copy of the element maps in BRANCH and its subbranches: the hash tables
- * are duplicated but the keys and values (element content data) are not.
+ * copy of the element maps in BRANCH: the hash table is
+ * duplicated but the keys and values (element content data) are not.
  * It assumes that modifications on a svn_branch_state_t treat element
  * map keys and values as immutable -- which they do.
  */
 svn_branch_subtree_t *
-svn_branch_get_subtree(const svn_branch_state_t *branch,
+svn_branch_get_subtree_n(svn_branch_state_t *branch,
                        int eid,
                        apr_pool_t *result_pool);
 
@@ -585,19 +548,16 @@ svn_branch_update_element(svn_branch_sta
                           const char *new_name,
                           const svn_element_payload_t *new_payload);
 
-/* Purge orphaned elements and subbranches.
+/* Purge orphaned elements in BRANCH.
  */
 void
-svn_branch_purge_r(svn_branch_state_t *branch,
-                   apr_pool_t *scratch_pool);
+svn_branch_purge(svn_branch_state_t *branch,
+                 apr_pool_t *scratch_pool);
 
 /* Instantiate elements in a branch.
  *
  * In TO_BRANCH, instantiate (or alter, if existing) each element of
  * ELEMENTS, each with its given tree structure (parent, name) and payload.
- *
- * Also branch the subbranches in ELEMENTS, creating corresponding new
- * subbranches in TO_BRANCH, recursively.
  */
 svn_error_t *
 svn_branch_instantiate_elements(svn_branch_state_t *to_branch,
@@ -623,14 +583,6 @@ svn_branch_map_add_subtree(svn_branch_st
                            svn_branch_subtree_t new_subtree,
                            apr_pool_t *scratch_pool);
 
-/* Return the root repos-relpath of BRANCH.
- *
- * ### TODO: Clarify sequencing requirements.
- */
-const char *
-svn_branch_get_root_rrpath(const svn_branch_state_t *branch,
-                           apr_pool_t *result_pool);
-
 /* Return the subtree-relative path of element EID in SUBTREE.
  *
  * If the element EID does not currently exist in SUBTREE, return NULL.
@@ -652,17 +604,6 @@ svn_branch_get_path_by_eid(const svn_bra
                            int eid,
                            apr_pool_t *result_pool);
 
-/* Return the repos-relpath of element EID in BRANCH.
- *
- * If the element EID does not currently exist in BRANCH, return NULL.
- *
- * ### TODO: Clarify sequencing requirements.
- */
-const char *
-svn_branch_get_rrpath_by_eid(const svn_branch_state_t *branch,
-                             int eid,
-                             apr_pool_t *result_pool);
-
 /* Return the EID for the branch-relative path PATH in BRANCH.
  *
  * If no element of BRANCH is at this path, return -1.
@@ -674,40 +615,6 @@ svn_branch_get_eid_by_path(const svn_bra
                            const char *path,
                            apr_pool_t *scratch_pool);
 
-/* Return the EID for the repos-relpath RRPATH in BRANCH.
- *
- * If no element of BRANCH is at this path, return -1.
- *
- * ### TODO: Clarify sequencing requirements.
- */
-int
-svn_branch_get_eid_by_rrpath(svn_branch_state_t *branch,
-                             const char *rrpath,
-                             apr_pool_t *scratch_pool);
-
-/* 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
- * RELPATH.
- *
- * Set *BRANCH_P to the deepest branch within ROOT_BRANCH (recursively,
- * including itself) that contains the path RELPATH.
- *
- * 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 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_relpath(
-                                svn_branch_state_t **branch_p,
-                                int *eid_p,
-                                svn_branch_state_t *root_branch,
-                                const char *relpath,
-                                apr_pool_t *scratch_pool);
-
 /* Get the default branching metadata for r0 of a new repository.
  */
 svn_string_t *

Copied: subversion/branches/move-tracking-2/subversion/include/private/svn_branch_nested.h (from r1708080, 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_nested.h?p2=subversion/branches/move-tracking-2/subversion/include/private/svn_branch_nested.h&p1=subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h&r1=1708080&r2=1708550&rev=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_branch_nested.h Wed Oct 14 06:38:16 2015
@@ -20,609 +20,33 @@
  * ====================================================================
  * @endcopyright
  *
- * @file svn_branch.h
- * @brief Operating on a branched version history
+ * @file svn_branch_nested.h
+ * @brief Nested branches and subbranch-root elements
  *
  * @since New in 1.10.
  */
 
-/* Transactions
- *
- * A 'txn' contains a set of changes to the branches/elements.
- *
- * To make changes you say, for example, "for element 5: I want the parent
- * element to be 3 now, and its name to be 'bar', and its content to be
- * {props=... text=...}". That sets up a move and/or rename and/or
- * content-change (or possibly a no-op for all three aspects) for element 5.
- *
- * Before or after (or at the same time, if we make a parallelizable
- * implementation) we can make edits to the other elements, including
- * element 3.
- *
- * So at the time of the edit method 'change e5: let its parent be e3'
- * we might or might not have even created e3, if that happens to be an
- * element that we wish to create rather than one that already existed.
- *
- * We allow this non-ordering because we want the changes to different
- * elements to be totally independent.
- *
- * So at any given 'moment' in time during specifying the changes to a
- * txn, the txn state is not necessarily one that maps directly to a
- * flat tree (single-rooted, no cycles, no clashes of paths, etc.).
- *
- * Once we've finished specifying the edits, then the txn state will be
- * converted to a flat tree, and that's the final result. But we can't
- * query an arbitrary txn (potentially in the middle of making changes
- * to it) by path, because the paths are not fully defined yet.
- *
- * So there are three kinds of operations:
- *
- * - query involving paths
- *   => requires a flat tree state to query, not an in-progress txn
- *
- * - query, not involving paths
- *   => accepts a txn-in-progress or a flat tree
- *
- * - modify (not involving paths)
- *   => requires a txn
- *
- * Currently, a txn is represented by 'svn_branch_revision_root_t', with
- * 'svn_branch_state_t' for the individual branches in it. A flat tree is
- * represented by 'svn_branch_subtree_t'. But there is currently not a
- * clean separation; there is some overlap and some warts such as the
- * 'svn_editor3_sequence_point' method.
- */
-
-
-#ifndef SVN_BRANCH_H
-#define SVN_BRANCH_H
+#ifndef SVN_BRANCH_NESTED_H
+#define SVN_BRANCH_NESTED_H
 
 #include <apr_pools.h>
 
 #include "svn_types.h"
-#include "svn_error.h"
-#include "svn_io.h"    /* for svn_stream_t  */
-#include "svn_delta.h"
 
-#include "private/svn_element.h"
+#include "private/svn_branch.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
 
-/* ### */
-#define SVN_ERR_BRANCHING 123456
-
-/** Element Identifier (EID).
- *
- * An element may appear in any or all branches, and its EID is the same in
- * each branch in which the element appears.
- * 
- * By definition, an element keeps the same EID for its whole lifetime, even
- * if deleted from all branches and later 'resurrected'.
- *
- * In principle, an EID is an arbitrary token and has no intrinsic
- * relationships (except equality) to other EIDs. The current implementation
- * uses integers and allocates them sequentially from a central counter, but
- * the implementation may be changed.
- *
- * ### In most places the code currently says 'int', verbatim.
- */
-typedef int svn_branch_eid_t;
-
-typedef struct svn_branch_el_rev_id_t svn_branch_el_rev_id_t;
-
-typedef struct svn_branch_rev_bid_eid_t svn_branch_rev_bid_eid_t;
-
-typedef struct svn_branch_rev_bid_t svn_branch_rev_bid_t;
-
-typedef struct svn_branch_state_t svn_branch_state_t;
-
-/* Per-repository branching info.
- */
-typedef struct svn_branch_repos_t svn_branch_repos_t;
-
-/* A container for all the branching metadata for a specific revision (or
- * an uncommitted transaction).
- */
-typedef struct svn_branch_revision_root_t
-{
-  /* The repository in which this revision exists. */
-  svn_branch_repos_t *repos;
-
-  /* If committed, the revision number; else SVN_INVALID_REVNUM. */
-  svn_revnum_t rev;
-
-  /* If committed, the previous revision number, else the revision number
-     on which this transaction is based. */
-  svn_revnum_t base_rev;
-
-  /* The range of element ids assigned. */
-  /* EIDs local to the txn are negative, assigned by decrementing FIRST_EID
-   * (skipping -1). */
-  int first_eid, next_eid;
-
-  /* The root branches, indexed by top-level branch id (0...N). */
-  apr_array_header_t *root_branches;
-
-  /* All branches, including root branches. */
-  apr_array_header_t *branches;
-
-} svn_branch_revision_root_t;
-
-/* Create a new branching revision-info object.
- *
- * It will have no branch-roots.
- */
-svn_branch_revision_root_t *
-svn_branch_revision_root_create(svn_branch_repos_t *repos,
-                                svn_revnum_t rev,
-                                svn_revnum_t base_rev,
-                                apr_pool_t *result_pool);
-
-/* Return the top-level branch numbered TOP_BRANCH_NUM in REV_ROOT.
- *
- * Return null if there is no such branch.
- */
-svn_branch_state_t *
-svn_branch_revision_root_get_root_branch(svn_branch_revision_root_t *rev_root,
-                                         int top_branch_num);
-
-/* Return all the branches in REV_ROOT.
- *
- * Return an empty array if there are none.
- */
-const apr_array_header_t *
-svn_branch_revision_root_get_branches(svn_branch_revision_root_t *rev_root,
-                                      apr_pool_t *result_pool);
-
-/* Return the branch whose id is BRANCH_ID in REV_ROOT.
- *
- * Return NULL if not found.
- *
- * Note: a branch id is, in behavioural terms, an arbitrary token. In the
- * current implementation it is constructed from the hierarchy of subbranch
- * root EIDs leading to the branch, but that may be changed in future.
- *
- * See also: svn_branch_get_id().
- */
-svn_branch_state_t *
-svn_branch_revision_root_get_branch_by_id(const svn_branch_revision_root_t *rev_root,
-                                          const char *branch_id,
-                                          apr_pool_t *scratch_pool);
-
-/* Assign a new txn-scope element id in REV_ROOT.
- */
-int
-svn_branch_txn_new_eid(svn_branch_revision_root_t *rev_root);
-
-/* Change txn-local EIDs (negative integers) in TXN to revision EIDs, by
- * assigning a new revision-EID (positive integer) for each one.
- *
- * Rewrite TXN->first_eid and TXN->next_eid accordingly.
- */
-svn_error_t *
-svn_branch_txn_finalize_eids(svn_branch_revision_root_t *txn,
-                             apr_pool_t *scratch_pool);
-
-/* Often, branches have the same root element. For example,
- * branching /trunk to /branches/br1 results in:
- *
- *      branch 1: (root-EID=100)
- *          EID 100 => /trunk
- *          ...
- *      branch 2: (root-EID=100)
- *          EID 100 => /branches/br1
- *          ...
- *
- * However, the root element of one branch may correspond to a non-root
- * element of another branch.
- *
- * Continuing the same example, branching from the trunk subtree
- * /trunk/D (which is not itself a branch root) results in:
- *
- *      branch 3: (root-EID=104)
- *          EID 100 => (nil)
- *          ...
- *          EID 104 => /branches/branch-of-trunk-subtree-D
- *          ...
- */
-
-/* A branch state.
- *
- * A branch state object describes one version of one branch.
- */
-struct svn_branch_state_t
-{
-  /* --- Identity of this object --- */
-
-  /* The previous location in the lifeline of this branch. */
-  /* (REV = -1 means "in this txn") */
-  svn_branch_rev_bid_t *predecessor;
-
-  /* The EID of its pathwise root element. */
-  int root_eid;
-
-  /* The revision to which this branch state belongs */
-  svn_branch_revision_root_t *rev_root;
-
-  /* The outer branch state that contains the subbranch
-     root element of this branch. Null if this is a root branch. */
-  struct svn_branch_state_t *outer_branch;
-
-  /* The subbranch-root element in OUTER_BRANCH of the root of this branch.
-   * The top branch id if this is a root branch. */
-  int outer_eid;
-
-  /* --- Contents of this object --- */
-
-  /* EID -> svn_branch_el_rev_content_t mapping. */
-  /* ### TODO: This should use an svn_branch_subtree_t instead of E_MAP and
-   *     ROOT_EID. And the immediate subbranches would be directly in there,
-   *     instead of (or as well as) being in a single big list in REV_ROOT.
-   *     And a whole bunch of methods would be common to both. */
-  apr_hash_t *e_map;
-
-};
-
-/* Create a new branch state object, with no elements (not even a root
- * element).
- */
-svn_branch_state_t *
-svn_branch_state_create(svn_branch_rev_bid_t *predecessor,
-                        int root_eid,
-                        svn_branch_revision_root_t *rev_root,
-                        svn_branch_state_t *outer_branch,
-                        int outer_eid,
-                        apr_pool_t *result_pool);
-
-/* Get the full id of branch BRANCH.
- *
- * Branch id format:
- *      B<top-level-branch-num>[.<1st-level-eid>[.<2nd-level-eid>[...]]]
- *
- * Note: a branch id is, in behavioural terms, an arbitrary token. In the
- * current implementation it is constructed from the hierarchy of subbranch
- * root EIDs leading to the branch, but that may be changed in future.
- *
- * See also: svn_branch_revision_root_get_branch_by_id().
- */
-const char *
-svn_branch_get_id(svn_branch_state_t *branch,
-                  apr_pool_t *result_pool);
-
-/* Return the id of the branch nested in OUTER_BID at element OUTER_EID.
- *
- * For a top-level branch, OUTER_BID is null and OUTER_EID is the
- * top-level branch number.
- *
- * (Such branches need not exist. This works purely with ids, making use
- * of the fact that nested branch ids are predictable based on the nesting
- * element id.)
- */
-const char *
-svn_branch_id_nest(const char *outer_bid,
-                   int outer_eid,
-                   apr_pool_t *result_pool);
-
-/* Given a nested branch id BID, set *OUTER_BID to the outer branch's id
- * and *OUTER_EID to the nesting element in the outer branch.
- *
- * For a top-level branch, set *OUTER_BID to NULL and *OUTER_EID to the
- * top-level branch number.
- *
- * (Such branches need not exist. This works purely with ids, making use
- * of the fact that nested branch ids are predictable based on the nesting
- * element id.)
- */
-void
-svn_branch_id_unnest(const char **outer_bid,
-                     int *outer_eid,
-                     const char *bid,
-                     apr_pool_t *result_pool);
-
-/* Create a new branch at OUTER_BRANCH:OUTER_EID, with no elements
- * (not even a root element).
- *
- * Create and return a new branch object. Register its existence in REV_ROOT.
- *
- * If OUTER_BRANCH is NULL, create a top-level branch with a new top-level
- * branch number, ignoring OUTER_EID. Otherise, create a branch that claims
- * to be nested under OUTER_BRANCH:OUTER_EID, but do not require that
- * a subbranch root element exists there, nor create one.
- *
- * Set the root element to ROOT_EID.
- */
-svn_branch_state_t *
-svn_branch_add_new_branch(svn_branch_revision_root_t *rev_root,
-                          svn_branch_rev_bid_t *predecessor,
-                          svn_branch_state_t *outer_branch,
-                          int outer_eid,
-                          int root_eid,
-                          apr_pool_t *scratch_pool);
-
-/* Delete the branch BRANCH, and any subbranches recursively.
- *
- * Do not require that a subbranch root element exists in its outer branch,
- * nor delete it if it does exist.
- */
-void
-svn_branch_delete_branch_r(svn_branch_state_t *branch,
-                           apr_pool_t *scratch_pool);
-
-/* Return an array of pointers to the branches that are immediate
- * sub-branches of BRANCH.
- */
-apr_array_header_t *
-svn_branch_get_immediate_subbranches(const svn_branch_state_t *branch,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool);
-
-/* Return the subbranch rooted at BRANCH:EID, or NULL if that is
- * not a subbranch root.
- */
-svn_branch_state_t *
-svn_branch_get_subbranch_at_eid(svn_branch_state_t *branch,
-                                int eid,
-                                apr_pool_t *scratch_pool);
-
-/* element */
 /*
-typedef struct svn_branch_element_t
-{
-  int eid;
-  svn_node_kind_t node_kind;
-} svn_branch_element_t;
-*/
-
-/* Branch-Element-Revision */
-struct svn_branch_el_rev_id_t
-{
-  /* The branch state that applies to REV. */
-  svn_branch_state_t *branch;
-  /* Element. */
-  int eid;
-  /* Revision. SVN_INVALID_REVNUM means 'in this transaction', not 'head'.
-     ### Do we need this if BRANCH refers to a particular branch-revision? */
-  svn_revnum_t rev;
-
-};
-
-/* Revision-branch-element id. */
-struct svn_branch_rev_bid_eid_t
-{
-  /* Revision. SVN_INVALID_REVNUM means 'in this transaction', not 'head'. */
-  svn_revnum_t rev;
-  /* The branch id in revision REV. */
-  const char *bid;
-  /* Element id. */
-  int eid;
-
-};
-
-/* Revision-branch id. */
-struct svn_branch_rev_bid_t
-{
-  /* Revision. SVN_INVALID_REVNUM means 'in this transaction', not 'head'. */
-  svn_revnum_t rev;
-  /* The branch id in revision REV. */
-  const char *bid;
-
-};
-
-/* Return a new el_rev_id object constructed with *shallow* copies of BRANCH,
- * EID and REV, allocated in RESULT_POOL.
- */
-svn_branch_el_rev_id_t *
-svn_branch_el_rev_id_create(svn_branch_state_t *branch,
-                            int eid,
-                            svn_revnum_t rev,
-                            apr_pool_t *result_pool);
-
-/* Return a new id object constructed with deep copies of REV, BRANCH_ID
- * and EID, allocated in RESULT_POOL.
- */
-svn_branch_rev_bid_eid_t *
-svn_branch_rev_bid_eid_create(svn_revnum_t rev,
-                              const char *branch_id,
-                              int eid,
-                              apr_pool_t *result_pool);
-svn_branch_rev_bid_t *
-svn_branch_rev_bid_create(svn_revnum_t rev,
-                          const char *branch_id,
-                          apr_pool_t *result_pool);
-
-/* Return a new id object constructed with a deep copy of OLD_ID,
- * allocated in RESULT_POOL. */
-svn_branch_rev_bid_eid_t *
-svn_branch_rev_bid_eid_dup(const svn_branch_rev_bid_eid_t *old_id,
-                           apr_pool_t *result_pool);
-svn_branch_rev_bid_t *
-svn_branch_rev_bid_dup(const svn_branch_rev_bid_t *old_id,
-                       apr_pool_t *result_pool);
-
-/* The content (parent, name and payload) of an element-revision.
- * In other words, an el-rev node in a (mixed-rev) directory-tree.
- */
-typedef struct svn_branch_el_rev_content_t
-{
-  /* eid of the parent element, or -1 if this is the root element */
-  int parent_eid;
-  /* struct svn_branch_element_t *parent_element; */
-  /* element name, or "" for root element; never null */
-  const char *name;
-  /* payload (kind, props, text, ...);
-   * null if this is a subbranch root element */
-  svn_element_payload_t *payload;
-
-} svn_branch_el_rev_content_t;
-
-/* Return a new content object constructed with deep copies of PARENT_EID,
- * NAME and PAYLOAD, allocated in RESULT_POOL.
- */
-svn_branch_el_rev_content_t *
-svn_branch_el_rev_content_create(svn_branch_eid_t parent_eid,
-                                 const char *name,
-                                 const svn_element_payload_t *payload,
-                                 apr_pool_t *result_pool);
-
-/* Return a deep copy of OLD, allocated in RESULT_POOL.
- */
-svn_branch_el_rev_content_t *
-svn_branch_el_rev_content_dup(const svn_branch_el_rev_content_t *old,
-                              apr_pool_t *result_pool);
-
-/* Return TRUE iff CONTENT_LEFT is the same as CONTENT_RIGHT. */
-svn_boolean_t
-svn_branch_el_rev_content_equal(const svn_branch_el_rev_content_t *content_left,
-                                const svn_branch_el_rev_content_t *content_right,
-                                apr_pool_t *scratch_pool);
-
-
-/* Describe a subtree of elements.
- *
- * A subtree is described by the content of element ROOT_EID in E_MAP,
- * and its children (as determined by their parent links) and their names
- * and their content recursively. For the element ROOT_EID itself, only
- * its content is relevant; its parent and name are to be ignored.
- *
- * E_MAP may also contain entries that are not part of the subtree. Thus,
- * to select a sub-subtree, it is only necessary to change ROOT_EID.
- *
- * The EIDs used in here may be considered either as global EIDs (known to
- * the repo), or as local stand-alone EIDs (in their own local name-space),
- * according to the context.
- *
- * ### TODO: This should be used in the implementation of svn_branch_state_t.
- *     A whole bunch of methods would be common to both.
- */
-typedef struct svn_branch_subtree_t
-{
-  svn_branch_rev_bid_t *predecessor;
-
-  /* EID -> svn_branch_el_rev_content_t mapping. */
-  apr_hash_t *e_map;
-
-  /* Subtree root EID. (ROOT_EID must be an existing key in E_MAP.) */
-  int root_eid;
-
-  /* Subbranches to be included: each subbranch-root element in E_MAP
-     should be mapped here.
-
-     A mapping of (int)EID -> (svn_branch_subtree_t *). */
-  apr_hash_t *subbranches;
-} svn_branch_subtree_t;
-
-/* Create an empty subtree (no elements populated, not even ROOT_EID).
- *
- * The result contains a *shallow* copy of E_MAP, or a new empty mapping
- * if E_MAP is null.
- */
-svn_branch_subtree_t *
-svn_branch_subtree_create(apr_hash_t *e_map,
-                          int root_eid,
-                          apr_pool_t *result_pool);
-
-/* Return the subbranch rooted at SUBTREE:EID, or NULL if that is
- * not a subbranch root. */
-svn_branch_subtree_t *
-svn_branch_subtree_get_subbranch_at_eid(svn_branch_subtree_t *subtree,
-                                        int eid,
-                                        apr_pool_t *result_pool);
-
-/* Return the subtree of BRANCH rooted at EID.
- * Recursive: includes subbranches.
- *
- * The result is limited by the lifetime of BRANCH. It includes a shallow
- * copy of the element maps in BRANCH and its subbranches: the hash tables
- * are duplicated but the keys and values (element content data) are not.
- * It assumes that modifications on a svn_branch_state_t treat element
- * map keys and values as immutable -- which they do.
- */
-svn_branch_subtree_t *
-svn_branch_get_subtree(const svn_branch_state_t *branch,
-                       int eid,
-                       apr_pool_t *result_pool);
-
-/* Declare that the following function requires/implies that in BRANCH's
- * mapping, for each existing element, the parent also exists.
- *
- * ### Find a better word? flattened, canonical, finalized, ...
- */
-#define SVN_BRANCH_SEQUENCE_POINT(branch)
-
-/* Return the mapping of elements in branch BRANCH.
- *
- * The mapping is from pointer-to-eid to
- * pointer-to-svn_branch_el_rev_content_t.
- */
-apr_hash_t *
-svn_branch_get_elements(svn_branch_state_t *branch);
-
-/* In BRANCH, get element EID (parent, name, payload).
- *
- * If element EID is not present, return null. Otherwise, the returned
- * element's payload may be null meaning it is a subbranch-root.
- */
-svn_branch_el_rev_content_t *
-svn_branch_get_element(const svn_branch_state_t *branch,
-                       int eid);
-
-/* In BRANCH, delete element EID.
  */
 void
-svn_branch_delete_element(svn_branch_state_t *branch,
-                          int eid);
-
-/* Set or change the EID:element mapping for EID in BRANCH.
- *
- * Duplicate NEW_NAME and NEW_PAYLOAD into the branch mapping's pool.
- */
-void
-svn_branch_update_element(svn_branch_state_t *branch,
-                          int eid,
-                          svn_branch_eid_t new_parent_eid,
-                          const char *new_name,
-                          const svn_element_payload_t *new_payload);
-
-/* Purge orphaned elements and subbranches.
- */
-void
-svn_branch_purge_r(svn_branch_state_t *branch,
-                   apr_pool_t *scratch_pool);
-
-/* Instantiate elements in a branch.
- *
- * In TO_BRANCH, instantiate (or alter, if existing) each element of
- * ELEMENTS, each with its given tree structure (parent, name) and payload.
- *
- * Also branch the subbranches in ELEMENTS, creating corresponding new
- * subbranches in TO_BRANCH, recursively.
- */
-svn_error_t *
-svn_branch_instantiate_elements(svn_branch_state_t *to_branch,
-                                svn_branch_subtree_t elements,
-                                apr_pool_t *scratch_pool);
-
-/* Create a copy of NEW_SUBTREE in TO_BRANCH.
- *
- * For each non-root element in NEW_SUBTREE, create a new element with
- * a new EID, no matter what EID is used to represent it in NEW_SUBTREE.
- *
- * For the new subtree root element, if TO_EID is -1, generate a new EID,
- * otherwise alter (if it exists) or instantiate the element TO_EID.
- *
- * Set the new subtree root element's parent to NEW_PARENT_EID and name to
- * NEW_NAME.
- */
-svn_error_t *
-svn_branch_map_add_subtree(svn_branch_state_t *to_branch,
-                           int to_eid,
-                           svn_branch_eid_t new_parent_eid,
-                           const char *new_name,
-                           svn_branch_subtree_t new_subtree,
-                           apr_pool_t *scratch_pool);
+svn_branch_get_outer_branch_and_eid(svn_branch_state_t **outer_branch_p,
+                                    int *outer_eid_p,
+                                    const svn_branch_state_t *branch,
+                                    apr_pool_t *scratch_pool);
 
 /* Return the root repos-relpath of BRANCH.
  *
@@ -632,27 +56,6 @@ const char *
 svn_branch_get_root_rrpath(const svn_branch_state_t *branch,
                            apr_pool_t *result_pool);
 
-/* Return the subtree-relative path of element EID in SUBTREE.
- *
- * If the element EID does not currently exist in SUBTREE, return NULL.
- *
- * ### TODO: Clarify sequencing requirements.
- */
-const char *
-svn_branch_subtree_get_path_by_eid(const svn_branch_subtree_t *subtree,
-                                   int eid,
-                                   apr_pool_t *result_pool);
-/* Return the branch-relative path of element EID in BRANCH.
- *
- * If the element EID does not currently exist in BRANCH, return NULL.
- *
- * ### TODO: Clarify sequencing requirements.
- */
-const char *
-svn_branch_get_path_by_eid(const svn_branch_state_t *branch,
-                           int eid,
-                           apr_pool_t *result_pool);
-
 /* Return the repos-relpath of element EID in BRANCH.
  *
  * If the element EID does not currently exist in BRANCH, return NULL.
@@ -664,17 +67,6 @@ svn_branch_get_rrpath_by_eid(const svn_b
                              int eid,
                              apr_pool_t *result_pool);
 
-/* Return the EID for the branch-relative path PATH in BRANCH.
- *
- * If no element of BRANCH is at this path, return -1.
- *
- * ### TODO: Clarify sequencing requirements.
- */
-int
-svn_branch_get_eid_by_path(const svn_branch_state_t *branch,
-                           const char *path,
-                           apr_pool_t *scratch_pool);
-
 /* Return the EID for the repos-relpath RRPATH in BRANCH.
  *
  * If no element of BRANCH is at this path, return -1.
@@ -709,38 +101,73 @@ svn_branch_find_nested_branch_element_by
                                 const char *relpath,
                                 apr_pool_t *scratch_pool);
 
-/* Get the default branching metadata for r0 of a new repository.
+/* 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
+ * field is -1.
+ *
+ * Allocate *EL_REV_P (but not the branch object that it refers to) in
+ * RESULT_POOL.
+ *
+ * ### TODO: Clarify sequencing requirements.
  */
-svn_string_t *
-svn_branch_get_default_r0_metadata(apr_pool_t *result_pool);
+svn_error_t *
+svn_branch_repos_find_el_rev_by_path_rev(svn_branch_el_rev_id_t **el_rev_p,
+                                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);
 
-/* Create a new revision-root object *REV_ROOT_P, initialized with info
- * parsed from STREAM, allocated in RESULT_POOL.
+/* Return an array of pointers to the branches that are immediate
+ * sub-branches of BRANCH.
  */
-svn_error_t *
-svn_branch_revision_root_parse(svn_branch_revision_root_t **rev_root_p,
-                               svn_branch_repos_t *repos,
-                               svn_stream_t *stream,
-                               apr_pool_t *result_pool,
-                               apr_pool_t *scratch_pool);
+apr_array_header_t *
+svn_branch_get_immediate_subbranches(svn_branch_state_t *branch,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool);
 
-/* Write to STREAM a parseable representation of REV_ROOT.
+/* Return the subbranch rooted at BRANCH:EID, or NULL if that is
+ * not a subbranch root.
  */
-svn_error_t *
-svn_branch_revision_root_serialize(svn_stream_t *stream,
-                                   svn_branch_revision_root_t *rev_root,
-                                   apr_pool_t *scratch_pool);
+svn_branch_state_t *
+svn_branch_get_subbranch_at_eid(svn_branch_state_t *branch,
+                                int eid,
+                                apr_pool_t *scratch_pool);
+
+/* Return the subtree of BRANCH rooted at EID.
+ * Recursive: includes subbranches.
+ *
+ * The result is limited by the lifetime of BRANCH. It includes a shallow
+ * copy of the element maps in BRANCH and its subbranches: the hash tables
+ * are duplicated but the keys and values (element content data) are not.
+ * It assumes that modifications on a svn_branch_state_t treat element
+ * map keys and values as immutable -- which they do.
+ */
+svn_branch_subtree_t *
+svn_branch_get_subtree(svn_branch_state_t *branch,
+                       int eid,
+                       apr_pool_t *result_pool);
 
-/* Write to STREAM a parseable representation of BRANCH.
+/* Instantiate elements in a branch.
+ *
+ * In TO_BRANCH, instantiate (or alter, if existing) each element of
+ * ELEMENTS, each with its given tree structure (parent, name) and payload.
+ *
+ * Also branch the subbranches in ELEMENTS, creating corresponding new
+ * subbranches in TO_BRANCH, recursively.
  */
 svn_error_t *
-svn_branch_state_serialize(svn_stream_t *stream,
-                           svn_branch_state_t *branch,
-                           apr_pool_t *scratch_pool);
+svn_branch_instantiate_elements_r(svn_branch_state_t *to_branch,
+                                  svn_branch_subtree_t elements,
+                                  apr_pool_t *scratch_pool);
 
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* SVN_BRANCH_H */
+#endif /* SVN_BRANCH_NESTED_H */

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h?rev=1708550&r1=1708549&r2=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h Wed Oct 14 06:38:16 2015
@@ -60,14 +60,6 @@ struct svn_branch_revision_root_t *
 svn_branch_repos_get_revision(const svn_branch_repos_t *repos,
                               svn_revnum_t revnum);
 
-/* Return a pointer to the root branch of revision REVNUM of the
- * repository REPOS.
- */
-struct svn_branch_state_t *
-svn_branch_repos_get_root_branch(const svn_branch_repos_t *repos,
-                                 svn_revnum_t revnum,
-                                 int top_branch_num);
-
 /* Return the revision root that represents the base revision (or,
  * potentially, txn) of the revision or txn REV_ROOT.
  */
@@ -104,27 +96,6 @@ 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 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
- * field is -1.
- *
- * Allocate *EL_REV_P (but not the branch object that it refers to) in
- * RESULT_POOL.
- *
- * ### TODO: Clarify sequencing requirements.
- */
-svn_error_t *
-svn_branch_repos_find_el_rev_by_path_rev(svn_branch_el_rev_id_t **el_rev_p,
-                                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);
-
 
 #ifdef __cplusplus
 }

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=1708550&r1=1708549&r2=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c Wed Oct 14 06:38:16 2015
@@ -80,6 +80,30 @@ svn_branch_txn_new_eid(svn_branch_revisi
   return eid;
 }
 
+/*  */
+static const char *
+branch_finalize_bid(const char *bid,
+                    int mapping_offset,
+                    apr_pool_t *result_pool)
+{
+  const char *outer_bid;
+  int outer_eid;
+
+  svn_branch_id_unnest(&outer_bid, &outer_eid, bid, result_pool);
+
+  if (outer_bid)
+    {
+      outer_bid = branch_finalize_bid(outer_bid, mapping_offset, result_pool);
+    }
+
+  if (outer_eid < -1)
+    {
+      outer_eid = mapping_offset - outer_eid;
+    }
+
+  return svn_branch_id_nest(outer_bid, outer_eid, result_pool);
+}
+
 /* Change txn-local EIDs (negative integers) in BRANCH to revision EIDs, by
  * assigning a new revision-EID (positive integer) for each one.
  */
@@ -90,16 +114,12 @@ branch_finalize_eids(svn_branch_state_t
 {
   apr_hash_index_t *hi;
 
+  branch->bid = branch_finalize_bid(branch->bid, mapping_offset, scratch_pool);
   if (branch->root_eid < -1)
     {
       branch->root_eid = mapping_offset - branch->root_eid;
     }
 
-  if (branch->outer_eid < -1)
-    {
-      branch->outer_eid = mapping_offset - branch->outer_eid;
-    }
-
   for (hi = apr_hash_first(scratch_pool, branch->e_map);
        hi; hi = apr_hash_next(hi))
     {
@@ -149,16 +169,6 @@ svn_branch_txn_finalize_eids(svn_branch_
   return SVN_NO_ERROR;
 }
 
-svn_branch_state_t *
-svn_branch_revision_root_get_root_branch(svn_branch_revision_root_t *rev_root,
-                                         int top_branch_num)
-{
-  if (top_branch_num < 0 || top_branch_num >= rev_root->root_branches->nelts)
-    return NULL;
-  return APR_ARRAY_IDX(rev_root->root_branches, top_branch_num, void *);
-
-}
-
 const apr_array_header_t *
 svn_branch_revision_root_get_branches(svn_branch_revision_root_t *rev_root,
                                       apr_pool_t *result_pool)
@@ -200,12 +210,8 @@ assert_branch_state_invariants(const svn
 {
   apr_hash_index_t *hi;
 
+  assert(branch->bid);
   assert(branch->rev_root);
-  if (branch->outer_branch)
-    {
-      assert(EID_IS_ALLOCATED(branch, branch->outer_eid));
-    }
-  assert(branch->outer_eid != -1);
   assert(branch->e_map);
 
   /* Validate elements in the map */
@@ -218,21 +224,19 @@ assert_branch_state_invariants(const svn
 }
 
 svn_branch_state_t *
-svn_branch_state_create(svn_branch_rev_bid_t *predecessor,
+svn_branch_state_create(const char *bid,
+                        svn_branch_rev_bid_t *predecessor,
                         int root_eid,
                         svn_branch_revision_root_t *rev_root,
-                        svn_branch_state_t *outer_branch,
-                        int outer_eid,
                         apr_pool_t *result_pool)
 {
   svn_branch_state_t *b = apr_pcalloc(result_pool, sizeof(*b));
 
+  b->bid = apr_pstrdup(result_pool, bid);
   b->predecessor = svn_branch_rev_bid_dup(predecessor, result_pool);
   b->root_eid = root_eid;
   b->rev_root = rev_root;
   b->e_map = apr_hash_make(result_pool);
-  b->outer_branch = outer_branch;
-  b->outer_eid = outer_eid;
   assert_branch_state_invariants(b, result_pool);
   return b;
 }
@@ -437,8 +441,6 @@ svn_branch_get_element(const svn_branch_
 {
   svn_branch_el_rev_content_t *element;
 
-  SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-
   element = svn_int_hash_get(branch->e_map, eid);
 
   if (element)
@@ -504,13 +506,12 @@ map_purge_orphans(apr_hash_t *e_map,
                   apr_pool_t *scratch_pool);
 
 svn_branch_subtree_t *
-svn_branch_get_subtree(const svn_branch_state_t *branch,
+svn_branch_get_subtree_n(svn_branch_state_t *branch,
                        int eid,
                        apr_pool_t *result_pool)
 {
   svn_branch_subtree_t *new_subtree;
   svn_branch_el_rev_content_t *subtree_root_element;
-  SVN_ITER_T(svn_branch_state_t) *bi;
 
   SVN_BRANCH_SEQUENCE_POINT(branch);
 
@@ -529,25 +530,6 @@ svn_branch_get_subtree(const svn_branch_
                    svn_branch_el_rev_content_create(
                      -1, "", subtree_root_element->payload, result_pool));
 
-  /* Add subbranches */
-  for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
-                            branch, result_pool, result_pool), result_pool))
-    {
-      svn_branch_state_t *subbranch = bi->val;
-      const char *subbranch_relpath_in_subtree
-        = svn_branch_subtree_get_path_by_eid(new_subtree, subbranch->outer_eid,
-                                             bi->iterpool);
-
-      /* Is it pathwise at or below EID? If so, add it into the subtree. */
-      if (subbranch_relpath_in_subtree)
-        {
-          svn_branch_subtree_t *this_subtree
-            = svn_branch_get_subtree(subbranch, subbranch->root_eid, result_pool);
-
-          svn_int_hash_set(new_subtree->subbranches, subbranch->outer_eid,
-                           this_subtree);
-        }
-    }
   return new_subtree;
 }
 
@@ -602,50 +584,10 @@ map_purge_orphans(apr_hash_t *e_map,
 }
 
 void
-svn_branch_purge_r(svn_branch_state_t *branch,
-                   apr_pool_t *scratch_pool)
+svn_branch_purge(svn_branch_state_t *branch,
+                 apr_pool_t *scratch_pool)
 {
-  SVN_ITER_T(svn_branch_state_t) *bi;
-
-  /* first, remove elements that have no parent element */
   map_purge_orphans(branch->e_map, branch->root_eid, scratch_pool);
-
-  /* second, remove subbranches that have no subbranch-root element */
-  for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
-                            branch, scratch_pool, scratch_pool), scratch_pool))
-    {
-      svn_branch_state_t *b = bi->val;
-
-      if (svn_branch_get_element(branch, b->outer_eid))
-        {
-          svn_branch_purge_r(b, bi->iterpool);
-        }
-      else
-        {
-          svn_branch_delete_branch_r(b, bi->iterpool);
-        }
-    }
-}
-
-const char *
-svn_branch_get_root_rrpath(const svn_branch_state_t *branch,
-                           apr_pool_t *result_pool)
-{
-  const char *root_rrpath;
-
-  if (branch->outer_branch)
-    {
-      root_rrpath
-        = svn_branch_get_rrpath_by_eid(branch->outer_branch, branch->outer_eid,
-                                       result_pool);
-    }
-  else
-    {
-      root_rrpath = "";
-    }
-
-  SVN_ERR_ASSERT_NO_RETURN(root_rrpath);
-  return root_rrpath;
 }
 
 const char *
@@ -688,22 +630,6 @@ svn_branch_get_path_by_eid(const svn_bra
   return path;
 }
 
-const char *
-svn_branch_get_rrpath_by_eid(const svn_branch_state_t *branch,
-                             int eid,
-                             apr_pool_t *result_pool)
-{
-  const char *path = svn_branch_get_path_by_eid(branch, eid, result_pool);
-  const char *rrpath = NULL;
-
-  if (path)
-    {
-      rrpath = svn_relpath_join(svn_branch_get_root_rrpath(branch, result_pool),
-                                path, result_pool);
-    }
-  return rrpath;
-}
-
 int
 svn_branch_get_eid_by_path(const svn_branch_state_t *branch,
                            const char *path,
@@ -733,23 +659,6 @@ svn_branch_get_eid_by_path(const svn_bra
   return -1;
 }
 
-int
-svn_branch_get_eid_by_rrpath(svn_branch_state_t *branch,
-                             const char *rrpath,
-                             apr_pool_t *scratch_pool)
-{
-  const char *path = svn_relpath_skip_ancestor(svn_branch_get_root_rrpath(
-                                                 branch, scratch_pool),
-                                               rrpath);
-  int eid = -1;
-
-  if (path)
-    {
-      eid = svn_branch_get_eid_by_path(branch, path, scratch_pool);
-    }
-  return eid;
-}
-
 svn_error_t *
 svn_branch_map_add_subtree(svn_branch_state_t *to_branch,
                            int to_eid,
@@ -824,100 +733,31 @@ svn_branch_instantiate_elements(svn_bran
                        this_element, apr_hash_pool_get(to_branch->e_map)));
     }
 
-  /* branch any subbranches */
-  {
-    SVN_ITER_T(svn_branch_subtree_t) *bi;
-
-    for (SVN_HASH_ITER(bi, scratch_pool, elements.subbranches))
-      {
-        int this_outer_eid = svn_int_hash_this_key(bi->apr_hi);
-        svn_branch_subtree_t *this_subtree = bi->val;
-        svn_branch_state_t *new_branch;
-
-        /* branch this subbranch into NEW_BRANCH (recursing) */
-        new_branch = svn_branch_add_new_branch(to_branch->rev_root,
-                                               this_subtree->predecessor,
-                                               to_branch, this_outer_eid,
-                                               this_subtree->root_eid,
-                                               bi->iterpool);
-
-        SVN_ERR(svn_branch_instantiate_elements(new_branch, *this_subtree,
-                                                bi->iterpool));
-      }
-  }
-
   return SVN_NO_ERROR;
 }
 
-apr_array_header_t *
-svn_branch_get_immediate_subbranches(const svn_branch_state_t *branch,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool)
-{
-  svn_array_t *subbranches = svn_array_make(result_pool);
-  SVN_ITER_T(svn_branch_state_t) *bi;
-
-  for (SVN_ARRAY_ITER(bi, branch->rev_root->branches, scratch_pool))
-    {
-      /* Is it an immediate child? */
-      if (bi->val->outer_branch == branch)
-        SVN_ARRAY_PUSH(subbranches) = bi->val;
-    }
-  return subbranches;
-}
-
 svn_branch_state_t *
-svn_branch_get_subbranch_at_eid(svn_branch_state_t *branch,
-                                int eid,
-                                apr_pool_t *scratch_pool)
-{
-  SVN_ITER_T(svn_branch_state_t) *bi;
-
-  /* TODO: more efficient to search in branch->rev_root->branches */
-  for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
-                            branch, scratch_pool, scratch_pool), scratch_pool))
-    {
-      if (bi->val->outer_eid == eid)
-        return bi->val;
-    }
-  return NULL;
-}
-
-svn_branch_state_t *
-svn_branch_add_new_branch(svn_branch_revision_root_t *rev_root,
+svn_branch_add_new_branch(const char *bid,
+                          svn_branch_revision_root_t *rev_root,
                           svn_branch_rev_bid_t *predecessor,
-                          svn_branch_state_t *outer_branch,
-                          int outer_eid,
                           int root_eid,
                           apr_pool_t *scratch_pool)
 {
   svn_branch_state_t *new_branch;
 
-  SVN_ERR_ASSERT_NO_RETURN(!outer_branch || outer_branch->rev_root == rev_root);
   SVN_ERR_ASSERT_NO_RETURN(root_eid != -1);
 
-  if (! outer_branch)
-    outer_eid = rev_root->root_branches->nelts;
-
-  new_branch = svn_branch_state_create(predecessor, root_eid, rev_root,
-                                       outer_branch, outer_eid,
+  new_branch = svn_branch_state_create(bid, predecessor, root_eid, rev_root,
                                        rev_root->branches->pool);
 
-  /* A branch must not already exist at this outer element */
-  SVN_ERR_ASSERT_NO_RETURN(!outer_branch ||
-                           svn_branch_get_subbranch_at_eid(
-                             outer_branch, outer_eid, scratch_pool) == NULL);
-
   SVN_ARRAY_PUSH(rev_root->branches) = new_branch;
-  if (!outer_branch)
+  if (!strchr(bid, '.'))
     SVN_ARRAY_PUSH(rev_root->root_branches) = new_branch;
 
   return new_branch;
 }
 
-/* Remove branch BRANCH from the list of branches in REV_ROOT.
- */
-static void
+void
 svn_branch_revision_root_delete_branch(
                                 svn_branch_revision_root_t *rev_root,
                                 svn_branch_state_t *branch,
@@ -951,23 +791,6 @@ svn_branch_revision_root_delete_branch(
     }
 }
 
-void
-svn_branch_delete_branch_r(svn_branch_state_t *branch,
-                           apr_pool_t *scratch_pool)
-{
-  SVN_ITER_T(svn_branch_state_t) *bi;
-
-  for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
-                            branch, scratch_pool, scratch_pool), scratch_pool))
-    {
-      svn_branch_delete_branch_r(bi->val, bi->iterpool);
-    }
-
-  svn_branch_revision_root_delete_branch(branch->rev_root,
-                                         branch, scratch_pool);
-}
-
-
 /*
  * ========================================================================
  * Parsing and Serializing
@@ -979,7 +802,7 @@ svn_branch_get_default_r0_metadata(apr_p
 {
   static const char *default_repos_info
     = "r0: eids 0 1 branches 1\n"
-      "B0 root-eid 0 num-eids 1  # at /\n"
+      "B0 root-eid 0 num-eids 1\n"
       "e0: normal -1 .\n";
 
   return svn_string_create(default_repos_info, result_pool);
@@ -1102,7 +925,6 @@ svn_branch_state_parse(svn_branch_state_
   int root_eid, num_eids;
   svn_branch_rev_bid_t *predecessor;
   svn_branch_state_t *branch_state;
-  svn_branch_state_t *outer_branch;
   int outer_eid;
   int i;
 
@@ -1114,17 +936,8 @@ svn_branch_state_parse(svn_branch_state_
     const char *outer_bid;
 
     svn_branch_id_unnest(&outer_bid, &outer_eid, bid, scratch_pool);
-    if (outer_bid)
-      {
-        outer_branch
-          = svn_branch_revision_root_get_branch_by_id(rev_root, outer_bid,
-                                                      scratch_pool);
-      }
-    else
-      outer_branch = NULL;
   }
-  branch_state = svn_branch_state_create(predecessor, root_eid, rev_root,
-                                         outer_branch, outer_eid,
+  branch_state = svn_branch_state_create(bid, predecessor, root_eid, rev_root,
                                          result_pool);
 
   /* Read in the structure. Set the payload of each normal element to a
@@ -1201,7 +1014,7 @@ svn_branch_revision_root_parse(svn_branc
       SVN_ARRAY_PUSH(rev_root->branches) = branch;
 
       /* Note the root branches */
-      if (! branch->outer_branch)
+      if (! strchr(branch->bid, '.'))
         {
           APR_ARRAY_PUSH(rev_root->root_branches, void *) = branch;
         }
@@ -1229,8 +1042,6 @@ svn_branch_state_serialize(svn_stream_t
                            svn_branch_state_t *branch,
                            apr_pool_t *scratch_pool)
 {
-  const char *branch_root_rrpath = svn_branch_get_root_rrpath(branch,
-                                                              scratch_pool);
   SVN_ITER_T(svn_branch_el_rev_content_t) *hi;
   const char *predecessor_str = "";
 
@@ -1243,12 +1054,11 @@ svn_branch_state_serialize(svn_stream_t
     }
 
   SVN_ERR(svn_stream_printf(stream, scratch_pool,
-                            "%s root-eid %d num-eids %d%s  # at /%s\n",
+                            "%s root-eid %d num-eids %d%s\n",
                             svn_branch_get_id(branch, scratch_pool),
                             branch->root_eid,
                             apr_hash_count(branch->e_map),
-                            predecessor_str,
-                            branch_root_rrpath));
+                            predecessor_str));
 
   map_purge_orphans(branch->e_map, branch->root_eid, scratch_pool);
 
@@ -1307,71 +1117,10 @@ svn_branch_revision_root_serialize(svn_s
  * ========================================================================
  */
 
-void
-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 *relpath,
-                                apr_pool_t *scratch_pool)
-{
-  /* The path we're looking for is (path-wise) in this branch. See if it
-     is also in a sub-branch. */
-  while (TRUE)
-    {
-      SVN_ITER_T(svn_branch_state_t) *bi;
-      svn_boolean_t found = FALSE;
-
-      for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
-                                root_branch, scratch_pool, scratch_pool),
-                          scratch_pool))
-        {
-          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_path(root_branch, relpath, scratch_pool);
-}
-
-
-/*
- * ========================================================================
- */
-
 const char *
 svn_branch_get_id(svn_branch_state_t *branch,
                   apr_pool_t *result_pool)
 {
-  const char *id = "";
-
-  while (branch->outer_branch)
-    {
-      id = apr_psprintf(result_pool, ".%d%s", branch->outer_eid, id);
-      branch = branch->outer_branch;
-    }
-  id = apr_psprintf(result_pool, "B%d%s", branch->outer_eid, id);
-  return id;
+  return branch->bid;
 }