subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1697871 - in /subversion/branches/move-tracking-2/subversion: include/private/svn_branch.h include/private/svn_branch_repos.h libsvn_delta/branch.c libsvn_delta/branch_repos.c libsvn_delta/compat3e.c libsvn_ra/ra_loader.c svnmover/svnmover.c
Date Wed, 26 Aug 2015 10:10:32 GMT
Author: julianfoad
Date: Wed Aug 26 10:10:31 2015
New Revision: 1697871

URL: http://svn.apache.org/r1697871
Log:
On the 'move-tracking-2' branch: Separate the repository-object API from the
rest of the branching API, into its own header and implementation files.

* subversion/include/private/svn_branch.h,
  subversion/libsvn_delta/branch.c
  (svn_branch_repos_t): Leave the typedef here; make the struct definition
    opaque, moving it to 'branch_repos.c'.
  (svn_branch_repos_create,
   svn_branch_repos_get_revision,
   svn_branch_repos_get_root_branch,
   svn_branch_repos_get_branch_by_id,
   svn_branch_repos_find_el_rev_by_id,
   svn_branch_repos_find_el_rev_by_path_rev,
   svn_branch_revision_root_get_base): Move these...

* subversion/include/private/svn_branch_repos.h,
  subversion/libsvn_delta/branch_repos.c
  ... to these new files.
  (svn_branch_repos_get_base_revision_root): Renamed from
    'svn_branch_revision_root_get_base'.
  (svn_branch_repos_add_revision): New.

* subversion/libsvn_delta/compat3e.c
  Include 'svn_branch_repos.h'.

* subversion/libsvn_ra/ra_loader.c
  Include 'svn_branch_repos.h'.
  (svn_branch_repos_fetch_info,
   commit_callback_wrapper): Use 'svn_branch_repos_add_revision' instead of
    direct access to the 'repos' structure.

* subversion/svnmover/svnmover.c
  Include 'svn_branch_repos.h'.
  (wc_checkout,
   display_diff_of_commit): Track the rename.

Added:
    subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h
      - copied, changed from r1697723, subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c
      - copied, changed from r1697723, 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/libsvn_delta/branch.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c
    subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c

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=1697871&r1=1697870&r2=1697871&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 Aug 26 10:10:31 2015
@@ -119,82 +119,7 @@ typedef struct svn_branch_state_t svn_br
 
 /* Per-repository branching info.
  */
-typedef struct svn_branch_repos_t
-{
-  /* Array of (svn_branch_revision_root_t *), indexed by revision number. */
-  apr_array_header_t *rev_roots;
-
-  /* The pool in which this object lives. */
-  apr_pool_t *pool;
-} svn_branch_repos_t;
-
-/* Create a new branching metadata object */
-svn_branch_repos_t *
-svn_branch_repos_create(apr_pool_t *result_pool);
-
-/* Return a pointer to revision REVNUM of the repository REPOS.
- */
-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);
-
-/* 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.
- *
- * 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.
- */
-svn_error_t *
-svn_branch_repos_find_el_rev_by_id(svn_branch_el_rev_id_t **el_rev_p,
-                                   const svn_branch_repos_t *repos,
-                                   svn_revnum_t revnum,
-                                   const char *branch_id,
-                                   int eid,
-                                   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);
+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).
@@ -232,12 +157,6 @@ svn_branch_revision_root_create(svn_bran
                                 svn_revnum_t base_rev,
                                 apr_pool_t *result_pool);
 
-/* Return the revision root that represents the base revision (or,
- * potentially, txn) of the revision or txn REV_ROOT.
- */
-svn_branch_revision_root_t *
-svn_branch_revision_root_get_base(svn_branch_revision_root_t *rev_root);
-
 /* Return the top-level branch numbered TOP_BRANCH_NUM in REV_ROOT.
  *
  * Return null if there is no such branch.

Copied: subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h (from r1697723, 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_repos.h?p2=subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h&p1=subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h&r1=1697723&r2=1697871&rev=1697871&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_branch_repos.h Wed Aug 26 10:10:31 2015
@@ -20,118 +20,40 @@
  * ====================================================================
  * @endcopyright
  *
- * @file svn_branch.h
- * @brief Operating on a branched version history
+ * @file svn_branch_repos.h
+ * @brief Operating on a repository
  *
  * @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_REPOS_H
+#define SVN_BRANCH_REPOS_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_state_t svn_branch_state_t;
-
-/* Per-repository branching info.
- */
-typedef struct svn_branch_repos_t
-{
-  /* Array of (svn_branch_revision_root_t *), indexed by revision number. */
-  apr_array_header_t *rev_roots;
-
-  /* The pool in which this object lives. */
-  apr_pool_t *pool;
-} svn_branch_repos_t;
-
 /* Create a new branching metadata object */
 svn_branch_repos_t *
 svn_branch_repos_create(apr_pool_t *result_pool);
 
+/* Add REV_ROOT as the next revision in the repository REPOS.
+ *
+ * (This does not change the REV and BASE_REV fields of REV_ROOT. The
+ * caller should set those, before or after this call.)
+ */
+svn_error_t *
+svn_branch_repos_add_revision(svn_branch_repos_t *repos,
+                              svn_branch_revision_root_t *rev_root);
+
 /* Return a pointer to revision REVNUM of the repository REPOS.
  */
 struct svn_branch_revision_root_t *
@@ -146,6 +68,12 @@ svn_branch_repos_get_root_branch(const s
                                  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.
+ */
+svn_branch_revision_root_t *
+svn_branch_repos_get_base_revision_root(svn_branch_revision_root_t *rev_root);
+
 /* Set *BRANCH_P to the branch found in REPOS : REVNUM : BRANCH_ID.
  *
  * Return an error if REVNUM or BRANCH_ID is not found.
@@ -156,6 +84,7 @@ svn_branch_repos_get_branch_by_id(svn_br
                                   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.
  *
@@ -196,605 +125,9 @@ svn_branch_repos_find_el_rev_by_path_rev
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool);
 
-/* 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. */
-  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 revision root that represents the base revision (or,
- * potentially, txn) of the revision or txn REV_ROOT.
- */
-svn_branch_revision_root_t *
-svn_branch_revision_root_get_base(svn_branch_revision_root_t *rev_root);
-
-/* 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 element id in REV_ROOT.
- */
-int
-svn_branch_allocate_new_eid(svn_branch_revision_root_t *rev_root);
-
-/* 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 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(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);
-
-/* 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, or, if ROOT_EID is -1, allocate a new
- * EID for the root element.
- */
-svn_branch_state_t *
-svn_branch_add_new_branch(svn_branch_revision_root_t *rev_root,
-                          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;
-
-};
-
-/* 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);
-
-/* 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);
-
-/* 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
-{
-  /* 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);
-
-/* Set or change the EID:element mapping for EID in BRANCH to reflect a
- * subbranch root element. This element has no payload in this branch; the
- * corresponding element of the subbranch will define its payload.
- *
- * Duplicate NEW_NAME into the branch mapping's pool.
- */
-void
-svn_branch_update_subbranch_root_element(svn_branch_state_t *branch,
-                                         int eid,
-                                         svn_branch_eid_t new_parent_eid,
-                                         const char *new_name);
-
-/* Purge orphaned elements and subbranches.
- */
-void
-svn_branch_purge_r(svn_branch_state_t *branch,
-                   apr_pool_t *scratch_pool);
-
-/* Instantiate a subtree.
- *
- * In TO_BRANCH, instantiate (or alter, if existing) each element of
- * FROM_SUBTREE, with the given tree structure and payload. Set the subtree
- * root element's parent to NEW_PARENT_EID and name to NEW_NAME.
- *
- * Also branch the subbranches in FROM_SUBTREE, creating corresponding new
- * subbranches in TO_BRANCH, recursively.
- *
- * NEW_PARENT_EID MUST be an existing element in TO_BRANCH. It may be the
- * root element of TO_BRANCH.
- */
-svn_error_t *
-svn_branch_instantiate_subtree(svn_branch_state_t *to_branch,
-                               svn_branch_eid_t new_parent_eid,
-                               const char *new_name,
-                               svn_branch_subtree_t from_subtree,
-                               apr_pool_t *scratch_pool);
-
-/* Create a new branch of a given subtree.
- *
- * Create a new branch object. Register its existence in REV_ROOT.
- * Instantiate the subtree FROM_SUBTREE in this new branch. In the new
- * branch, create new subbranches corresponding to any subbranches
- * specified in FROM_SUBTREE, recursively.
- *
- * If TO_OUTER_BRANCH is NULL, create a top-level branch with a new top-level
- * branch number, ignoring TO_OUTER_EID. Otherise, create a branch that claims
- * to be nested under TO_OUTER_BRANCH:TO_OUTER_EID, but do not require that
- * a subbranch root element exists there, nor create one.
- *
- * Set *NEW_BRANCH_P to the new branch (the one at TO_OUTER_BRANCH:TO_OUTER_EID).
- */
-svn_error_t *
-svn_branch_branch_subtree(svn_branch_state_t **new_branch_p,
-                          svn_branch_subtree_t from_subtree,
-                          svn_branch_revision_root_t *rev_root,
-                          svn_branch_state_t *to_outer_branch,
-                          svn_branch_eid_t to_outer_eid,
-                          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);
-
-/* 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.
- *
- * ### 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.
- *
- * ### 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.
- *
- * ### 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.
- *
- * ### 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 *
-svn_branch_get_default_r0_metadata(apr_pool_t *result_pool);
-
-/* Create a new revision-root object *REV_ROOT_P, initialized with info
- * parsed from STREAM, allocated in RESULT_POOL.
- */
-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);
-
-/* Write to STREAM a parseable representation of REV_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);
-
-/* Write to STREAM a parseable representation of BRANCH.
- */
-svn_error_t *
-svn_branch_state_serialize(svn_stream_t *stream,
-                           svn_branch_state_t *branch,
-                           apr_pool_t *scratch_pool);
-
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* SVN_BRANCH_H */
+#endif /* SVN_BRANCH_REPOS_H */

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=1697871&r1=1697870&r2=1697871&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c Wed Aug 26 10:10:31 2015
@@ -54,35 +54,6 @@
   ((branch1)->outer_branch && \
    BRANCH_IS_SAME_BRANCH((branch1)->outer_branch, branch2, scratch_pool))
 
-svn_branch_repos_t *
-svn_branch_repos_create(apr_pool_t *result_pool)
-{
-  svn_branch_repos_t *repos = apr_pcalloc(result_pool, sizeof(*repos));
-
-  repos->rev_roots = svn_array_make(result_pool);
-  repos->pool = result_pool;
-  return repos;
-}
-
-struct svn_branch_revision_root_t *
-svn_branch_repos_get_revision(const svn_branch_repos_t *repos,
-                              svn_revnum_t revnum)
-{
-  assert(revnum < repos->rev_roots->nelts);
-  return svn_array_get(repos->rev_roots, revnum);
-}
-
-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)
-{
-  svn_branch_revision_root_t *rev_root
-    = svn_branch_repos_get_revision(repos, revnum);
-
-  return svn_branch_revision_root_get_root_branch(rev_root, top_branch_num);
-}
-
 svn_branch_revision_root_t *
 svn_branch_revision_root_create(svn_branch_repos_t *repos,
                                 svn_revnum_t rev,
@@ -100,13 +71,6 @@ svn_branch_revision_root_create(svn_bran
   return rev_root;
 }
 
-svn_branch_revision_root_t *
-svn_branch_revision_root_get_base(svn_branch_revision_root_t *rev_root)
-{
-  return svn_branch_repos_get_revision(rev_root->repos,
-                                       (int)rev_root->base_rev);
-}
-
 int
 svn_branch_allocate_new_eid(svn_branch_revision_root_t *rev_root)
 {
@@ -904,7 +868,7 @@ svn_branch_add_new_branch(svn_branch_rev
 
   new_branch = svn_branch_state_create(root_eid, rev_root,
                                        outer_branch, outer_eid,
-                                       rev_root->repos->pool);
+                                       rev_root->branches->pool);
 
   /* A branch must not already exist at this outer element */
   SVN_ERR_ASSERT_NO_RETURN(!outer_branch ||
@@ -1313,83 +1277,6 @@ svn_branch_find_nested_branch_element_by
     *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 *
-svn_branch_repos_find_el_rev_by_id(svn_branch_el_rev_id_t **el_rev_p,
-                                   const svn_branch_repos_t *repos,
-                                   svn_revnum_t revnum,
-                                   const char *branch_id,
-                                   int eid,
-                                   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));
-
-  el_rev->rev = revnum;
-  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;
-    }
-  else
-    {
-      el_rev->eid = -1;
-    }
-  *el_rev_p = el_rev;
-  return SVN_NO_ERROR;
-}
-
-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)
-{
-  svn_branch_el_rev_id_t *el_rev = apr_palloc(result_pool, sizeof(*el_rev));
-  svn_branch_state_t *branch;
-
-  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_relpath(&el_rev->branch,
-                                                   &el_rev->eid,
-                                                   branch, relpath,
-                                                   scratch_pool);
-
-  /* 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;
-}
-
 
 /*
  * ========================================================================

Copied: subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c (from r1697723, 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_repos.c?p2=subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c&p1=subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c&r1=1697723&r2=1697871&rev=1697871&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c Wed Aug 26 10:10:31 2015
@@ -1,5 +1,5 @@
 /*
- * branch.c : Element-Based Branching and Move Tracking.
+ * branch_repos.c : Element-Based Branching and Move Tracking.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -26,33 +26,23 @@
 #include "svn_types.h"
 #include "svn_error.h"
 #include "svn_dirent_uri.h"
-#include "svn_hash.h"
 #include "svn_iter.h"
 
-#include "private/svn_element.h"
-#include "private/svn_branch.h"
-#include "private/svn_sorts_private.h"
+#include "private/svn_branch_repos.h"
 #include "svn_private_config.h"
 
 
-/* Is EID allocated (no matter whether an element with this id exists)? */
-#define EID_IS_ALLOCATED(branch, eid) \
-  ((eid) >= (branch)->rev_root->first_eid && (eid) < (branch)->rev_root->next_eid)
-
-#define IS_BRANCH_ROOT_EID(branch, eid) \
-  ((eid) == (branch)->root_eid)
-
-/* Is BRANCH1 the same branch as BRANCH2? Compare by full branch-ids; don't
-   require identical branch objects. */
-#define BRANCH_IS_SAME_BRANCH(branch1, branch2, scratch_pool) \
-  (strcmp(svn_branch_get_id(branch1, scratch_pool), \
-          svn_branch_get_id(branch2, scratch_pool)) == 0)
-
-/* Is BRANCH1 an immediate child of BRANCH2? Compare by full branch-ids; don't
-   require identical branch objects. */
-#define BRANCH_IS_CHILD_OF_BRANCH(branch1, branch2, scratch_pool) \
-  ((branch1)->outer_branch && \
-   BRANCH_IS_SAME_BRANCH((branch1)->outer_branch, branch2, scratch_pool))
+/* Per-repository branching info.
+ */
+struct svn_branch_repos_t
+{
+  /* Array of (svn_branch_revision_root_t *), indexed by revision number. */
+  apr_array_header_t *rev_roots;
+
+  /* The pool in which this object lives. */
+  apr_pool_t *pool;
+};
+
 
 svn_branch_repos_t *
 svn_branch_repos_create(apr_pool_t *result_pool)
@@ -64,6 +54,15 @@ svn_branch_repos_create(apr_pool_t *resu
   return repos;
 }
 
+svn_error_t *
+svn_branch_repos_add_revision(svn_branch_repos_t *repos,
+                              svn_branch_revision_root_t *rev_root)
+{
+  APR_ARRAY_PUSH(repos->rev_roots, void *) = rev_root;
+
+  return SVN_NO_ERROR;
+}
+
 struct svn_branch_revision_root_t *
 svn_branch_repos_get_revision(const svn_branch_repos_t *repos,
                               svn_revnum_t revnum)
@@ -84,1233 +83,9 @@ svn_branch_repos_get_root_branch(const s
 }
 
 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)
-{
-  svn_branch_revision_root_t *rev_root
-    = apr_pcalloc(result_pool, sizeof(*rev_root));
-
-  rev_root->repos = repos;
-  rev_root->rev = rev;
-  rev_root->base_rev = base_rev;
-  rev_root->root_branches = apr_array_make(result_pool, 0, sizeof(void *));
-  rev_root->branches = svn_array_make(result_pool);
-  return rev_root;
-}
-
-svn_branch_revision_root_t *
-svn_branch_revision_root_get_base(svn_branch_revision_root_t *rev_root)
-{
-  return svn_branch_repos_get_revision(rev_root->repos,
-                                       (int)rev_root->base_rev);
-}
-
-int
-svn_branch_allocate_new_eid(svn_branch_revision_root_t *rev_root)
-{
-  int eid = rev_root->next_eid++;
-
-  return eid;
-}
-
-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)
-{
-  return rev_root->branches;
-}
-
-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)
-{
-  SVN_ITER_T(svn_branch_state_t) *bi;
-  svn_branch_state_t *branch = NULL;
-
-  for (SVN_ARRAY_ITER(bi, rev_root->branches, scratch_pool))
-    {
-      svn_branch_state_t *b = bi->val;
-
-      if (strcmp(svn_branch_get_id(b, scratch_pool), branch_id) == 0)
-        {
-          branch = b;
-          break;
-        }
-    }
-  return branch;
-}
-
-static void
-branch_validate_element(const svn_branch_state_t *branch,
-                        int eid,
-                        const svn_branch_el_rev_content_t *element);
-
-/* Assert BRANCH satisfies all its invariants.
- */
-static void
-assert_branch_state_invariants(const svn_branch_state_t *branch,
-                               apr_pool_t *scratch_pool)
-{
-  apr_hash_index_t *hi;
-
-  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 */
-  for (hi = apr_hash_first(scratch_pool, branch->e_map);
-       hi; hi = apr_hash_next(hi))
-    {
-      branch_validate_element(branch, svn_int_hash_this_key(hi),
-                              apr_hash_this_val(hi));
-    }
-}
-
-svn_branch_state_t *
-svn_branch_state_create(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->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;
-}
-
-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)
-{
-  svn_branch_el_rev_id_t *id = apr_palloc(result_pool, sizeof(*id));
-
-  id->branch = branch;
-  id->eid = eid;
-  id->rev = rev;
-  return id;
-}
-
-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_eid_t *id = apr_palloc(result_pool, sizeof(*id));
-
-  id->bid = branch_id;
-  id->eid = eid;
-  id->rev = rev;
-  return id;
-}
-
-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_eid_t *id = apr_pmemdup(result_pool, old_id, sizeof(*id));
-
-  id->bid = apr_pstrdup(result_pool, old_id->bid);
-  return id;
-}
-
-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)
-{
-  svn_branch_el_rev_content_t *content
-     = apr_palloc(result_pool, sizeof(*content));
-
-  content->parent_eid = parent_eid;
-  content->name = apr_pstrdup(result_pool, name);
-  content->payload = svn_element_payload_dup(payload, result_pool);
-  return content;
-}
-
-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)
-{
-  svn_branch_el_rev_content_t *content
-     = apr_pmemdup(result_pool, old, sizeof(*content));
-
-  content->name = apr_pstrdup(result_pool, old->name);
-  content->payload = svn_element_payload_dup(old->payload, result_pool);
-  return content;
-}
-
-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)
-{
-  if (!content_left && !content_right)
-    {
-      return TRUE;
-    }
-  else if (!content_left || !content_right)
-    {
-      return FALSE;
-    }
-
-  if (content_left->parent_eid != content_right->parent_eid)
-    {
-      return FALSE;
-    }
-  if (strcmp(content_left->name, content_right->name) != 0)
-    {
-      return FALSE;
-    }
-  if (! svn_element_payload_equal(content_left->payload, content_right->payload,
-                                  scratch_pool))
-    {
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-
-/*
- * ========================================================================
- * Branch mappings
- * ========================================================================
- */
-
-svn_branch_subtree_t *
-svn_branch_subtree_create(apr_hash_t *e_map,
-                          int root_eid,
-                          apr_pool_t *result_pool)
-{
-  svn_branch_subtree_t *subtree = apr_pcalloc(result_pool, sizeof(*subtree));
-
-  subtree->e_map = e_map ? apr_hash_copy(result_pool, e_map)
-                         : apr_hash_make(result_pool);
-  subtree->root_eid = root_eid;
-  subtree->subbranches = apr_hash_make(result_pool);
-  return subtree;
-}
-
-svn_branch_subtree_t *
-svn_branch_subtree_get_subbranch_at_eid(svn_branch_subtree_t *subtree,
-                                        int eid,
-                                        apr_pool_t *result_pool)
-{
-  subtree = svn_int_hash_get(subtree->subbranches, eid);
-
-  return subtree;
-}
-
-/* Validate that ELEMENT is suitable for a mapping of BRANCH:EID.
- * ELEMENT->payload may be null.
- */
-static void
-branch_validate_element(const svn_branch_state_t *branch,
-                        int eid,
-                        const svn_branch_el_rev_content_t *element)
-{
-  SVN_ERR_ASSERT_NO_RETURN(element);
-
-  /* Parent EID must be valid and different from this element's EID, or -1
-     iff this is the branch root element. */
-  SVN_ERR_ASSERT_NO_RETURN(
-    IS_BRANCH_ROOT_EID(branch, eid)
-    ? (element->parent_eid == -1)
-    : (element->parent_eid != eid
-       && EID_IS_ALLOCATED(branch, element->parent_eid)));
-
-  /* Element name must be given, and empty iff EID is the branch root. */
-  SVN_ERR_ASSERT_NO_RETURN(
-    element->name
-    && IS_BRANCH_ROOT_EID(branch, eid) == (*element->name == '\0'));
-
-  /* Payload, if specified, must be in full or by reference. */
-  if (element->payload)
-    {
-      SVN_ERR_ASSERT_NO_RETURN(svn_element_payload_invariants(element->payload));
-    }
-  else /* it's a subbranch root */
-    {
-      /* a subbranch root element must not be the branch root element */
-      SVN_ERR_ASSERT_NO_RETURN(eid != branch->root_eid);
-    }
-}
-
-apr_hash_t *
-svn_branch_get_elements(svn_branch_state_t *branch)
-{
-  return branch->e_map;
-}
-
-svn_branch_el_rev_content_t *
-svn_branch_get_element(const svn_branch_state_t *branch,
-                       int eid)
-{
-  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)
-    branch_validate_element(branch, eid, element);
-  return element;
-}
-
-/* In BRANCH, set element EID to ELEMENT.
- *
- * If ELEMENT is null, delete element EID. Otherwise, ELEMENT->payload may be
- * null meaning it is a subbranch-root.
- *
- * Assume ELEMENT is already allocated with sufficient lifetime.
- */
-static void
-branch_map_set(svn_branch_state_t *branch,
-               int eid,
-               svn_branch_el_rev_content_t *element)
-{
-  apr_pool_t *map_pool = apr_hash_pool_get(branch->e_map);
-
-  SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-  if (element)
-    branch_validate_element(branch, eid, element);
-
-  svn_int_hash_set(branch->e_map, eid, element);
-  assert_branch_state_invariants(branch, map_pool);
-}
-
-void
-svn_branch_delete_element(svn_branch_state_t *branch,
-                          int eid)
-{
-  SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-
-  branch_map_set(branch, eid, NULL);
-}
-
-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)
-{
-  apr_pool_t *map_pool = apr_hash_pool_get(branch->e_map);
-  svn_branch_el_rev_content_t *element
-    = svn_branch_el_rev_content_create(new_parent_eid, new_name, new_payload,
-                                       map_pool);
-
-  /* EID must be a valid element id */
-  SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-  /* NEW_PAYLOAD must be specified, either in full or by reference */
-  SVN_ERR_ASSERT_NO_RETURN(new_payload);
-
-  /* Insert the new version */
-  branch_map_set(branch, eid, element);
-}
-
-void
-svn_branch_update_subbranch_root_element(svn_branch_state_t *branch,
-                                         int eid,
-                                         svn_branch_eid_t new_parent_eid,
-                                         const char *new_name)
-{
-  apr_pool_t *map_pool = apr_hash_pool_get(branch->e_map);
-  svn_branch_el_rev_content_t *element
-    = svn_branch_el_rev_content_create(new_parent_eid, new_name,
-                                       NULL /*payload*/, map_pool);
-
-  /* EID must be a valid element id */
-  SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-
-  /* Insert the new version */
-  branch_map_set(branch, eid, element);
-}
-
-static void
-map_purge_orphans(apr_hash_t *e_map,
-                  int root_eid,
-                  apr_pool_t *scratch_pool);
-
-svn_branch_subtree_t *
-svn_branch_get_subtree(const 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);
-
-  new_subtree = svn_branch_subtree_create(branch->e_map, eid,
-                                          result_pool);
-
-  /* Purge orphans */
-  map_purge_orphans(new_subtree->e_map, new_subtree->root_eid, result_pool);
-
-  /* Remove 'parent' and 'name' attributes from subtree root element */
-  subtree_root_element
-    = svn_int_hash_get(new_subtree->e_map, new_subtree->root_eid);
-  svn_int_hash_set(new_subtree->e_map, new_subtree->root_eid,
-                   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;
-}
-
-/* Purge entries from E_MAP that don't connect, via parent directory hierarchy,
- * to ROOT_EID. In other words, remove elements that have been implicitly
- * deleted.
- *
- * ROOT_EID must be present in E_MAP.
- *
- * ### Does not detect cycles: current implementation will not purge a cycle
- *     that is disconnected from ROOT_EID. This could be a problem.
- */
-static void
-map_purge_orphans(apr_hash_t *e_map,
-                  int root_eid,
-                  apr_pool_t *scratch_pool)
-{
-  apr_hash_index_t *hi;
-  svn_boolean_t changed;
-
-  SVN_ERR_ASSERT_NO_RETURN(svn_int_hash_get(e_map, root_eid));
-
-  do
-    {
-      changed = FALSE;
-
-      for (hi = apr_hash_first(scratch_pool, e_map);
-           hi; hi = apr_hash_next(hi))
-        {
-          int this_eid = svn_int_hash_this_key(hi);
-          svn_branch_el_rev_content_t *this_element = apr_hash_this_val(hi);
-
-          if (this_eid != root_eid)
-            {
-              svn_branch_el_rev_content_t *parent_element
-                = svn_int_hash_get(e_map, this_element->parent_eid);
-
-              /* Purge if parent is deleted */
-              if (! parent_element)
-                {
-                  SVN_DBG(("purge orphan: e%d", this_eid));
-                  svn_int_hash_set(e_map, this_eid, NULL);
-                  changed = TRUE;
-                }
-              else
-                SVN_ERR_ASSERT_NO_RETURN(parent_element->payload);
-            }
-        }
-    }
-  while (changed);
-}
-
-void
-svn_branch_purge_r(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 *
-svn_branch_subtree_get_path_by_eid(const svn_branch_subtree_t *subtree,
-                                   int eid,
-                                   apr_pool_t *result_pool)
-{
-  const char *path = "";
-  svn_branch_el_rev_content_t *element;
-
-  for (; eid != subtree->root_eid; eid = element->parent_eid)
-    {
-      element = svn_int_hash_get(subtree->e_map, eid);
-      if (! element)
-        return NULL;
-      path = svn_relpath_join(element->name, path, result_pool);
-    }
-  SVN_ERR_ASSERT_NO_RETURN(eid == subtree->root_eid);
-  return path;
-}
-
-const char *
-svn_branch_get_path_by_eid(const svn_branch_state_t *branch,
-                           int eid,
-                           apr_pool_t *result_pool)
-{
-  const char *path = "";
-  svn_branch_el_rev_content_t *element;
-
-  SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-
-  for (; ! IS_BRANCH_ROOT_EID(branch, eid); eid = element->parent_eid)
-    {
-      element = svn_branch_get_element(branch, eid);
-      if (! element)
-        return NULL;
-      path = svn_relpath_join(element->name, path, result_pool);
-    }
-  SVN_ERR_ASSERT_NO_RETURN(IS_BRANCH_ROOT_EID(branch, eid));
-  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,
-                           apr_pool_t *scratch_pool)
-{
-  apr_hash_index_t *hi;
-
-  /* ### This is a crude, linear search */
-  for (hi = apr_hash_first(scratch_pool, branch->e_map);
-       hi; hi = apr_hash_next(hi))
-    {
-      int eid = svn_int_hash_this_key(hi);
-      const char *this_path = svn_branch_get_path_by_eid(branch, eid,
-                                                         scratch_pool);
-
-      if (! this_path)
-        {
-          /* Mapping is not complete; this element is in effect not present. */
-          continue;
-        }
-      if (strcmp(path, this_path) == 0)
-        {
-          return eid;
-        }
-    }
-
-  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,
-                           svn_branch_eid_t new_parent_eid,
-                           const char *new_name,
-                           svn_branch_subtree_t new_subtree,
-                           apr_pool_t *scratch_pool)
-{
-  apr_hash_index_t *hi;
-  svn_branch_el_rev_content_t *new_root_content;
-
-  if (new_subtree.subbranches && apr_hash_count(new_subtree.subbranches))
-    {
-      return svn_error_createf(SVN_ERR_BRANCHING, NULL,
-                               _("Adding or copying a subtree containing "
-                                 "subbranches is not implemented"));
-    }
-
-  /* Get a new EID for the root element, if not given. */
-  if (to_eid == -1)
-    {
-      to_eid = svn_branch_allocate_new_eid(to_branch->rev_root);
-    }
-
-  /* Create the new subtree root element */
-  new_root_content = svn_int_hash_get(new_subtree.e_map, new_subtree.root_eid);
-  if (new_root_content->payload)
-    svn_branch_update_element(to_branch, to_eid,
-                              new_parent_eid, new_name,
-                              new_root_content->payload);
-  else
-    svn_branch_update_subbranch_root_element(to_branch, to_eid,
-                                             new_parent_eid, new_name);
-
-  /* Process its immediate children */
-  for (hi = apr_hash_first(scratch_pool, new_subtree.e_map);
-       hi; hi = apr_hash_next(hi))
-    {
-      int this_from_eid = svn_int_hash_this_key(hi);
-      svn_branch_el_rev_content_t *from_element = apr_hash_this_val(hi);
-
-      if (from_element->parent_eid == new_subtree.root_eid)
-        {
-          svn_branch_subtree_t this_subtree;
-
-          /* Recurse. (We don't try to check whether it's a directory node,
-             as we might not have the node kind in the map.) */
-          this_subtree.e_map = new_subtree.e_map;
-          this_subtree.root_eid = this_from_eid;
-          this_subtree.subbranches = apr_hash_make(scratch_pool);
-          SVN_ERR(svn_branch_map_add_subtree(to_branch, -1 /*to_eid*/,
-                                             to_eid, from_element->name,
-                                             this_subtree, scratch_pool));
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_branch_instantiate_subtree(svn_branch_state_t *to_branch,
-                               svn_branch_eid_t new_parent_eid,
-                               const char *new_name,
-                               svn_branch_subtree_t new_subtree,
-                               apr_pool_t *scratch_pool)
-{
-  apr_hash_index_t *hi;
-  svn_branch_el_rev_content_t *new_root_content;
-
-  /* Source element must not be the same as the target parent element */
-  if (new_subtree.root_eid == new_parent_eid)
-    {
-      return svn_error_createf(SVN_ERR_BRANCHING, NULL,
-                               _("Cannot branch from e%d to %s e%d/%s: "
-                                 "target element cannot be its own parent"),
-                               new_subtree.root_eid,
-                               svn_branch_get_id(to_branch, scratch_pool),
-                               new_parent_eid, new_name);
-    }
-
-  /* Instantiate the root element of NEW_SUBTREE */
-  new_root_content = svn_int_hash_get(new_subtree.e_map, new_subtree.root_eid);
-  if (new_root_content->payload)
-    svn_branch_update_element(to_branch, new_subtree.root_eid,
-                              new_parent_eid, new_name,
-                              new_root_content->payload);
-  else
-    svn_branch_update_subbranch_root_element(to_branch, new_subtree.root_eid,
-                                             new_parent_eid, new_name);
-
-  /* Instantiate all the children of NEW_SUBTREE */
-  for (hi = apr_hash_first(scratch_pool, new_subtree.e_map);
-       hi; hi = apr_hash_next(hi))
-    {
-      int this_eid = svn_int_hash_this_key(hi);
-      svn_branch_el_rev_content_t *this_element = apr_hash_this_val(hi);
-
-      if (this_eid != new_subtree.root_eid)
-        {
-          branch_map_set(to_branch, this_eid, this_element);
-        }
-    }
-
-  /* branch any subbranches */
-  {
-    SVN_ITER_T(svn_branch_subtree_t) *bi;
-
-    for (SVN_HASH_ITER(bi, scratch_pool, new_subtree.subbranches))
-      {
-        int this_outer_eid = svn_int_hash_this_key(bi->apr_hi);
-        svn_branch_subtree_t *this_subtree = bi->val;
-
-        /* branch this subbranch into NEW_BRANCH (recursing) */
-        SVN_ERR(svn_branch_branch_subtree(NULL,
-                                          *this_subtree,
-                                          to_branch->rev_root,
-                                          to_branch, this_outer_eid,
-                                          bi->iterpool));
-      }
-  }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_branch_branch_subtree(svn_branch_state_t **new_branch_p,
-                          svn_branch_subtree_t from_subtree,
-                          svn_branch_revision_root_t *rev_root,
-                          svn_branch_state_t *to_outer_branch,
-                          svn_branch_eid_t to_outer_eid,
-                          apr_pool_t *scratch_pool)
-{
-  svn_branch_state_t *new_branch;
-
-  /* create new branch */
-  new_branch = svn_branch_add_new_branch(rev_root,
-                                         to_outer_branch, to_outer_eid,
-                                         from_subtree.root_eid,
-                                         scratch_pool);
-
-  /* Populate the new branch mapping */
-  SVN_ERR(svn_branch_instantiate_subtree(new_branch, -1, "", from_subtree,
-                                         scratch_pool));
-
-  if (new_branch_p)
-    *new_branch_p = new_branch;
-  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_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);
-
-  if (! outer_branch)
-    outer_eid = rev_root->root_branches->nelts;
-  if (root_eid == -1)
-    root_eid = svn_branch_allocate_new_eid(rev_root);
-
-  new_branch = svn_branch_state_create(root_eid, rev_root,
-                                       outer_branch, outer_eid,
-                                       rev_root->repos->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)
-    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
-svn_branch_revision_root_delete_branch(
-                                svn_branch_revision_root_t *rev_root,
-                                svn_branch_state_t *branch,
-                                apr_pool_t *scratch_pool)
-{
-  SVN_ITER_T(svn_branch_state_t) *bi;
-
-  SVN_ERR_ASSERT_NO_RETURN(branch->rev_root == rev_root);
-
-  for (SVN_ARRAY_ITER(bi, rev_root->branches, scratch_pool))
-    {
-      if (bi->val == branch)
-        {
-          SVN_DBG(("deleting branch b%s e%d",
-                   svn_branch_get_id(bi->val, bi->iterpool),
-                   bi->val->root_eid));
-          svn_sort__array_delete(rev_root->branches, bi->i, 1);
-          break;
-        }
-    }
-  for (SVN_ARRAY_ITER(bi, rev_root->root_branches, scratch_pool))
-    {
-      if (bi->val == branch)
-        {
-          SVN_DBG(("deleting root-branch b%s e%d",
-                   svn_branch_get_id(bi->val, bi->iterpool),
-                   bi->val->root_eid));
-          svn_sort__array_delete(rev_root->root_branches, bi->i, 1);
-          break;
-        }
-    }
-}
-
-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
- * ========================================================================
- */
-
-svn_string_t *
-svn_branch_get_default_r0_metadata(apr_pool_t *result_pool)
-{
-  static const char *default_repos_info
-    = "r0: eids 0 1 branches 1\n"
-      "B0 root-eid 0  # at /\n"
-      "e0: normal -1 .\n";
-
-  return svn_string_create(default_repos_info, result_pool);
-}
-
-/*  */
-static svn_error_t *
-parse_branch_line(char *bid_p,
-                  int *root_eid_p,
-                  svn_stream_t *stream,
-                  apr_pool_t *scratch_pool)
-{
-  svn_stringbuf_t *line;
-  svn_boolean_t eof;
-  int n;
-
-  /* Read a line */
-  SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, scratch_pool));
-  SVN_ERR_ASSERT(!eof);
-
-  n = sscanf(line->data, "%s root-eid %d",
-             bid_p, root_eid_p);
-  SVN_ERR_ASSERT(n >= 2);  /* C std is unclear on whether '%n' counts */
-
-  return SVN_NO_ERROR;
-}
-
-/*  */
-static svn_error_t *
-parse_element_line(int *eid_p,
-                   svn_boolean_t *is_subbranch_p,
-                   int *parent_eid_p,
-                   const char **name_p,
-                   svn_stream_t *stream,
-                   apr_pool_t *scratch_pool)
+svn_branch_repos_get_base_revision_root(svn_branch_revision_root_t *rev_root)
 {
-  svn_stringbuf_t *line;
-  svn_boolean_t eof;
-  char kind[10];
-  int n;
-  int offset;
-
-  /* Read a line */
-  SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, scratch_pool));
-  SVN_ERR_ASSERT(!eof);
-
-  n = sscanf(line->data, "e%d: %9s %d%n",
-             eid_p,
-             kind, parent_eid_p, &offset);
-  SVN_ERR_ASSERT(n >= 3);  /* C std is unclear on whether '%n' counts */
-  SVN_ERR_ASSERT(line->data[offset] == ' ');
-  *name_p = line->data + offset + 1;
-
-  *is_subbranch_p = (strcmp(kind, "subbranch") == 0);
-
-  if (strcmp(*name_p, "(null)") == 0)
-    *name_p = NULL;
-  else if (strcmp(*name_p, ".") == 0)
-    *name_p = "";
-
-  return SVN_NO_ERROR;
-}
-
-/* Set *OUTER_BID to the outer branch's id and *OUTER_EID to this branch's
- * outer EID.
- *
- * For a top-level branch, set *OUTER_BID to NULL and *OUTER_EID to the
- * top-level branch number.
- */
-static void
-branch_id_split(const char **outer_bid,
-                int *outer_eid,
-                const char *bid,
-                apr_pool_t *result_pool)
-{
-  char *last_dot = strrchr(bid, '.');
-
-  if (last_dot) /* BID looks like "B3.11" or "B3.11.22" etc. */
-    {
-      *outer_bid = apr_pstrndup(result_pool, bid, last_dot - bid);
-      *outer_eid = atoi(last_dot + 1);
-    }
-  else /* looks like "B0" or B22" (with no dot) */
-    {
-      *outer_bid = NULL;
-      *outer_eid = atoi(bid + 1);
-    }
-}
-
-/* Create a new branch *NEW_BRANCH, initialized
- * with info parsed from STREAM, allocated in RESULT_POOL.
- */
-static svn_error_t *
-svn_branch_state_parse(svn_branch_state_t **new_branch,
-                       svn_branch_revision_root_t *rev_root,
-                       svn_stream_t *stream,
-                       apr_pool_t *result_pool,
-                       apr_pool_t *scratch_pool)
-{
-  char bid[1000];
-  int root_eid;
-  svn_branch_state_t *branch_state;
-  svn_branch_state_t *outer_branch;
-  int outer_eid;
-  int eid;
-
-  SVN_ERR(parse_branch_line(bid, &root_eid,
-                            stream, scratch_pool));
-
-  /* Find the outer branch and outer EID */
-  {
-    const char *outer_bid;
-
-    branch_id_split(&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(root_eid, rev_root,
-                                         outer_branch, outer_eid,
-                                         result_pool);
-
-  /* Read in the structure. Set the payload of each normal element to a
-     (branch-relative) reference. */
-  for (eid = rev_root->first_eid; eid < rev_root->next_eid; eid++)
-    {
-      int this_eid, this_parent_eid;
-      const char *this_name;
-      svn_boolean_t is_subbranch;
-
-      SVN_ERR(parse_element_line(&this_eid,
-                                 &is_subbranch, &this_parent_eid, &this_name,
-                                 stream, scratch_pool));
-
-      if (this_name)
-        {
-          if (! is_subbranch)
-            {
-              svn_element_payload_t *payload
-                = svn_element_payload_create_ref(rev_root->rev, bid, eid,
-                                                 result_pool);
-              svn_branch_update_element(
-                branch_state, eid, this_parent_eid, this_name, payload);
-            }
-          else
-            {
-              svn_branch_update_subbranch_root_element(
-                branch_state, eid, this_parent_eid, this_name);
-            }
-        }
-    }
-
-  *new_branch = branch_state;
-  return SVN_NO_ERROR;
-}
-
-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)
-{
-  svn_branch_revision_root_t *rev_root;
-  svn_revnum_t rev;
-  int first_eid, next_eid;
-  int num_branches;
-  svn_stringbuf_t *line;
-  svn_boolean_t eof;
-  int n;
-  int j;
-
-  SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, scratch_pool));
-  SVN_ERR_ASSERT(! eof);
-  n = sscanf(line->data, "r%ld: eids %d %d "
-                         "branches %d",
-             &rev,
-             &first_eid, &next_eid,
-             &num_branches);
-  SVN_ERR_ASSERT(n == 4);
-
-  rev_root = svn_branch_revision_root_create(repos, rev, rev - 1,
-                                             result_pool);
-  rev_root->first_eid = first_eid;
-  rev_root->next_eid = next_eid;
-
-  /* parse the branches */
-  for (j = 0; j < num_branches; j++)
-    {
-      svn_branch_state_t *branch;
-
-      SVN_ERR(svn_branch_state_parse(&branch, rev_root, stream,
-                                     result_pool, scratch_pool));
-      SVN_ARRAY_PUSH(rev_root->branches) = branch;
-
-      /* Note the root branches */
-      if (! branch->outer_branch)
-        {
-          APR_ARRAY_PUSH(rev_root->root_branches, void *) = branch;
-        }
-    }
-
-  *rev_root_p = rev_root;
-  return SVN_NO_ERROR;
-}
-
-/* Write to STREAM a parseable representation of BRANCH.
- */
-svn_error_t *
-svn_branch_state_serialize(svn_stream_t *stream,
-                           svn_branch_state_t *branch,
-                           apr_pool_t *scratch_pool)
-{
-  svn_branch_revision_root_t *rev_root = branch->rev_root;
-  const char *branch_root_rrpath = svn_branch_get_root_rrpath(branch,
-                                                              scratch_pool);
-  int eid;
-
-  SVN_ERR(svn_stream_printf(stream, scratch_pool,
-                            "%s root-eid %d  # at /%s\n",
-                            svn_branch_get_id(branch, scratch_pool),
-                            branch->root_eid,
-                            branch_root_rrpath));
-
-  map_purge_orphans(branch->e_map, branch->root_eid, scratch_pool);
-  for (eid = rev_root->first_eid; eid < rev_root->next_eid; eid++)
-    {
-      svn_branch_el_rev_content_t *element = svn_branch_get_element(branch, eid);
-      int parent_eid;
-      const char *name;
-
-      if (element)
-        {
-          parent_eid = element->parent_eid;
-          name = element->name[0] ? element->name : ".";
-        }
-      else
-        {
-          /* ### TODO: instead, omit the line completely; but the
-                 parser currently can't handle that. */
-          parent_eid = -1;
-          name = "(null)";
-        }
-      SVN_ERR(svn_stream_printf(stream, scratch_pool,
-                                "e%d: %s %d %s\n",
-                                eid,
-                                element ? (element->payload ? "normal" : "subbranch")
-                                     : "none",
-                                parent_eid, name));
-    }
-  return SVN_NO_ERROR;
-}
-
-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_ITER_T(svn_branch_state_t) *bi;
-
-  SVN_ERR(svn_stream_printf(stream, scratch_pool,
-                            "r%ld: eids %d %d "
-                            "branches %d\n",
-                            rev_root->rev,
-                            rev_root->first_eid, rev_root->next_eid,
-                            rev_root->branches->nelts));
-
-  for (SVN_ARRAY_ITER(bi, rev_root->branches, scratch_pool))
-    SVN_ERR(svn_branch_state_serialize(stream, bi->val, bi->iterpool));
-  return SVN_NO_ERROR;
-}
-
-
-/*
- * ========================================================================
- */
-
-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);
+  return svn_branch_repos_get_revision(rev_root->repos, rev_root->base_rev);
 }
 
 svn_error_t *
@@ -1390,23 +165,3 @@ svn_branch_repos_find_el_rev_by_path_rev
   return SVN_NO_ERROR;
 }
 
-
-/*
- * ========================================================================
- */
-
-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;
-}
-

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=1697871&r1=1697870&r2=1697871&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c Wed Aug 26 10:10:31 2015
@@ -31,6 +31,7 @@
 #include "svn_props.h"
 #include "svn_pools.h"
 
+#include "private/svn_branch_repos.h"
 #include "private/svn_delta_private.h"
 #include "private/svn_editor3e.h"
 #include "../libsvn_delta/debug_editor.h"

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c?rev=1697871&r1=1697870&r2=1697871&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c Wed Aug 26 10:10:31 2015
@@ -52,6 +52,7 @@
 #include "ra_loader.h"
 #include "deprecated.h"
 
+#include "private/svn_branch_repos.h"
 #include "private/svn_auth_private.h"
 #include "private/svn_ra_private.h"
 #include "private/svn_delta_private.h"
@@ -750,7 +751,7 @@ svn_branch_repos_fetch_info(svn_branch_r
                                              repos, ra_session, branch_info_dir,
                                              r,
                                              result_pool, scratch_pool));
-      APR_ARRAY_PUSH(repos->rev_roots, void *) = rev_root;
+      SVN_ERR(svn_branch_repos_add_revision(repos, rev_root));
     }
 
   *repos_p = repos;
@@ -826,7 +827,7 @@ commit_callback_wrapper(const svn_commit
       svn_branch_repos_t *repos = ccwb->branching_txn->repos;
 
       ccwb->branching_txn->rev = commit_info->revision;
-      APR_ARRAY_PUSH(repos->rev_roots, void *) = ccwb->branching_txn;
+      SVN_ERR(svn_branch_repos_add_revision(repos, ccwb->branching_txn));
       SVN_ERR(store_repos_info(ccwb->branching_txn, ccwb->session,
                                ccwb->branch_info_dir, 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=1697871&r1=1697870&r2=1697871&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Wed Aug 26 10:10:31 2015
@@ -45,6 +45,7 @@
 
 #include "private/svn_cmdline_private.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_branch_repos.h"
 #include "private/svn_editor3e.h"
 #include "private/svn_ra_private.h"
 #include "private/svn_string_private.h"
@@ -193,7 +194,7 @@ wc_checkout(svnmover_wc_t *wc,
                                       wc->pool, scratch_pool));
 
   /* Store the WC base state */
-  base_txn = svn_branch_revision_root_get_base(edit_txn);
+  base_txn = svn_branch_repos_get_base_revision_root(edit_txn);
   wc->base = apr_pcalloc(wc->pool, sizeof(*wc->base));
   wc->base->revision = base_revision;
   wc->base->branch_id = base_branch_id;
@@ -2623,7 +2624,7 @@ display_diff_of_commit(const commit_call
                        apr_pool_t *scratch_pool)
 {
   svn_branch_revision_root_t *previous_head_txn
-    = svn_branch_revision_root_get_base(ccbb->edit_txn);
+    = svn_branch_repos_get_base_revision_root(ccbb->edit_txn);
   svn_branch_state_t *base_branch
     = svn_branch_revision_root_get_branch_by_id(previous_head_txn,
                                                 ccbb->wc_base_branch_id,



Mime
View raw message