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/08/26 12:10:32 UTC
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
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,