diff options
Diffstat (limited to 'subversion/include')
59 files changed, 5598 insertions, 415 deletions
diff --git a/subversion/include/private/ra_svn_sasl.h b/subversion/include/private/ra_svn_sasl.h index 428e20e8033c..e8284517a83a 100644 --- a/subversion/include/private/ra_svn_sasl.h +++ b/subversion/include/private/ra_svn_sasl.h @@ -27,14 +27,8 @@ #ifndef RA_SVN_SASL_H #define RA_SVN_SASL_H -#ifdef WIN32 -/* This prevents sasl.h from redefining iovec, which is always defined by APR - on win32. */ -#define STRUCT_IOVEC_DEFINED -#include <sasl.h> -#else -#include <sasl/sasl.h> -#endif +/* Keep this include statement at the top of this file. */ +#include "private/ra_svn_wrapped_sasl.h" #include <apr_errno.h> #include <apr_pools.h> diff --git a/subversion/include/private/ra_svn_wrapped_sasl.h b/subversion/include/private/ra_svn_wrapped_sasl.h new file mode 100644 index 000000000000..266a4f8279de --- /dev/null +++ b/subversion/include/private/ra_svn_wrapped_sasl.h @@ -0,0 +1,131 @@ +/* + * svn_wrapped_sasl.h : wrapped SASL API + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ + +#ifndef RA_SVN_WRAPPED_SASL_H +#define RA_SVN_WRAPPED_SASL_H + +#include <stddef.h> + +#ifdef WIN32 +# define APR_WANT_IOVEC +# include <apr_want.h> + /* This prevents sasl.h from redefining iovec, + which is always defined by APR on win32. */ +# define STRUCT_IOVEC_DEFINED +# include <sasl.h> +#else +# include <sasl/sasl.h> +#endif + +/* Apple deprecated the SASL API on Mac OS X 10.11, causing a + moderately huge number of deprecation warnings to be emitted during + compilation. Consequently, we wrap the parts of the SASL API that + we use in a set of private functions and disable the deprecation + warnings for this header and the implementation file. */ +#ifdef __APPLE__ +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# endif +#endif /* __APPLE__ */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void +svn_sasl__set_mutex(sasl_mutex_alloc_t *, sasl_mutex_lock_t *, + sasl_mutex_unlock_t *, sasl_mutex_free_t *); + +void +svn_sasl__done(void); + +void +svn_sasl__dispose(sasl_conn_t **); + +const char * +svn_sasl__errstring(int, const char *, const char **); + +const char * +svn_sasl__errdetail(sasl_conn_t *); + +int +svn_sasl__getprop(sasl_conn_t *, int, const void **); + +int +svn_sasl__setprop(sasl_conn_t *, int, const void *); + +int +svn_sasl__client_init(const sasl_callback_t *); + +int +svn_sasl__client_new(const char *, const char *, const char *, const char *, + const sasl_callback_t *, unsigned, sasl_conn_t **); + +int +svn_sasl__client_start(sasl_conn_t *, const char *, sasl_interact_t **, + const char **, unsigned *, const char **); + +int +svn_sasl__client_step(sasl_conn_t *, const char *, unsigned, + sasl_interact_t **, const char **, unsigned *); + +int +svn_sasl__server_init(const sasl_callback_t *, const char *); + +int +svn_sasl__server_new(const char *, const char *, const char *, + const char *, const char *, const sasl_callback_t *, + unsigned, sasl_conn_t **); + +int +svn_sasl__listmech(sasl_conn_t *, const char *, const char *, const char *, + const char *, const char **, unsigned *, int *); + +int +svn_sasl__server_start(sasl_conn_t *, const char *, const char *, unsigned, + const char **, unsigned *); + +int +svn_sasl__server_step(sasl_conn_t *, const char *, unsigned, + const char **, unsigned *); + +int +svn_sasl__encode(sasl_conn_t *, const char *, unsigned, + const char **, unsigned *); + +int +svn_sasl__decode(sasl_conn_t *, const char *, unsigned, + const char **, unsigned *); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#ifdef __APPLE__ +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) +# pragma GCC diagnostic pop +# endif +#endif /* __APPLE__ */ + +#endif /* RA_SVN_WRAPPED_SASL_H */ diff --git a/subversion/include/private/svn_atomic.h b/subversion/include/private/svn_atomic.h index 6a6b2dca6be1..f86a39ec68c6 100644 --- a/subversion/include/private/svn_atomic.h +++ b/subversion/include/private/svn_atomic.h @@ -76,21 +76,81 @@ extern "C" { /** @} */ /** + * @name Single-threaded atomic initialization + * @{ + */ + +/** + * Callback for svn_atomic__init_once(). + * @return an #svn_error_t if the initialization fails. + * @since New in 1.10 + */ +typedef svn_error_t *(*svn_atomic__err_init_func_t)(void *baton, + apr_pool_t *pool); + +/** + * Callback for svn_atomic__init_no_error(). + * @return a string containing an error message if the initialization fails. + * @since New in 1.10 + */ +typedef const char *(*svn_atomic__str_init_func_t)(void *baton); + +/** * Call an initialization function in a thread-safe manner. * * @a global_status must be a pointer to a global, zero-initialized - * #svn_atomic_t. @a init_func is a pointer to the function that performs - * the actual initialization. @a baton and and @a pool are passed on to the - * init_func for its use. + * #svn_atomic_t. @a err_init_func is a pointer to the function that + * performs the actual initialization. @a baton and and @a pool are + * passed on to @a err_init_func for its use. + * + * @return the error returned by @a err_init_func. * * @since New in 1.5. */ svn_error_t * svn_atomic__init_once(volatile svn_atomic_t *global_status, - svn_error_t *(*init_func)(void*,apr_pool_t*), + svn_atomic__err_init_func_t err_init_func, void *baton, apr_pool_t* pool); +/** + * Call an initialization function in a thread-safe manner. + * + * Unlike svn_atomic__init_once(), this function does not need a pool + * and does not create an #svn_error_t, and neither should the + * @a str_init_func implementation. + * + * @a global_status must be a pointer to a global, zero-initialized + * #svn_atomic_t. @a str_init_func is a pointer to the function that + * performs the actual initialization. @a baton is passed on to + * @a str_init_func for its use. + * + * @return the error string returned by @a str_init_func. + * + * @since New in 1.10. + */ +const char * +svn_atomic__init_once_no_error(volatile svn_atomic_t *global_status, + svn_atomic__str_init_func_t str_init_func, + void *baton); + + +/** + * Query and increment the global counter and set @a value to the new + * counter value. + * + * This function is thread-safe and you should call it whenever you need + * a number that is unique within the current process. The values are > 0. + * + * @return the error object in case of a synchronization failure. + * + * @since New in 1.10. + */ +svn_error_t * +svn_atomic__unique_counter(apr_uint64_t* value); + +/** @} */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_branch.h b/subversion/include/private/svn_branch.h new file mode 100644 index 000000000000..3fbaeb7ef77c --- /dev/null +++ b/subversion/include/private/svn_branch.h @@ -0,0 +1,679 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_branch.h + * @brief Operating on a branched version history + * + * @since New in ???. + */ + +/* 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__txn_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_branch__txn_sequence_point' method. + */ + + +#ifndef SVN_BRANCH_H +#define SVN_BRANCH_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" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* ### */ +#define SVN_BRANCH__ERR 123456 + +/** Element Identifier (EID). + * + * An element may appear in any or all branches, and its EID is the same in + * each branch in which the element appears. + * + * By definition, an element keeps the same EID for its whole lifetime, even + * if deleted from all branches and later 'resurrected'. + * + * In principle, an EID is an arbitrary token and has no intrinsic + * relationships (except equality) to other EIDs. The current implementation + * uses integers and allocates them sequentially from a central counter, but + * the implementation may be changed. + * + * ### In most places the code currently says 'int', verbatim. + */ +typedef int svn_branch__eid_t; + +typedef struct svn_branch__el_rev_id_t svn_branch__el_rev_id_t; + +typedef struct svn_branch__rev_bid_eid_t svn_branch__rev_bid_eid_t; + +typedef struct svn_branch__rev_bid_t svn_branch__rev_bid_t; + +typedef struct svn_branch__state_t svn_branch__state_t; + +/* Per-repository branching info. + */ +typedef struct svn_branch__repos_t svn_branch__repos_t; + +/* Methods (conceptually public, but called indirectly) for a transaction. + */ +typedef struct svn_branch__txn_vtable_t svn_branch__txn_vtable_t; + +/* Private data for a transaction. + */ +typedef struct svn_branch__txn_priv_t svn_branch__txn_priv_t; + +/* A container for all the branching metadata for a specific revision (or + * an uncommitted transaction). + */ +typedef struct svn_branch__txn_t +{ + /* Methods (conceptually public, but called indirectly). */ + svn_branch__txn_vtable_t *vtable; + + /* Private data. */ + svn_branch__txn_priv_t *priv; + + /* Public data. */ + + /* 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; + +} svn_branch__txn_t; + +/* Create a new branch txn object. + */ +svn_branch__txn_t * +svn_branch__txn_create(const svn_branch__txn_vtable_t *vtable, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool); + +/* Return all the branches in TXN. + * + * These branches are available for reading. (Some of them may also be + * mutable.) + * + * ### Rename to 'list_branches' & return only their ids? + * + * Return an empty array if there are none. + */ +apr_array_header_t * +svn_branch__txn_get_branches(const svn_branch__txn_t *txn, + apr_pool_t *result_pool); + +/* Return the branch whose id is BRANCH_ID in TXN. + * + * 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__txn_get_branch_by_id(const svn_branch__txn_t *txn, + const char *branch_id, + apr_pool_t *scratch_pool); + +svn_error_t * +svn_branch__txn_get_num_new_eids(const svn_branch__txn_t *txn, + int *num_new_eids_p, + apr_pool_t *scratch_pool); + +/* Assign a new txn-scope element id in TXN. + */ +svn_error_t * +svn_branch__txn_new_eid(svn_branch__txn_t *txn, + int *new_eid_p, + apr_pool_t *scratch_pool); + +/** Open for writing, either a new branch or an existing branch. + * + * When creating a new branch, declare its root element id to be ROOT_EID. Do + * not instantiate the root element, nor any other elements. + * + * TREE_REF specifies the initial tree content, by reference to a committed + * tree. It overwrites any existing tree, even if the branch was already + * mutable in the txn. + * + * If TREE_REF is null, then the initial tree is empty for a new branch + * (not already present in the txn), or the branch's current tree if the + * branch was already present (readable or mutable) in the txn. + * + * ### TODO: Take a 'history' parameter; 'none' is a valid option. + * + * We use a common 'open subbranch' method for both 'find' and 'add' + * cases, according to the principle that 'editing' a txn should dictate + * the new state without reference to the old state. + * + * This method returns a mutable 'branch state' object which is a part of + * the txn. + * + * ### When opening ('finding') an existing branch, ROOT_EID should match + * it. (Should we check, and throw an error if not?) + */ +svn_error_t * +svn_branch__txn_open_branch(svn_branch__txn_t *txn, + svn_branch__state_t **new_branch_p, + const char *branch_id, + int root_eid, + svn_branch__rev_bid_eid_t *tree_ref, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Register a sequence point. + * + * At a sequence point, elements are arranged in a tree hierarchy: each + * element has exactly one parent element, except the root, and so on. + * Translation between paths and element addressing is defined only at + * a sequence point. + * + * The other edit operations -- add, alter, delete, etc. -- result in a + * state that is not a sequence point. + * + * The new transaction begins at a sequence point. Completion of editing + * (svn_branch__txn_complete()) also creates a sequence point. + */ +svn_error_t * +svn_branch__txn_sequence_point(svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +/** Finalize this transaction. + * + * Notify that the edit has been completed successfully. + */ +svn_error_t * +svn_branch__txn_complete(svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +/** Abandon this transaction. + * + * Notify that editing this transaction was not successful. + */ +svn_error_t * +svn_branch__txn_abort(svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +/* Change txn-local EIDs (negative integers) in TXN to revision EIDs, by + * assigning a new revision-EID (positive integer) for each one. + * + * Rewrite TXN->first_eid and TXN->next_eid accordingly. + */ +svn_error_t * +svn_branch__txn_finalize_eids(svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +/* Often, branches have the same root element. For example, + * branching /trunk to /branches/br1 results in: + * + * branch 1: (root-EID=100) + * EID 100 => /trunk + * ... + * branch 2: (root-EID=100) + * EID 100 => /branches/br1 + * ... + * + * However, the root element of one branch may correspond to a non-root + * element of another branch. + * + * Continuing the same example, branching from the trunk subtree + * /trunk/D (which is not itself a branch root) results in: + * + * branch 3: (root-EID=104) + * EID 100 => (nil) + * ... + * EID 104 => /branches/branch-of-trunk-subtree-D + * ... + */ + +/* Methods (conceptually public, but called indirectly) for a branch state. + */ +typedef struct svn_branch__state_vtable_t svn_branch__state_vtable_t; + +/* Private data for a branch state. + */ +typedef struct svn_branch__state_priv_t svn_branch__state_priv_t; + +/* A branch state. + * + * A branch state object describes one version of one branch. + */ +struct svn_branch__state_t +{ + /* Methods (conceptually public, but called indirectly). */ + svn_branch__state_vtable_t *vtable; + + /* Private data. */ + svn_branch__state_priv_t *priv; + + /* Public data. */ + + /* The branch identifier (starting with 'B') */ + const char *bid; + + /* The revision to which this branch state belongs */ + /* ### Later we should remove this and let a single state be sharable + by multiple txns. */ + svn_branch__txn_t *txn; + +}; + +/* Create a new branch state object. + */ +svn_branch__state_t * +svn_branch__state_create(const svn_branch__state_vtable_t *vtable, + svn_cancel_func_t cancel_func, + void *cancel_baton, + 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__txn_get_branch_by_id(). + */ +const char * +svn_branch__get_id(const svn_branch__state_t *branch, + apr_pool_t *result_pool); + +/* Return the element id of the root element of BRANCH. + */ +int +svn_branch__root_eid(const svn_branch__state_t *branch); + +/* Return the id of the branch nested in OUTER_BID at element OUTER_EID. + * + * For a top-level branch, OUTER_BID is null and OUTER_EID is the + * top-level branch number. + * + * (Such branches need not exist. This works purely with ids, making use + * of the fact that nested branch ids are predictable based on the nesting + * element id.) + */ +const char * +svn_branch__id_nest(const char *outer_bid, + int outer_eid, + apr_pool_t *result_pool); + +/* Given a nested branch id BID, set *OUTER_BID to the outer branch's id + * and *OUTER_EID to the nesting element in the outer branch. + * + * For a top-level branch, set *OUTER_BID to NULL and *OUTER_EID to the + * top-level branch number. + * + * (Such branches need not exist. This works purely with ids, making use + * of the fact that nested branch ids are predictable based on the nesting + * element id.) + */ +void +svn_branch__id_unnest(const char **outer_bid, + int *outer_eid, + const char *bid, + apr_pool_t *result_pool); + +/* Remove the branch with id BID from the list of branches in TXN. + */ +svn_error_t * +svn_branch__txn_delete_branch(svn_branch__txn_t *txn, + const char *bid, + apr_pool_t *scratch_pool); + +/* Branch-Element-Revision */ +struct svn_branch__el_rev_id_t +{ + /* The branch state that applies to REV. */ + svn_branch__state_t *branch; + /* Element. */ + int eid; + /* Revision. SVN_INVALID_REVNUM means 'in this transaction', not 'head'. + ### Do we need this if BRANCH refers to a particular branch-revision? */ + svn_revnum_t rev; + +}; + +/* Revision-branch-element id. */ +struct svn_branch__rev_bid_eid_t +{ + /* Revision. SVN_INVALID_REVNUM means 'in this transaction', not 'head'. */ + svn_revnum_t rev; + /* The branch id in revision REV. */ + const char *bid; + /* Element id. */ + int eid; + +}; + +/* Revision-branch id. */ +struct svn_branch__rev_bid_t +{ + /* Revision. SVN_INVALID_REVNUM means 'in this transaction', not 'head'. */ + svn_revnum_t rev; + /* The branch id in revision REV. */ + const char *bid; + +}; + +/* Return a new el_rev_id object constructed with *shallow* copies of BRANCH, + * EID and REV, allocated in RESULT_POOL. + */ +svn_branch__el_rev_id_t * +svn_branch__el_rev_id_create(svn_branch__state_t *branch, + int eid, + svn_revnum_t rev, + apr_pool_t *result_pool); + +/* Return a new id object constructed with a deep copy of OLD_ID, + * allocated in RESULT_POOL. */ +svn_branch__el_rev_id_t * +svn_branch__el_rev_id_dup(const svn_branch__el_rev_id_t *old_id, + apr_pool_t *result_pool); + +/* Return a new id object constructed with deep copies of REV, BRANCH_ID + * and EID, allocated in RESULT_POOL. + */ +svn_branch__rev_bid_eid_t * +svn_branch__rev_bid_eid_create(svn_revnum_t rev, + const char *branch_id, + int eid, + apr_pool_t *result_pool); +svn_branch__rev_bid_t * +svn_branch__rev_bid_create(svn_revnum_t rev, + const char *branch_id, + apr_pool_t *result_pool); + +/* Return a new id object constructed with a deep copy of OLD_ID, + * allocated in RESULT_POOL. */ +svn_branch__rev_bid_eid_t * +svn_branch__rev_bid_eid_dup(const svn_branch__rev_bid_eid_t *old_id, + apr_pool_t *result_pool); +svn_branch__rev_bid_t * +svn_branch__rev_bid_dup(const svn_branch__rev_bid_t *old_id, + apr_pool_t *result_pool); + +svn_boolean_t +svn_branch__rev_bid_equal(const svn_branch__rev_bid_t *id1, + const svn_branch__rev_bid_t *id2); + +typedef struct svn_branch__history_t +{ + /* The immediate parents of this state in the branch/merge graph. + Hash of (BID -> svn_branch__rev_bid_t). */ + apr_hash_t *parents; +} svn_branch__history_t; + +svn_branch__history_t * +svn_branch__history_create_empty(apr_pool_t *result_pool); + +svn_branch__history_t * +svn_branch__history_create(apr_hash_t *parents, + apr_pool_t *result_pool); + +svn_branch__history_t * +svn_branch__history_dup(const svn_branch__history_t *old, + apr_pool_t *result_pool); + +/* Return the mapping of elements in branch BRANCH. + */ +svn_error_t * +svn_branch__state_get_elements(const svn_branch__state_t *branch, + svn_element__tree_t **element_tree_p, + apr_pool_t *result_pool); + +/* In BRANCH, get element EID (parent, name, payload). + * + * If element EID is not present, return null. + */ +svn_error_t * +svn_branch__state_get_element(const svn_branch__state_t *branch, + svn_element__content_t **element_p, + int eid, + apr_pool_t *result_pool); + +/** Equivalent to + * alter_one(..., element->parent_eid, element->name, element->payload), + * or, if @a element is null, to + * delete_one(...). + */ +svn_error_t * +svn_branch__state_set_element(svn_branch__state_t *branch, + int eid, + const svn_element__content_t *element, + apr_pool_t *result_pool); + +/** Specify that the element of @a branch identified by @a eid shall not + * be present. + * + * The delete is not explicitly recursive. However, as an effect of the + * final 'flattening' of a branch state into a single tree, each element + * in the final state that still has this element as its parent will also + * be deleted, recursively. + * + * The element @a eid must not be the root element of @a branch. + * + * ### Options for Out-Of-Date Checking on Rebase + * + * We may want to specify what kind of OOD check takes place. The + * following two options differ in what happens to an element that is + * added, on the other side, as a child of this deleted element. + * + * Rebase option 1: The rebase checks for changes in the whole subtree, + * excluding any portions of the subtree for which an explicit delete or + * move-away has been issued. The check includes checking that the other + * side has not added any child. In other words, the deletion is + * interpreted as an action affecting a subtree (dynamically rooted at + * this element), rather than as an action affecting a single element or + * a fixed set of elements that was explicitly or implicitly specified + * by the sender. + * + * To delete a mixed-rev subtree, the client sends an explicit delete for + * each subtree that has a different base revision from its parent. + * + * Rebase option 2: The rebase checks for changes to this element only. + * The sender can send an explicit delete for each existing child element + * that it requires to be checked as well. However, there is no way for + * the sender to specify whether a child element added by the other side + * should be considered an out-of-date error or silently deleted. + * + * It would also be possible to let the caller specify, at some suitable + * granularity, which option to use. + */ +svn_error_t * +svn_branch__state_delete_one(svn_branch__state_t *branch, + svn_branch__eid_t eid, + apr_pool_t *scratch_pool); + +/** Specify the tree position and payload of the element of @a branch + * identified by @a eid. + * + * Set the element's parent EID, name and payload to @a new_parent_eid, + * @a new_name and @a new_payload respectively. + * + * This may create a new element or alter an existing element. + * + * If the element ... we can describe the effect as ... + * + * exists in the branch => altering it; + * previously existed in the branch => resurrecting it; + * only existed in other branches => branching it; + * never existed anywhere => creating or adding it. + * + * However, these are imprecise descriptions and not mutually exclusive. + * For example, if it existed previously in this branch and another, then + * we may describe the result as 'resurrecting' and/or as 'branching'. + * + * Duplicate @a new_name and @a new_payload into the branch's pool. + */ +svn_error_t * +svn_branch__state_alter_one(svn_branch__state_t *branch, + svn_branch__eid_t eid, + svn_branch__eid_t new_parent_eid, + const char *new_name, + const svn_element__payload_t *new_payload, + apr_pool_t *scratch_pool); + +svn_error_t * +svn_branch__state_copy_tree(svn_branch__state_t *branch, + const svn_branch__rev_bid_eid_t *src_el_rev, + svn_branch__eid_t new_parent_eid, + const char *new_name, + apr_pool_t *scratch_pool); + +/* Purge orphaned elements in BRANCH. + */ +svn_error_t * +svn_branch__state_purge(svn_branch__state_t *branch, + apr_pool_t *scratch_pool); + +/* Get the merge history of BRANCH. + */ +svn_error_t * +svn_branch__state_get_history(svn_branch__state_t *branch, + svn_branch__history_t **merge_history_p, + apr_pool_t *result_pool); + +/* Set the merge history of BRANCH. + */ +svn_error_t * +svn_branch__state_set_history(svn_branch__state_t *branch, + const svn_branch__history_t *merge_history, + apr_pool_t *scratch_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 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); + +/* 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 txn object *TXN_P, initialized with info + * parsed from STREAM, allocated in RESULT_POOL. + */ +svn_error_t * +svn_branch__txn_parse(svn_branch__txn_t **txn_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 TXN. + */ +svn_error_t * +svn_branch__txn_serialize(svn_branch__txn_t *txn, + svn_stream_t *stream, + 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 */ diff --git a/subversion/include/private/svn_branch_compat.h b/subversion/include/private/svn_branch_compat.h new file mode 100644 index 000000000000..8c7d0b2a04dc --- /dev/null +++ b/subversion/include/private/svn_branch_compat.h @@ -0,0 +1,273 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_branch_compat.h + * @brief Compatibility with svn_delta_editor_t etc. + * + * @since New in ???. + */ + +#ifndef SVN_BRANCH_COMPAT_H +#define SVN_BRANCH_COMPAT_H + +#include <apr_pools.h> + +#include "svn_types.h" +#include "svn_error.h" +#include "svn_delta.h" +#include "svn_ra.h" +#include "private/svn_branch.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** Callback to retrieve a node's kind and content. This is + * needed by the various editor shims in order to effect backwards + * compatibility. + * + * Implementations should set @a *kind to the node kind of @a repos_relpath + * in @a revision. + * + * Implementations should set @a *props to the hash of properties + * associated with @a repos_relpath in @a revision, allocating that hash + * and its contents in @a result_pool. Only the 'regular' props should be + * included, not special props such as 'entry props'. + * + * Implementations should set @a *filename to the name of a file + * suitable for use as a delta base for @a repos_relpath in @a revision + * (allocating @a *filename from @a result_pool), or to @c NULL if the + * base stream is empty. + * + * Any output argument may be NULL if the output is not wanted. + * + * @a baton is an implementation-specific closure. + * @a repos_relpath is relative to the repository root. + * The implementation should ensure that @a new_content, including any + * file therein, lives at least for the life time of @a result_pool. + * @a scratch_pool is provided for temporary allocations. + */ +typedef svn_error_t *(*svn_branch__compat_fetch_func_t)( + svn_node_kind_t *kind, + apr_hash_t **props, + svn_stringbuf_t **file_text, + apr_hash_t **children_names, + void *baton, + const char *repos_relpath, + svn_revnum_t revision, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool + ); + +/* + */ +svn_error_t * +svn_branch__compat_fetch(svn_element__payload_t **payload_p, + svn_branch__txn_t *txn, + svn_element__branch_ref_t branch_ref, + svn_branch__compat_fetch_func_t fetch_func, + void *fetch_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* An object for communicating out-of-band details between an Ev1-to-Ev3 + * shim and an Ev3-to-Ev1 shim. */ +typedef struct svn_branch__compat_shim_connector_t svn_branch__compat_shim_connector_t; + +/* Return an Ev3 editor in *EDITOR_P which will drive the Ev1 delta + * editor DEDITOR/DEDIT_BATON. + * + * This editor buffers all the changes and then drives the Ev1 when the + * returned editor's "close" method is called. + * + * This editor converts moves into copy-and-delete. It presently makes a + * one-way (lossy) conversion. + * + * TODO: Option to pass the 'move' information through as some sort of + * metadata so that it can be preserved in an Ev3-Ev1-Ev3 round-trip + * conversion. + * - Use 'entry-props'? + * - Send copy-and-delete with copy-from-rev = -1? + * + * This editor implements the "independent per-element changes" variant + * of the Ev3 commit editor interface. + * + * Use *BRANCHING_TXN as the branching state info ... + * + * SHIM_CONNECTOR can be used to enable a more exact round-trip conversion + * from an Ev1 drive to Ev3 and back to Ev1. The caller should pass the + * returned *SHIM_CONNECTOR value to svn_delta__delta_from_ev3_for_commit(). + * SHIM_CONNECTOR may be null if not wanted. + * + * REPOS_ROOT_URL is the repository root URL. + * + * FETCH_FUNC/FETCH_BATON is a callback by which the shim may retrieve the + * original or copy-from kind/properties/text for a path being committed. + * + * CANCEL_FUNC / CANCEL_BATON: The usual cancellation callback; folded + * into the produced editor. May be NULL/NULL if not wanted. + * + * Allocate the new editor in RESULT_POOL, which may become large and must + * live for the lifetime of the edit. Use SCRATCH_POOL for temporary + * allocations. + */ +svn_error_t * +svn_branch__compat_txn_from_delta_for_commit( + svn_branch__txn_t **txn_p, + svn_branch__compat_shim_connector_t **shim_connector, + const svn_delta_editor_t *deditor, + void *dedit_baton, + svn_branch__txn_t *branching_txn, + const char *repos_root_url, + svn_branch__compat_fetch_func_t fetch_func, + void *fetch_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Return a delta editor in DEDITOR/DEDITOR_BATON which will drive EDITOR. + * + * REPOS_ROOT_URL is the repository root URL, and BASE_RELPATH is the + * relative path within the repository of the root directory of the edit. + * (An Ev1 edit must be rooted at a directory, not at a file.) + * + * FETCH_FUNC/FETCH_BATON is a callback by which the shim may retrieve the + * original or copy-from kind/properties/text for a path being committed. + * + * SHIM_CONNECTOR can be used to enable a more exact round-trip conversion + * from an Ev1 drive to Ev3 and back to Ev1. It must live for the lifetime + * of the edit. It may be null if not wanted. + * + * Allocate the new editor in RESULT_POOL, which may become large and must + * live for the lifetime of the edit. Use SCRATCH_POOL for temporary + * allocations. + */ +svn_error_t * +svn_branch__compat_delta_from_txn_for_commit( + const svn_delta_editor_t **deditor, + void **dedit_baton, + svn_branch__txn_t *edit_txn, + const char *repos_root_url, + const char *base_relpath, + svn_branch__compat_fetch_func_t fetch_func, + void *fetch_baton, + const svn_branch__compat_shim_connector_t *shim_connector, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Return in NEW_DEDITOR/NEW_DETIT_BATON a delta editor that wraps + * OLD_DEDITOR/OLD_DEDIT_BATON, inserting a pair of shims that convert + * Ev1 to Ev3 and back to Ev1. + * + * REPOS_ROOT_URL is the repository root URL, and BASE_RELPATH is the + * relative path within the repository of the root directory of the edit. + * + * FETCH_FUNC/FETCH_BATON is a callback by which the shim may retrieve the + * original or copy-from kind/properties/text for a path being committed. + */ +svn_error_t * +svn_branch__compat_insert_shims( + const svn_delta_editor_t **new_deditor, + void **new_dedit_baton, + const svn_delta_editor_t *old_deditor, + void *old_dedit_baton, + const char *repos_root, + const char *base_relpath, + svn_branch__compat_fetch_func_t fetch_func, + void *fetch_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* A callback for declaring the target revision of an update or switch. + */ +typedef svn_error_t *(*svn_branch__compat_set_target_revision_func_t)( + void *baton, + svn_revnum_t target_revision, + apr_pool_t *scratch_pool); + +/* An update (or switch) editor. + * + * This consists of a plain Ev3 editor and the additional methods or + * resources needed for use as an update or switch editor. + */ +typedef struct svn_branch__compat_update_editor3_t { + /* The txn we're driving. */ + svn_branch__txn_t *edit_txn; + + /* A method to communicate the target revision of the update (or switch), + * to be called before driving the editor. It has its own baton, rather + * than using the editor's baton, so that the editor can be replaced (by + * a wrapper editor, typically) without having to wrap this callback. */ + svn_branch__compat_set_target_revision_func_t set_target_revision_func; + void *set_target_revision_baton; +} svn_branch__compat_update_editor3_t; + +/* Like svn_delta__ev3_from_delta_for_commit() but for an update editor. + */ +svn_error_t * +svn_branch__compat_txn_from_delta_for_update( + svn_branch__compat_update_editor3_t **editor_p, + const svn_delta_editor_t *deditor, + void *dedit_baton, + svn_branch__txn_t *branching_txn, + const char *repos_root_url, + const char *base_repos_relpath, + svn_branch__compat_fetch_func_t fetch_func, + void *fetch_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Like svn_delta__delta_from_ev3_for_commit() but for an update editor. + */ +svn_error_t * +svn_branch__compat_delta_from_txn_for_update( + const svn_delta_editor_t **deditor, + void **dedit_baton, + svn_branch__compat_update_editor3_t *update_editor, + const char *repos_root_url, + const char *base_repos_relpath, + svn_branch__compat_fetch_func_t fetch_func, + void *fetch_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* An Ev1 editor that drives (heuristically) a move-tracking editor. + */ +svn_error_t * +svn_branch__compat_get_migration_editor( + const svn_delta_editor_t **old_editor, + void **old_edit_baton, + svn_branch__txn_t *edit_txn, + svn_ra_session_t *from_session, + svn_revnum_t revision, + apr_pool_t *result_pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_BRANCH_COMPAT_H */ diff --git a/subversion/include/private/svn_branch_impl.h b/subversion/include/private/svn_branch_impl.h new file mode 100644 index 000000000000..ad4df3b1b12d --- /dev/null +++ b/subversion/include/private/svn_branch_impl.h @@ -0,0 +1,197 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_branch_impl.h + * @brief Declarations needed by implementators of branch classes + * + * @since New in ???. + */ + +#ifndef SVN_BRANCH_IMPL_H +#define SVN_BRANCH_IMPL_H + +#include "private/svn_branch.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Common aspects od a txn/branch 'editor' class (derived from Ev2) */ +typedef struct svn_branch__vtable_priv_t +{ + /* Standard cancellation function. Called before each callback. */ + svn_cancel_func_t cancel_func; + void *cancel_baton; + +#ifdef ENABLE_ORDERING_CHECK + svn_boolean_t within_callback; + svn_boolean_t finished; + apr_pool_t *state_pool; +#endif + +} svn_branch__vtable_priv_t; + +/* The methods of svn_branch__txn_t. + * See the corresponding public API functions for details. + */ + +typedef apr_array_header_t *(*svn_branch__txn_v_get_branches_t)( + const svn_branch__txn_t *txn, + apr_pool_t *result_pool); + +typedef svn_error_t *(*svn_branch__txn_v_delete_branch_t)( + svn_branch__txn_t *txn, + const char *bid, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_get_num_new_eids_t)( + const svn_branch__txn_t *txn, + int *num_new_eids_p, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_new_eid_t)( + svn_branch__txn_t *txn, + svn_branch__eid_t *eid_p, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_open_branch_t)( + svn_branch__txn_t *txn, + svn_branch__state_t **new_branch_p, + const char *new_branch_id, + int root_eid, + svn_branch__rev_bid_eid_t *from, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_finalize_eids_t)( + svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_serialize_t)( + svn_branch__txn_t *txn, + svn_stream_t *stream, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_sequence_point_t)( + svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_complete_t)( + svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__txn_v_abort_t)( + svn_branch__txn_t *txn, + apr_pool_t *scratch_pool); + +struct svn_branch__txn_vtable_t +{ + svn_branch__vtable_priv_t vpriv; + + /* Methods. */ + svn_branch__txn_v_get_branches_t get_branches; + svn_branch__txn_v_delete_branch_t delete_branch; + svn_branch__txn_v_get_num_new_eids_t get_num_new_eids; + svn_branch__txn_v_new_eid_t new_eid; + svn_branch__txn_v_open_branch_t open_branch; + svn_branch__txn_v_finalize_eids_t finalize_eids; + svn_branch__txn_v_serialize_t serialize; + svn_branch__txn_v_sequence_point_t sequence_point; + svn_branch__txn_v_complete_t complete; + svn_branch__txn_v_complete_t abort; + +}; + +/* The methods of svn_branch__state_t. + * See the corresponding public API functions for details. + */ + +typedef svn_error_t *(*svn_branch__state_v_get_elements_t)( + const svn_branch__state_t *branch, + svn_element__tree_t **element_tree_p, + apr_pool_t *result_pool); + +typedef svn_error_t *(*svn_branch__state_v_get_element_t)( + const svn_branch__state_t *branch, + svn_element__content_t **element_p, + int eid, + apr_pool_t *result_pool); + +typedef svn_error_t *(*svn_branch__state_v_set_element_t)( + svn_branch__state_t *branch, + svn_branch__eid_t eid, + const svn_element__content_t *element, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__state_v_copy_one_t)( + svn_branch__state_t *branch, + const svn_branch__rev_bid_eid_t *src_el_rev, + svn_branch__eid_t local_eid, + svn_branch__eid_t new_parent_eid, + const char *new_name, + const svn_element__payload_t *new_payload, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__state_v_copy_tree_t)( + svn_branch__state_t *branch, + const svn_branch__rev_bid_eid_t *src_el_rev, + svn_branch__eid_t new_parent_eid, + const char *new_name, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__state_v_purge_t)( + svn_branch__state_t *branch, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__state_v_get_history_t)( + svn_branch__state_t *branch, + svn_branch__history_t **history_p, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_branch__state_v_set_history_t)( + svn_branch__state_t *branch, + const svn_branch__history_t *history, + apr_pool_t *scratch_pool); + +struct svn_branch__state_vtable_t +{ + svn_branch__vtable_priv_t vpriv; + + svn_branch__state_v_get_elements_t get_elements; + svn_branch__state_v_get_element_t get_element; + svn_branch__state_v_set_element_t set_element; + svn_branch__state_v_copy_one_t copy_one; + svn_branch__state_v_copy_tree_t copy_tree; + svn_branch__state_v_purge_t purge; + svn_branch__state_v_get_history_t get_history; + svn_branch__state_v_set_history_t set_history; + +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* SVN_BRANCH_IMPL_H */ + diff --git a/subversion/include/private/svn_branch_nested.h b/subversion/include/private/svn_branch_nested.h new file mode 100644 index 000000000000..5f262739b092 --- /dev/null +++ b/subversion/include/private/svn_branch_nested.h @@ -0,0 +1,216 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_branch_nested.h + * @brief Nested branches and subbranch-root elements + * + * @since New in ???. + */ + +#ifndef SVN_BRANCH_NESTED_H +#define SVN_BRANCH_NESTED_H + +#include <apr_pools.h> + +#include "svn_types.h" + +#include "private/svn_branch.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* + */ +void +svn_branch__get_outer_branch_and_eid(svn_branch__state_t **outer_branch_p, + int *outer_eid_p, + const svn_branch__state_t *branch, + apr_pool_t *scratch_pool); + +/* Return the root repos-relpath of BRANCH. + * + * ### TODO: Clarify sequencing requirements. + */ +const char * +svn_branch__get_root_rrpath(const svn_branch__state_t *branch, + 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 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. + */ +svn_error_t * +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); + +/* 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); + +/* Set *SUBBRANCHES_P an array of pointers to the branches that are immediate + * sub-branches of BRANCH. + */ +svn_error_t * +svn_branch__get_immediate_subbranches(svn_branch__state_t *branch, + apr_array_header_t **subbranches_p, + 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_error_t * +svn_branch__get_subbranch_at_eid(svn_branch__state_t *branch, + svn_branch__state_t **subbranch_p, + int eid, + apr_pool_t *scratch_pool); + +/* A subtree of a branch, including any nested branches. + */ +typedef struct svn_branch__subtree_t +{ + svn_branch__rev_bid_t *predecessor; + + /* EID -> svn_element__content_t mapping. */ + svn_element__tree_t *tree; + + /* 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 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_error_t * +svn_branch__get_subtree(svn_branch__state_t *branch, + svn_branch__subtree_t **subtree_p, + int 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); + +/* Instantiate elements in a branch. + * + * In TO_BRANCH, instantiate (or alter, if existing) each element of + * ELEMENTS, each with its given tree structure (parent, name) and payload. + * + * Also branch the subbranches in ELEMENTS, creating corresponding new + * subbranches in TO_BRANCH, recursively. + */ +svn_error_t * +svn_branch__instantiate_elements_r(svn_branch__state_t *to_branch, + svn_branch__subtree_t elements, + apr_pool_t *scratch_pool); + +/* Create a branch txn object that implements nesting, and wraps a plain + * branch txn (that doesn't support nesting) WRAPPED_TXN. + */ +svn_branch__txn_t * +svn_branch__nested_txn_create(svn_branch__txn_t *wrapped_txn, + apr_pool_t *result_pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_BRANCH_NESTED_H */ diff --git a/subversion/include/private/svn_branch_repos.h b/subversion/include/private/svn_branch_repos.h new file mode 100644 index 000000000000..663d017ebf36 --- /dev/null +++ b/subversion/include/private/svn_branch_repos.h @@ -0,0 +1,104 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_branch_repos.h + * @brief Operating on a repository + * + * @since New in ???. + */ + + +#ifndef SVN_BRANCH_REPOS_H +#define SVN_BRANCH_REPOS_H + +#include <apr_pools.h> + +#include "svn_types.h" + +#include "private/svn_branch.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* 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__txn_t *rev_root); + +/* Return a pointer to revision REVNUM of the repository REPOS. + */ +struct svn_branch__txn_t * +svn_branch__repos_get_revision(const svn_branch__repos_t *repos, + svn_revnum_t revnum); + +/* Return the revision root that represents the base revision (or, + * potentially, txn) of the revision or txn REV_ROOT. + */ +svn_branch__txn_t * +svn_branch__repos_get_base_revision_root(svn_branch__txn_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. + */ +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); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_BRANCH_REPOS_H */ diff --git a/subversion/include/private/svn_cache.h b/subversion/include/private/svn_cache.h index 166295d6ce90..bedd0a8bfaf0 100644 --- a/subversion/include/private/svn_cache.h +++ b/subversion/include/private/svn_cache.h @@ -356,7 +356,12 @@ svn_cache__membuffer_cache_create(svn_membuffer_t **cache, * * If @a thread_safe is true, and APR is compiled with threads, all * accesses to the cache will be protected with a mutex, if the shared - * @a memcache has also been created with thread_safe flag set. + * @a membuffer has also been created with thread_safe flag set. + * + * If @a short_lived is set, assume that the data stored through this + * cache will probably only be needed for a short period of time. + * Typically, some UUID is used as part of the prefix in that scenario. + * This flag is a mere hint and does not affect functionality. * * These caches do not support svn_cache__iter. */ @@ -369,10 +374,24 @@ svn_cache__create_membuffer_cache(svn_cache__t **cache_p, const char *prefix, apr_uint32_t priority, svn_boolean_t thread_safe, + svn_boolean_t short_lived, apr_pool_t *result_pool, apr_pool_t *scratch_pool); /** + * Creates a null-cache instance in @a *cache_p, allocated from + * @a result_pool. The given @c id is the only data stored in it and can + * be retrieved through svn_cache__get_info(). + * + * The cache object will immediately evict (reject) any data being added + * to it and will always report as empty. + */ +svn_error_t * +svn_cache__create_null(svn_cache__t **cache_p, + const char *id, + apr_pool_t *result_pool); + +/** * Sets @a handler to be @a cache's error handling routine. If any * error is returned from a call to svn_cache__get or svn_cache__set, @a * handler will be called with @a baton and the error, and the diff --git a/subversion/include/private/svn_cmdline_private.h b/subversion/include/private/svn_cmdline_private.h index f21a5d2e911b..ac5fb7b07924 100644 --- a/subversion/include/private/svn_cmdline_private.h +++ b/subversion/include/private/svn_cmdline_private.h @@ -63,6 +63,7 @@ svn_cmdline__print_xml_prop(svn_stringbuf_t **outstr, * Expects a @c svn_cmdline_prompt_baton2_t to be passed as @a baton. * * @since New in 1.6. + * @deprecated Only used by old libgome-keyring implementation. */ svn_error_t * svn_cmdline__auth_gnome_keyring_unlock_prompt(char **keyring_password, @@ -88,7 +89,7 @@ typedef struct svn_cmdline__config_argument_t * containing svn_cmdline__config_argument_t* elements, allocating the option * data in @a pool * - * [Since 1.9/1.10:] If the file, section, or option value is not recognized, + * [Since 1.9:] If the file, section, or option value is not recognized, * warn to @c stderr, using @a prefix as in svn_handle_warning2(). * * @since New in 1.7. @@ -213,6 +214,18 @@ svn_cmdline__getopt_init(apr_getopt_t **os, const char *argv[], apr_pool_t *pool); +/* */ +svn_boolean_t +svn_cmdline__stdin_is_a_terminal(void); + +/* */ +svn_boolean_t +svn_cmdline__stdout_is_a_terminal(void); + +/* */ +svn_boolean_t +svn_cmdline__stderr_is_a_terminal(void); + /* Determine whether interactive mode should be enabled, based on whether * the user passed the --non-interactive or --force-interactive options. * If neither option was passed, interactivity is enabled if standard @@ -239,6 +252,32 @@ svn_cmdline__parse_trust_options( const char *opt_arg, apr_pool_t *scratch_pool); +/* Setup signal handlers for signals such as SIGINT and return a + cancellation handler function. This also sets some other signals + to be ignored. */ +svn_cancel_func_t +svn_cmdline__setup_cancellation_handler(void); + +/* Set the handlers for signals such as SIGINT back to default. */ +void +svn_cmdline__disable_cancellation_handler(void); + +/* Exit this process with a status that indicates the cancellation + signal, or return without exiting if there is no signal. This + allows the shell to use WIFSIGNALED and WTERMSIG to detect the + signal. See http://www.cons.org/cracauer/sigint.html */ +void +svn_cmdline__cancellation_exit(void); + +/** Reads a string from stdin until a newline or EOF is found + * + * @since New in 1.10. + */ +svn_error_t * +svn_cmdline__stdin_readline(const char **result, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_config_private.h b/subversion/include/private/svn_config_private.h new file mode 100644 index 000000000000..95cca27b20f9 --- /dev/null +++ b/subversion/include/private/svn_config_private.h @@ -0,0 +1,129 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_config_private.h + * @brief Private config file parsing API. + */ + +#ifndef SVN_CONFIG_PRIVATE_H +#define SVN_CONFIG_PRIVATE_H + +#include <apr_pools.h> + +#include "svn_error.h" +#include "svn_io.h" +#include "svn_string.h" +#include "svn_config.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Description of a constructor for in-memory config file + * representations. + */ +typedef struct svn_config__constructor_t svn_config__constructor_t; + +/* + * Constructor callback: called when the parsing of a new SECTION + * begins. If the implementation stores the value of SECTION, it + * must copy it into a permanent pool. + * + * May return SVN_ERR_CEASE_INVOCATION to stop further parsing. + */ +typedef svn_error_t *(*svn_config__open_section_fn)( + void *baton, svn_stringbuf_t *section); + +/* + * Constructor callback: called when the parsing of SECTION ends. If + * the implementation stores the value of SECTION, it must copy it + * into a permanent pool. + * + * May return SVN_ERR_CEASE_INVOCATION to stop further parsing. + */ +typedef svn_error_t *(*svn_config__close_section_fn)( + void *baton, svn_stringbuf_t *section); + +/* + * Constructor callback: called OPTION with VALUE in SECTION was + * parsed. If the implementation stores the values of SECTION, OPTION + * or VALUE, it must copy them into a permanent pool. + * + * May return SVN_ERR_CEASE_INVOCATION to stop further parsing. + */ +typedef svn_error_t *(*svn_config__add_value_fn)( + void *baton, svn_stringbuf_t *section, + svn_stringbuf_t *option, svn_stringbuf_t *value); + + +/* + * Create a new constuctor allocated from RESULT_POOL. + * Any of the callback functions may be NULL. + * The constructor implementation is responsible for implementing any + * case-insensitivity, value expansion, or other features on top of + * the basic parser. + */ +svn_config__constructor_t * +svn_config__constructor_create( + svn_config__open_section_fn open_section_callback, + svn_config__close_section_fn close_section_callback, + svn_config__add_value_fn add_value_callback, + apr_pool_t *result_pool); + +/* + * Parse the configuration from STREAM, using CONSTRUCTOR to build the + * in-memory representation of the parsed configuration. + * CONSTRUCTOR_BATON is passed unchanged to the constructor + * callbacks. The parser guarantees that sections and options will be + * passed to the callback in the same order as they're defined in + * STREAM. + * + * The lifetome of section names, option names and values passed to + * the constructor does not extend past the invocation of each + * callback; see calback docs, above. + * + * The parser will use SCRATCH_POOL for its own allocations. + */ +svn_error_t * +svn_config__parse_stream(svn_stream_t *stream, + svn_config__constructor_t *constructor, + void *constructor_baton, + apr_pool_t *scratch_pool); + +/* + * Write the configuration CFG to STREAM, using SCRATCH_POOL for + * temporary allocations. + * + * Note that option values will not be expanded and that the order + * of sections as well as the options within them is undefined. + */ +svn_error_t * +svn_config__write(svn_stream_t *stream, + const svn_config_t *cfg, + apr_pool_t *scratch_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_CONFIG_PRIVATE_H */ diff --git a/subversion/include/private/svn_delta_private.h b/subversion/include/private/svn_delta_private.h index 260327c43c69..fbf66e1be7b7 100644 --- a/subversion/include/private/svn_delta_private.h +++ b/subversion/include/private/svn_delta_private.h @@ -108,6 +108,25 @@ svn_txdelta__read_raw_window_len(apr_size_t *window_len, svn_stream_t *stream, apr_pool_t *pool); +/* Return a debug editor that wraps @a wrapped_editor. + * + * The debug editor simply prints an indication of what callbacks are being + * called to @c stdout, and is only intended for use in debugging subversion + * editors. + * + * @a prefix, if non-null, is printed between "DBG: " and each indication. + * + * Note: Our test suite generally ignores stdout lines starting with "DBG:". + */ +svn_error_t * +svn_delta__get_debug_editor(const svn_delta_editor_t **editor, + void **edit_baton, + const svn_delta_editor_t *wrapped_editor, + void *wrapped_baton, + const char *prefix, + apr_pool_t *pool); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_dep_compat.h b/subversion/include/private/svn_dep_compat.h index 729cf7e4df11..6b381d2ce81c 100644 --- a/subversion/include/private/svn_dep_compat.h +++ b/subversion/include/private/svn_dep_compat.h @@ -75,6 +75,27 @@ extern "C" { #endif /** + * Indicate whether we are running on a POSIX platform. This has + * implications on the way e.g. fsync() works. + * + * For details on this check, see + * http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system#POSIX + * + * @since New in 1.10. + */ +#ifndef SVN_ON_POSIX +#if !defined(_WIN32) \ + && ( defined(__unix__) \ + || defined(__unix) \ + || (defined(__APPLE__) && defined(__MACH__))) /* UNIX-style OS? */ +# include <unistd.h> +# if defined(_POSIX_VERSION) +# define SVN_ON_POSIX +# endif +#endif +#endif + +/** * APR keeps a few interesting defines hidden away in its private * headers apr_arch_file_io.h, so we redefined them here. * @@ -94,6 +115,28 @@ extern "C" { #endif /** + * APR 1 has volatile qualifier bugs in some atomic prototypes that + * are fixed in APR 2: + * https://issues.apache.org/bugzilla/show_bug.cgi?id=50731 + * Subversion code should put the volatile qualifier in the correct + * place when declaring variables which means that casting at the call + * site is necessary when using APR 1. No casts should be used with + * APR 2 as this allows the compiler to check that the variable has + * the correct volatile qualifier. + */ +#if APR_VERSION_AT_LEAST(2,0,0) +#define svn_atomic_casptr(mem, with, cmp) \ + apr_atomic_casptr((mem), (with), (cmp)) +#define svn_atomic_xchgptr(mem, val) \ + apr_atomic_xchgptr((mem), (val)) +#else +#define svn_atomic_casptr(mem, with, cmp) \ + apr_atomic_casptr((void volatile **)(mem), (with), (cmp)) +#define svn_atomic_xchgptr(mem, val) \ + apr_atomic_xchgptr((void volatile **)(mem), (val)) +#endif + +/** * Check at compile time if the Serf version is at least a certain * level. * @param major The major version component of the version checked diff --git a/subversion/include/private/svn_diff_private.h b/subversion/include/private/svn_diff_private.h index 48b4d5266200..bf7f490d37e9 100644 --- a/subversion/include/private/svn_diff_private.h +++ b/subversion/include/private/svn_diff_private.h @@ -113,6 +113,40 @@ svn_diff__display_prop_diffs(svn_stream_t *outstream, void *cancel_baton, apr_pool_t *scratch_pool); +/** Create a hunk object that adds a single line without newline. Return the + * new object in @a *hunk. + * + * @a line is the added text, without a trailing newline. + * + * The hunk will be associated with @a patch. + */ +svn_error_t * +svn_diff_hunk__create_adds_single_line(svn_diff_hunk_t **hunk, + const char *line, + const svn_patch_t *patch, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Create a hunk object that deletes a single line without newline. Return + * the new object in @a *hunk. + * + * @a line is the deleted text, without a trailing newline. + * + * The hunk will be associated with @a patch. + */ +svn_error_t * +svn_diff_hunk__create_deletes_single_line(svn_diff_hunk_t **hunk, + const char *line, + const svn_patch_t *patch, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Fetches the penalty fuzz of the diff hunk. The patch file parser applies + * an additional penalty on some cases of bad patch files. These cases may + * include errors as headers that aren't consistent with bodies, etc. + */ +svn_linenum_t +svn_diff_hunk__get_fuzz_penalty(const svn_diff_hunk_t *hunk); #ifdef __cplusplus } diff --git a/subversion/include/private/svn_diff_tree.h b/subversion/include/private/svn_diff_tree.h index 4554da2b47c9..713644d08c4e 100644 --- a/subversion/include/private/svn_diff_tree.h +++ b/subversion/include/private/svn_diff_tree.h @@ -114,12 +114,24 @@ extern "C" { * ### How come many users don't set the 'repos_relpath' field? */ typedef struct svn_diff_source_t { - /* Always available */ + /* Always available + In case of copyfrom: the revision copied from + */ svn_revnum_t revision; - /* Depending on the driver available for copyfrom */ - /* ### What? */ + /* In case of copyfrom: the repository relative path copied from. + + NULL if the node wasn't copied or moved, or when the driver doesn't + have this information */ const char *repos_relpath; + + /* In case of copyfrom: the relative path of source location before the + move. This path is relative WITHIN THE DIFF. The repository path is + typically in repos_relpath + + NULL if the node wasn't moved or if the driver doesn't have this + information. */ + const char *moved_from_relpath; } svn_diff_source_t; /** diff --git a/subversion/include/private/svn_element.h b/subversion/include/private/svn_element.h new file mode 100644 index 000000000000..c467175c748e --- /dev/null +++ b/subversion/include/private/svn_element.h @@ -0,0 +1,399 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_element.h + * @brief Tree elements + * + * @since New in ???. + */ + +#ifndef SVN_BRANCH_ELEMENT_H +#define SVN_BRANCH_ELEMENT_H + +#include <apr_pools.h> +#include <apr_tables.h> + +#include "svn_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* ====================================================================== */ + +/** Like apr_hash_get() but the hash key is an integer. */ +void * +svn_eid__hash_get(apr_hash_t *ht, + int key); + +/** Like apr_hash_set() but the hash key is an integer. */ +void +svn_eid__hash_set(apr_hash_t *ht, + int key, + const void *val); + +/** Like apr_hash_this_key() but the hash key is an integer. */ +int +svn_eid__hash_this_key(apr_hash_index_t *hi); + +struct svn_sort__item_t; + +/** A hash iterator for iterating over an array or a hash table in + * its natural order or in sorted order. + * + * For an array, the @a i and @a val members provide the index and value + * of the current item. + */ +typedef struct svn_eid__hash_iter_t +{ + /* private: an array of (svn_sort__item_t) hash items for sorted iteration */ + const apr_array_header_t *array; + + /* current element: iteration order index */ + int i; + /* current element: key */ + int eid; + /* current element: value */ + void *val; +} svn_eid__hash_iter_t; + +svn_eid__hash_iter_t * +svn_eid__hash_sorted_first(apr_pool_t *pool, + apr_hash_t *ht, + int (*comparison_func)(const struct svn_sort__item_t *, + const struct svn_sort__item_t *)); + +svn_eid__hash_iter_t * +svn_eid__hash_sorted_next(svn_eid__hash_iter_t *hi); + +/** A sort ordering callback function that returns an indication whether + * A sorts before or after or equal to B, by comparing their keys as EIDs. + */ +int +svn_eid__hash_sort_compare_items_by_eid(const struct svn_sort__item_t *a, + const struct svn_sort__item_t *b); + +#define SVN_EID__HASH_ITER_SORTED(i, ht, comparison_func, pool) \ + i = (void *)svn_eid__hash_sorted_first(pool, ht, comparison_func); \ + i; \ + i = (void *)svn_eid__hash_sorted_next((void *)i) + +#define SVN_EID__HASH_ITER_SORTED_BY_EID(i, ht, pool) \ + SVN_EID__HASH_ITER_SORTED(i, ht, svn_eid__hash_sort_compare_items_by_eid, pool) + + +/* ====================================================================== */ + +/** + */ +typedef struct svn_element__branch_ref_t +{ + svn_revnum_t rev; + const char *branch_id; + int eid; +} svn_element__branch_ref_t; + +/** Versioned payload of an element, excluding tree structure information. + * + * This specifies the properties and the text of a file or target of a + * symlink, directly, or by reference to an existing committed element, or + * by a delta against such a reference payload. + * + * ### An idea: If the sender and receiver agree, the payload for an element + * may be specified as "null" to designate that the payload is not + * available. For example, when a client performing a WC update has + * no read authorization for a given path, the server may send null + * payload and the client may record an 'absent' WC node. (This + * would not make sense in a commit.) + */ +typedef struct svn_element__payload_t svn_element__payload_t; + +/* + * ======================================================================== + * Element Payload Interface + * ======================================================================== + * + * @defgroup svn_element_payload Element payload interface + * @{ + */ + +/** Versioned payload of a node, excluding tree structure information. + * + * Payload is described by setting fields in one of the following ways. + * Other fields SHOULD be null (or equivalent). + * + * by reference: (kind=unknown, ref) + * dir: (kind=dir, props) + * file: (kind=file, props, text) + * symlink: (kind=symlink, props, target) + * + * ### Idea for the future: Specify payload as an (optional) reference + * plus (optional) overrides or deltas against the reference? + */ +struct svn_element__payload_t +{ + /* Is this a subbranch-root element, in other words a link to a nested + * branch? If so, all other fields are irrelevant. */ + svn_boolean_t is_subbranch_root; + + /* The node kind for this payload: dir, file, symlink, or unknown. */ + svn_node_kind_t kind; + + /* Reference an existing, committed payload. (Use with kind=unknown if + * there is no content in props/text/targe fields.) + * The 'null' value is (SVN_INVALID_REVNUM, NULL, *). */ + svn_element__branch_ref_t branch_ref; + + /* The pool in which the payload's content is allocated. Used when + * resolving (populating the props/text/target in) a payload that was + * originally defined by reference. */ + apr_pool_t *pool; + + /* Properties (for kind != unknown). + * Maps (const char *) name -> (svn_string_t) value. + * An empty hash means no properties. (SHOULD NOT be NULL.) + * ### Presently NULL means 'no change' in some contexts. */ + apr_hash_t *props; + + /* File text (for kind=file; otherwise SHOULD be NULL). */ + svn_stringbuf_t *text; + + /* Symlink target (for kind=symlink; otherwise SHOULD be NULL). */ + const char *target; + +}; + +/* Return true iff PAYLOAD satisfies all its invariants. + */ +svn_boolean_t +svn_element__payload_invariants(const svn_element__payload_t *payload); + +/** Duplicate a node-payload @a old into @a result_pool. + */ +svn_element__payload_t * +svn_element__payload_dup(const svn_element__payload_t *old, + apr_pool_t *result_pool); + +/* Return true iff the payload of LEFT is identical to that of RIGHT. + * References are not supported. Node kind 'unknown' is not supported. + */ +svn_boolean_t +svn_element__payload_equal(const svn_element__payload_t *left, + const svn_element__payload_t *right, + apr_pool_t *scratch_pool); + +/** Create a new node-payload object for a subbranch-root (link to a + * nested branch). + * + * Allocate the result in @a result_pool. + */ +svn_element__payload_t * +svn_element__payload_create_subbranch(apr_pool_t *result_pool); + +/** Create a new node-payload object by reference to an existing payload. + * + * Set the node kind to 'unknown'. + * + * Allocate the result in @a result_pool. + */ +svn_element__payload_t * +svn_element__payload_create_ref(svn_revnum_t rev, + const char *branch_id, + int eid, + apr_pool_t *result_pool); + +/** Create a new node-payload object for a directory node. + * + * Allocate the result in @a result_pool. + */ +svn_element__payload_t * +svn_element__payload_create_dir(apr_hash_t *props, + apr_pool_t *result_pool); + +/** Create a new node-payload object for a file node. + * + * Allocate the result in @a result_pool. + */ +svn_element__payload_t * +svn_element__payload_create_file(apr_hash_t *props, + svn_stringbuf_t *text, + apr_pool_t *result_pool); + +/** Create a new node-payload object for a symlink node. + * + * Allocate the result in @a result_pool. + */ +svn_element__payload_t * +svn_element__payload_create_symlink(apr_hash_t *props, + const char *target, + apr_pool_t *result_pool); + +/** @} */ + + +/* + * ======================================================================== + * Element-Revision Content + * ======================================================================== + * + * @defgroup svn_el_rev_content Element-Revision Content + * @{ + */ + +/* 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_element__content_t +{ + /* eid of the parent element, or -1 if this is the root element */ + int parent_eid; + /* element name, or "" for root element; never null */ + const char *name; + /* payload (kind, props, text, ...) */ + svn_element__payload_t *payload; + +} svn_element__content_t; + +/* Return a new content object constructed with deep copies of PARENT_EID, + * NAME and PAYLOAD, allocated in RESULT_POOL. + */ +svn_element__content_t * +svn_element__content_create(int 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_element__content_t * +svn_element__content_dup(const svn_element__content_t *old, + apr_pool_t *result_pool); + +/* Return TRUE iff CONTENT_LEFT is the same as CONTENT_RIGHT. */ +svn_boolean_t +svn_element__content_equal(const svn_element__content_t *content_left, + const svn_element__content_t *content_right, + apr_pool_t *scratch_pool); + +/** @} */ + + +/* + * ======================================================================== + * Element Tree + * ======================================================================== + * + * The elements in an Element Tree do not necessarily form a single, + * complete tree at all times. + * + * @defgroup svn_element_tree Element Tree + * @{ + */ + +/* A (sub)tree of elements. + * + * An element tree 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. + */ +typedef struct svn_element__tree_t +{ + /* EID -> svn_element__content_t mapping. */ + apr_hash_t *e_map; + + /* Subtree root EID. (ROOT_EID must be an existing key in E_MAP.) */ + int root_eid; + +} svn_element__tree_t; + +/* Create an element tree object. + * + * The result contains a *shallow* copy of E_MAP, or a new empty mapping + * if E_MAP is null. + */ +svn_element__tree_t * +svn_element__tree_create(apr_hash_t *e_map, + int root_eid, + apr_pool_t *result_pool); + +svn_element__content_t * +svn_element__tree_get(const svn_element__tree_t *tree, + int eid); + +svn_error_t * +svn_element__tree_set(svn_element__tree_t *tree, + int eid, + const svn_element__content_t *element); + +/* 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. + */ +void +svn_element__tree_purge_orphans(apr_hash_t *e_map, + int root_eid, + apr_pool_t *scratch_pool); + +/* Return the subtree-relative path of element EID in TREE. + * + * If the element EID does not currently exist in TREE, return NULL. + * + * ### TODO: Clarify sequencing requirements. + */ +const char * +svn_element__tree_get_path_by_eid(const svn_element__tree_t *tree, + int eid, + apr_pool_t *result_pool); + +/* Return the subtree rooted at EID within ELEMENT_TREE. + * + * The result is limited by the lifetime of ELEMENT_TREE. It includes a + * shallow copy of the mapping in ELEMENT_TREE: the hash table is + * duplicated but the keys and values (element content data) are not. + */ +svn_element__tree_t * +svn_element__tree_get_subtree_at_eid(svn_element__tree_t *element_tree, + int eid, + apr_pool_t *result_pool); + +/** @} */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_BRANCH_ELEMENT_H */ diff --git a/subversion/include/private/svn_fs_fs_private.h b/subversion/include/private/svn_fs_fs_private.h index 59aede1c7a62..d2573d447c9d 100644 --- a/subversion/include/private/svn_fs_fs_private.h +++ b/subversion/include/private/svn_fs_fs_private.h @@ -53,7 +53,8 @@ typedef struct svn_fs_fs__large_change_info_t /* size of the (deltified) representation */ apr_uint64_t size; - /* Revision of the representation. SVN_INVALID_REVNUM for unused entries. */ + /* Revision of the representation. SVN_INVALID_REVNUM for unused entries. + */ svn_revnum_t revision; /* node path. "" for unused instances */ @@ -151,6 +152,9 @@ typedef struct svn_fs_fs__representation_stats_t /* sum of ref_count * expanded_size, * i.e. total plaintext content if there was no rep sharing */ apr_uint64_t expanded_size; + + /* sum of all representation delta chain lengths */ + apr_uint64_t chain_len; } svn_fs_fs__representation_stats_t; /* Basic statistics we collect over a given set of noderevs. @@ -267,19 +271,20 @@ svn_fs_fs__get_stats(svn_fs_fs__stats_t **stats, apr_pool_t *result_pool, apr_pool_t *scratch_pool); -/* Node-revision IDs in FSFS consist of 3 of sub-IDs ("parts") that consist +/* A node-revision ID in FSFS consists of 3 sub-IDs ("parts") that consist * of a creation REVISION number and some revision- / transaction-local * counter value (NUMBER). Old-style ID parts use global counter values. * * The parts are: node_id, copy_id and txn_id for in-txn IDs as well as - * node_id, copy_id and rev_offset for in-revision IDs. This struct the + * node_id, copy_id and rev_item for in-revision IDs. This struct is the * data structure used for each of those parts. */ typedef struct svn_fs_fs__id_part_t { - /* SVN_INVALID_REVNUM for txns -> not a txn, COUNTER must be 0. - SVN_INVALID_REVNUM for others -> not assigned to a revision, yet. - 0 for others -> old-style ID or the root in rev 0. */ + /* SVN_INVALID_REVNUM for txn_id part -> not a txn, NUMBER must be 0. + SVN_INVALID_REVNUM for other parts -> not assigned to a revision, yet. + 0 for other parts -> old-style ID or the root in rev 0. + */ svn_revnum_t revision; /* sub-id value relative to REVISION. Its interpretation depends on diff --git a/subversion/include/private/svn_fs_private.h b/subversion/include/private/svn_fs_private.h index 5bd89c0280c0..4bd0a5052731 100644 --- a/subversion/include/private/svn_fs_private.h +++ b/subversion/include/private/svn_fs_private.h @@ -183,7 +183,7 @@ svn_fs__editor_commit(svn_revnum_t *revision, * * If there is no mergeinfo, set @a *mergeinfo to NULL. * - * See svn_fs_get_mergeinfo2() but for the meanings of @a inherit and + * See svn_fs_get_mergeinfo3() but for the meanings of @a inherit and * @a adjust_inheritable_mergeinfo and other details. */ svn_error_t * @@ -195,6 +195,22 @@ svn_fs__get_mergeinfo_for_path(svn_mergeinfo_t *mergeinfo, apr_pool_t *result_pool, apr_pool_t *scratch_pool); +/** Determine the previous location of @a path under @a root and return it + * as @a *node_path under @a *node_root. This may be called for arbitrary + * nodes but is intended for nodes that got deleted in @a root, i.e. when + * standard navigation fails. It also works if @a root is transaction root. + * + * Allocate @a *node_path and @a *node_root in @a result_pool while using + * @a scratch_pool for temporaries. + */ +svn_error_t * +svn_fs__get_deleted_node(svn_fs_root_t **node_root, + const char **node_path, + svn_fs_root_t *root, + const char *path, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /** @} */ diff --git a/subversion/include/private/svn_fs_util.h b/subversion/include/private/svn_fs_util.h index c9f74a126858..fc548ed15ee0 100644 --- a/subversion/include/private/svn_fs_util.h +++ b/subversion/include/private/svn_fs_util.h @@ -206,6 +206,15 @@ svn_fs__path_change_create_internal(const svn_fs_id_t *node_rev_id, svn_fs_path_change_kind_t change_kind, apr_pool_t *pool); +/* Allocate an svn_fs_path_change3_t structure in RESULT_POOL, initialize + and return it. + + Set the change_kind to CHANGE_KIND. Set all other fields to their + _unknown, NULL or invalid value, respectively. */ +svn_fs_path_change3_t * +svn_fs__path_change_create_internal2(svn_fs_path_change_kind_t change_kind, + apr_pool_t *result_pool); + /* Append REL_PATH (which may contain slashes) to each path that exists in the mergeinfo INPUT, and return a new mergeinfo in *OUTPUT. Deep copies the values. Perform all allocations in POOL. */ diff --git a/subversion/include/private/svn_io_private.h b/subversion/include/private/svn_io_private.h index 814c27aea422..2c9028a9c31d 100644 --- a/subversion/include/private/svn_io_private.h +++ b/subversion/include/private/svn_io_private.h @@ -85,32 +85,6 @@ svn_io__file_lock_autocreate(const char *lock_file, apr_pool_t *pool); -/** Buffer test handler function for a generic stream. @see svn_stream_t - * and svn_stream__is_buffered(). - * - * @since New in 1.7. - */ -typedef svn_boolean_t (*svn_stream__is_buffered_fn_t)(void *baton); - -/** Set @a stream's buffer test function to @a is_buffered_fn - * - * @since New in 1.7. - */ -void -svn_stream__set_is_buffered(svn_stream_t *stream, - svn_stream__is_buffered_fn_t is_buffered_fn); - -/** Return whether this generic @a stream uses internal buffering. - * This may be used to work around subtle differences between buffered - * and non-buffered APR files. A lazy-open stream cannot report the - * true buffering state until after the lazy open: a stream that - * initially reports as non-buffered may report as buffered later. - * - * @since New in 1.7. - */ -svn_boolean_t -svn_stream__is_buffered(svn_stream_t *stream); - /** Return the underlying file, if any, associated with the stream, or * NULL if not available. Accessing the file bypasses the stream. */ @@ -153,6 +127,13 @@ svn_stream__install_get_info(apr_finfo_t *finfo, apr_int32_t wanted, apr_pool_t *scratch_pool); +/* Internal version of svn_stream_from_aprfile2() supporting the + additional TRUNCATE_ON_SEEK argument. */ +svn_stream_t * +svn_stream__from_aprfile(apr_file_t *file, + svn_boolean_t disown, + svn_boolean_t truncate_on_seek, + apr_pool_t *pool); #if defined(WIN32) diff --git a/subversion/include/private/svn_log.h b/subversion/include/private/svn_log.h index 1ad8d559b9df..c2da89d173c1 100644 --- a/subversion/include/private/svn_log.h +++ b/subversion/include/private/svn_log.h @@ -93,7 +93,7 @@ svn_log__get_file(const char *path, svn_revnum_t rev, const char * svn_log__get_dir(const char *path, svn_revnum_t rev, svn_boolean_t want_contents, svn_boolean_t want_props, - apr_uint64_t dirent_fields, + apr_uint32_t dirent_fields, apr_pool_t *pool); /** @@ -253,6 +253,17 @@ const char * svn_log__get_inherited_props(const char *path, svn_revnum_t rev, apr_pool_t *pool); + +/** + * Return a log string for a list action. + * + * @since New in 1.10. + */ +const char * +svn_log__list(const char *path, svn_revnum_t revision, + apr_array_header_t *patterns, svn_depth_t depth, + apr_uint32_t dirent_fields, apr_pool_t *pool); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_mergeinfo_private.h b/subversion/include/private/svn_mergeinfo_private.h index 716d0c9f90e2..a34cb39ce3da 100644 --- a/subversion/include/private/svn_mergeinfo_private.h +++ b/subversion/include/private/svn_mergeinfo_private.h @@ -52,18 +52,21 @@ svn_rangelist__set_inheritance(svn_rangelist_t *rangelist, * Unlike svn_mergeinfo_parse(), this does not sort the ranges into order * or combine adjacent and overlapping ranges. * - * The compaction can be done with svn_rangelist__combine_adjacent_ranges(). + * The compaction can be done with svn_rangelist__canonicalize(). */ svn_error_t * svn_rangelist__parse(svn_rangelist_t **rangelist, const char *str, apr_pool_t *result_pool); -/* In-place combines adjacent ranges in a rangelist. - SCRATCH_POOL is just used for providing error messages. */ -svn_error_t * -svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist, - apr_pool_t *scratch_pool); +/* Return TRUE, if all ranges in RANGELIST are in ascending order and do +* not overlap and are not adjacent. +* +* If this returns FALSE, you probaly want to call +* svn_rangelist__canonicalize(). +*/ +svn_boolean_t +svn_rangelist__is_canonical(const svn_rangelist_t *rangelist); /** Canonicalize the @a rangelist: sort the ranges, and combine adjacent or * overlapping ranges into single ranges where possible. diff --git a/subversion/include/private/svn_mutex.h b/subversion/include/private/svn_mutex.h index c04820bacbbb..0b779474c350 100644 --- a/subversion/include/private/svn_mutex.h +++ b/subversion/include/private/svn_mutex.h @@ -27,8 +27,6 @@ #ifndef SVN_MUTEX_H #define SVN_MUTEX_H -#include <apr_thread_mutex.h> - #include "svn_error.h" #ifdef __cplusplus @@ -106,6 +104,17 @@ do { \ SVN_ERR(svn_mutex__unlock(svn_mutex__m, (expr))); \ } while (0) +#if APR_HAS_THREADS + +/** Return the APR mutex encapsulated in @a mutex. + * + * @note This function should only be called by APR wrapper code. + */ +apr_thread_mutex_t * +svn_mutex__get(svn_mutex__t *mutex); + +#endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_object_pool.h b/subversion/include/private/svn_object_pool.h index 7a9383e5f625..767a48bc6a12 100644 --- a/subversion/include/private/svn_object_pool.h +++ b/subversion/include/private/svn_object_pool.h @@ -65,80 +65,46 @@ /* The opaque object container type. */ typedef struct svn_object_pool__t svn_object_pool__t; -/* Extract the actual object from the WRAPPER using optional information - * from BATON (provided through #svn_object_pool__lookup) and return it. - * The result will be used with POOL and must remain valid throughout - * POOL's lifetime. - * - * It is legal to return a copy, allocated in POOL, of the wrapped object. - */ -typedef void * (* svn_object_pool__getter_t)(void *wrapper, - void *baton, - apr_pool_t *pool); - -/* Copy the information from the SOURCE object wrapper into the already - * existing *TARGET object wrapper using POOL for allocations and BATON - * for optional context (provided through #svn_object_pool__insert). - */ -typedef svn_error_t * (* svn_object_pool__setter_t)(void **target, - void *source, - void *baton, - apr_pool_t *pool); - /* Create a new object pool in POOL and return it in *OBJECT_POOL. - * Objects will be extracted using GETTER and updated using SETTER. Either - * one (or both) may be NULL and the default implementation assumes that - * wrapper == object and updating is a no-op. + * Objects are reference-counted and stored as opaque pointers. Each + * must be allocated in a separate pool ceated by + * svn_object_pool__new_item_pool. Unused objects get destroyed at + * the object pool's discretion. * * If THREAD_SAFE is not set, neither the object pool nor the object * references returned from it may be accessed from multiple threads. * * It is not legal to call any API on the object pool after POOL got - * cleared or destroyed. However, existing object references handed out - * from the object pool remain valid and will keep the internal pool data - * structures alive for as long as such object references exist. + * cleared or destroyed nor to use any objects from this object pool. */ svn_error_t * svn_object_pool__create(svn_object_pool__t **object_pool, - svn_object_pool__getter_t getter, - svn_object_pool__setter_t setter, svn_boolean_t thread_safe, apr_pool_t *pool); -/* Return the root pool containing the OBJECT_POOL and all sub-structures. +/* Return a pool to allocate the new object. */ apr_pool_t * -svn_object_pool__new_wrapper_pool(svn_object_pool__t *object_pool); - -/* Return the mutex used to serialize all OBJECT_POOL access. - */ -svn_mutex__t * -svn_object_pool__mutex(svn_object_pool__t *object_pool); - -/* Return the number of object instances (used or unused) in OBJECT_POOL. - */ -unsigned -svn_object_pool__count(svn_object_pool__t *object_pool); +svn_object_pool__new_item_pool(svn_object_pool__t *object_pool); /* In OBJECT_POOL, look for an available object by KEY and return a * reference to it in *OBJECT. If none can be found, *OBJECT will be NULL. - * BATON will be passed to OBJECT_POOL's getter function. The reference - * will be returned when *RESULT_POOL gets cleaned up or destroyed. + * + * The reference will be returned when *RESULT_POOL and may be destroyed + * or recycled by OBJECT_POOL. */ svn_error_t * svn_object_pool__lookup(void **object, svn_object_pool__t *object_pool, svn_membuf_t *key, - void *baton, apr_pool_t *result_pool); -/* Store the wrapped object WRAPPER under KEY in OBJECT_POOL and return - * a reference to the object in *OBJECT (just like lookup). +/* Store the object ITEM under KEY in OBJECT_POOL and return a reference + * to the object in *OBJECT (just like lookup). * - * The object must have been created in WRAPPER_POOL and the latter must - * be a sub-pool of OBJECT_POOL's root POOL (see #svn_object_pool__pool). + * The object must have been created in ITEM_POOL and the latter must + * have been created by svn_object_pool__new_item_pool. * - * BATON will be passed to OBJECT_POOL's setter and getter functions. * The reference will be returned when *RESULT_POOL gets cleaned up or * destroyed. */ @@ -146,9 +112,8 @@ svn_error_t * svn_object_pool__insert(void **object, svn_object_pool__t *object_pool, const svn_membuf_t *key, - void *wrapper, - void *baton, - apr_pool_t *wrapper_pool, + void *item, + apr_pool_t *item_pool, apr_pool_t *result_pool); #endif /* SVN_OBJECT_POOL_H */ diff --git a/subversion/include/private/svn_packed_data.h b/subversion/include/private/svn_packed_data.h index 6faf0dd0e116..841be3a0cebb 100644 --- a/subversion/include/private/svn_packed_data.h +++ b/subversion/include/private/svn_packed_data.h @@ -218,6 +218,11 @@ svn_packed__int_count(svn_packed__int_stream_t *stream); apr_size_t svn_packed__byte_count(svn_packed__byte_stream_t *stream); +/* Return the number of entries left to read from STREAM. + */ +apr_size_t +svn_packed__byte_block_count(svn_packed__byte_stream_t *stream); + /* Return the next number from STREAM as unsigned integer. Returns 0 when * reading beyond the end of the stream. */ diff --git a/subversion/include/private/svn_ra_svn_private.h b/subversion/include/private/svn_ra_svn_private.h index bc2fa4533f31..42fd31ee060c 100644 --- a/subversion/include/private/svn_ra_svn_private.h +++ b/subversion/include/private/svn_ra_svn_private.h @@ -34,6 +34,104 @@ extern "C" { #endif /* __cplusplus */ +/** Memory representation of an on-the-wire data item. */ +typedef struct svn_ra_svn__item_t svn_ra_svn__item_t; + +/* A list of svn_ra_svn__item_t objects. */ +typedef struct svn_ra_svn__list_t +{ + /* List contents (array). May be NULL if NELTS is 0. */ + struct svn_ra_svn__item_t *items; + + /* Number of elements in ITEMS. */ + int nelts; +} svn_ra_svn__list_t; + +/* List element access macro. */ +#define SVN_RA_SVN__LIST_ITEM(list, idx) (list)->items[idx] + +/** Memory representation of an on-the-wire data item. */ +struct svn_ra_svn__item_t +{ + /** Variant indicator. */ + svn_ra_svn_item_kind_t kind; + + /** Variant data. */ + union { + apr_uint64_t number; + svn_string_t string; + svn_string_t word; + svn_ra_svn__list_t list; + } u; +}; + +/** Command handler, used by svn_ra_svn__handle_commands(). */ +typedef svn_error_t *(*svn_ra_svn__command_handler)(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_ra_svn__list_t *params, + void *baton); + +/** Command table, used by svn_ra_svn_handle_commands(). + */ +typedef struct svn_ra_svn__cmd_entry_t +{ + /** Name of the command */ + const char *cmdname; + + /** Handler for the command */ + svn_ra_svn__command_handler handler; + + /** Only set when used through a deprecated API. + * HANDLER is NULL in that case. */ + svn_ra_svn_command_handler deprecated_handler; + + /** Termination flag. If set, command-handling will cease after + * command is processed. */ + svn_boolean_t terminate; +} svn_ra_svn__cmd_entry_t; + + +/* Return a deep copy of the SOURCE array containing private API + * svn_ra_svn__item_t SOURCE to public API *TARGET, allocating + * sub-structures in RESULT_POOL. */ +apr_array_header_t * +svn_ra_svn__to_public_array(const svn_ra_svn__list_t *source, + apr_pool_t *result_pool); + +/* Deep copy contents from private API *SOURCE to public API *TARGET, + * allocating sub-structures in RESULT_POOL. */ +void +svn_ra_svn__to_public_item(svn_ra_svn_item_t *target, + const svn_ra_svn__item_t *source, + apr_pool_t *result_pool); + +svn_ra_svn__list_t * +svn_ra_svn__to_private_array(const apr_array_header_t *source, + apr_pool_t *result_pool); + +/* Deep copy contents from public API *SOURCE to private API *TARGET, + * allocating sub-structures in RESULT_POOL. */ +void +svn_ra_svn__to_private_item(svn_ra_svn__item_t *target, + const svn_ra_svn_item_t *source, + apr_pool_t *result_pool); + +/** Add the capabilities in @a list to @a conn's capabilities. + * @a list contains svn_ra_svn__item_t entries (which should be of type + * SVN_RA_SVN_WORD; a malformed data error will result if any are not). + * + * This is idempotent: if a given capability was already set for + * @a conn, it remains set. + */ +svn_error_t * +svn_ra_svn__set_capabilities(svn_ra_svn_conn_t *conn, + const svn_ra_svn__list_t *list); + +/** Returns the preferred svndiff version to be used with connection @a conn. + */ +int +svn_ra_svn__svndiff_version(svn_ra_svn_conn_t *conn); + /** * Set the shim callbacks to be used by @a conn to @a shim_callbacks. @@ -161,10 +259,10 @@ svn_ra_svn__flush(svn_ra_svn_conn_t *conn, * to transmit an array or other unusual data. For example, to write * a tuple containing a revision, an array of words, and a boolean: * @code - SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "r(!", rev)); + SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "r(!", rev)); for (i = 0; i < n; i++) - SVN_ERR(svn_ra_svn_write_word(conn, pool, words[i])); - SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)b", flag)); @endcode + SVN_ERR(svn_ra_svn__write_word(conn, pool, words[i])); + SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)b", flag)); @endcode */ svn_error_t * svn_ra_svn__write_tuple(svn_ra_svn_conn_t *conn, @@ -175,7 +273,7 @@ svn_ra_svn__write_tuple(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - svn_ra_svn_item_t **item); + svn_ra_svn__item_t **item); /** Scan data on @a conn until we find something which looks like the * beginning of an svn server greeting (an open paren followed by a @@ -221,13 +319,12 @@ svn_ra_svn__skip_leading_garbage(svn_ra_svn_conn_t *conn, * * If an optional part of a tuple contains no data, 'r' values will be * set to @c SVN_INVALID_REVNUM; 'n' and 'B' values will be set to - * #SVN_RA_SVN_UNSPECIFIED_NUMBER; 's', 'c', 'w', and 'l' values - * will be set to @c NULL; and '3' values will be set to #svn_tristate_unknown - * 'b' may not appear inside an optional tuple specification; use '3' instead. + * #SVN_RA_SVN_UNSPECIFIED_NUMBER; 's', 'c', 'w', and 'l' values will + * be set to @c NULL; '3' values will be set to #svn_tristate_unknown; + * and 'b' values will be set to @c FALSE. */ svn_error_t * -svn_ra_svn__parse_tuple(const apr_array_header_t *list, - apr_pool_t *pool, +svn_ra_svn__parse_tuple(const svn_ra_svn__list_t *list, const char *fmt, ...); /** Read a tuple from the network and parse it as a tuple, using the @@ -238,13 +335,13 @@ svn_ra_svn__read_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *fmt, ...); -/** Parse an array of @c svn_ra_svn_item_t structures as a list of +/** Parse an array of @c svn_ra_svn__item_t structures as a list of * properties, storing the properties in a hash table. * * @since New in 1.5. */ svn_error_t * -svn_ra_svn__parse_proplist(const apr_array_header_t *list, +svn_ra_svn__parse_proplist(const svn_ra_svn__list_t *list, apr_pool_t *pool, apr_hash_t **props); @@ -300,7 +397,7 @@ svn_ra_svn__handle_command(svn_boolean_t *terminate, svn_error_t * svn_ra_svn__handle_commands2(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const svn_ra_svn_cmd_entry_t *commands, + const svn_ra_svn__cmd_entry_t *commands, void *baton, svn_boolean_t error_on_disconnect); @@ -347,7 +444,7 @@ svn_error_t * svn_ra_svn__write_cmd_open_root(svn_ra_svn_conn_t *conn, apr_pool_t *pool, svn_revnum_t rev, - const char *token); + const svn_string_t *token); /** Send a "delete-entry" command over connection @a conn. Delete the * @a path at optional revision @a rev below @a parent_token. @@ -358,7 +455,7 @@ svn_ra_svn__write_cmd_delete_entry(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, svn_revnum_t rev, - const char *parent_token); + const svn_string_t *parent_token); /** Send a "add-dir" command over connection @a conn. Add a new directory * node named @a path under the directory identified by @a parent_token. @@ -370,8 +467,8 @@ svn_error_t * svn_ra_svn__write_cmd_add_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, - const char *parent_token, - const char *token, + const svn_string_t *parent_token, + const svn_string_t *token, const char *copy_path, svn_revnum_t copy_rev); @@ -384,8 +481,8 @@ svn_error_t * svn_ra_svn__write_cmd_open_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, - const char *parent_token, - const char *token, + const svn_string_t *parent_token, + const svn_string_t *token, svn_revnum_t rev); /** Send a "change-dir-prop" command over connection @a conn. Set the @@ -395,7 +492,7 @@ svn_ra_svn__write_cmd_open_dir(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_cmd_change_dir_prop(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *token, + const svn_string_t *token, const char *name, const svn_string_t *value); @@ -406,7 +503,7 @@ svn_ra_svn__write_cmd_change_dir_prop(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_cmd_close_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *token); + const svn_string_t *token); /** Send a "absent-dir" command over connection @a conn. Directory node * named @a path under the directory identified by @a parent_token is @@ -416,7 +513,7 @@ svn_error_t * svn_ra_svn__write_cmd_absent_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, - const char *parent_token); + const svn_string_t *parent_token); /** Send a "add-file" command over connection @a conn. Add a new file * node named @a path under the directory identified by @a parent_token. @@ -428,8 +525,8 @@ svn_error_t * svn_ra_svn__write_cmd_add_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, - const char *parent_token, - const char *token, + const svn_string_t *parent_token, + const svn_string_t *token, const char *copy_path, svn_revnum_t copy_rev); @@ -442,8 +539,8 @@ svn_error_t * svn_ra_svn__write_cmd_open_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, - const char *parent_token, - const char *token, + const svn_string_t *parent_token, + const svn_string_t *token, svn_revnum_t rev); /** Send a "change-file-prop" command over connection @a conn. Set the @@ -453,7 +550,7 @@ svn_ra_svn__write_cmd_open_file(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_cmd_change_file_prop(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *token, + const svn_string_t *token, const char *name, const svn_string_t *value); @@ -465,7 +562,7 @@ svn_ra_svn__write_cmd_change_file_prop(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_cmd_close_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *token, + const svn_string_t *token, const char *text_checksum); /** Send a "absent-file" command over connection @a conn. File node @@ -476,7 +573,7 @@ svn_error_t * svn_ra_svn__write_cmd_absent_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, - const char *parent_token); + const svn_string_t *parent_token); /** Send a "apply-textdelta" command over connection @a conn. Starts a * series of text deltas to be applied to the file identified by @a token. @@ -486,7 +583,7 @@ svn_ra_svn__write_cmd_absent_file(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_cmd_apply_textdelta(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *token, + const svn_string_t *token, const char *base_checksum); /** Send a "textdelta-chunk" command over connection @a conn. Apply @@ -496,7 +593,7 @@ svn_ra_svn__write_cmd_apply_textdelta(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_cmd_textdelta_chunk(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *token, + const svn_string_t *token, const svn_string_t *chunk); /** Send a "textdelta-end" command over connection @a conn. Ends the @@ -506,7 +603,7 @@ svn_ra_svn__write_cmd_textdelta_chunk(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_cmd_textdelta_end(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *token); + const svn_string_t *token); /** Send a "close-edit" command over connection @a conn. Ends the editor * drive (successfully). Use @a pool for allocations. @@ -790,7 +887,7 @@ svn_error_t * svn_ra_svn__write_cmd_unlock(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *path, - const char *token, + const svn_string_t *token, svn_boolean_t break_lock); /** Send a "get-lock" command over connection @a conn. @@ -886,7 +983,7 @@ svn_ra_svn__write_cmd_finish_replay(svn_ra_svn_conn_t *conn, svn_error_t * svn_ra_svn__write_data_log_changed_path(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const char *path, + const svn_string_t *path, char action, const char *copyfrom_path, svn_revnum_t copyfrom_rev, @@ -916,6 +1013,19 @@ svn_ra_svn__write_data_log_entry(svn_ra_svn_conn_t *conn, svn_boolean_t invalid_revnum, unsigned revprop_count); +/** Send a directory entry @a dirent for @a path over connection @a conn. + * Use @a pool for allocations. + * + * Depending on the flags in @a dirent_fields, only selected elements will + * be transmitted. + */ +svn_error_t * +svn_ra_svn__write_dirent(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_dirent_t *dirent, + apr_uint32_t dirent_fields); + /** * @} */ @@ -931,7 +1041,7 @@ svn_ra_svn__write_data_log_entry(svn_ra_svn_conn_t *conn, * @see svn_log_changed_path2_t for a description of the output parameters. */ svn_error_t * -svn_ra_svn__read_data_log_changed_entry(const apr_array_header_t *items, +svn_ra_svn__read_data_log_changed_entry(const svn_ra_svn__list_t *items, svn_string_t **cpath, const char **action, const char **copy_path, diff --git a/subversion/include/private/svn_repos_private.h b/subversion/include/private/svn_repos_private.h index c5a232f29b55..c65b73fc1e69 100644 --- a/subversion/include/private/svn_repos_private.h +++ b/subversion/include/private/svn_repos_private.h @@ -34,6 +34,7 @@ #include "svn_editor.h" #include "svn_config.h" +#include "private/svn_object_pool.h" #include "private/svn_string_private.h" #ifdef __cplusplus @@ -74,6 +75,30 @@ svn_repos__validate_prop(const char *name, const svn_string_t *value, apr_pool_t *pool); +/* Attempt to normalize a Subversion property if it "needs translation" + * (according to svn_prop_needs_translation(), currently all svn:* props). + * + * At this time, the only performed normalization is translation of + * the line endings of the property value so that it would only contain + * LF (\n) characters. "\r" characters found mid-line are replaced with "\n". + * "\r\n" sequences are replaced with "\n". + * + * NAME is used to check that VALUE should be normalized, and if this + * is the case, VALUE is then normalized, allocated from RESULT_POOL. + * If no normalization is required, VALUE will be copied to RESULT_POOL + * unchanged. If NORMALIZED_P is not NULL, and the normalization + * happened, set *NORMALIZED_P to non-zero. If the property is returned + * unchanged and NORMALIZED_P is not NULL, then *NORMALIZED_P will be + * set to zero. SCRATCH_POOL will be used for temporary allocations. + */ +svn_error_t * +svn_repos__normalize_prop(const svn_string_t **result_p, + svn_boolean_t *normalized_p, + const char *name, + const svn_string_t *value, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /** * Given the error @a err from svn_repos_fs_commit_txn(), return an * string containing either or both of the svn_fs_commit_txn() error @@ -127,26 +152,27 @@ svn_repos__replay_ev2(svn_fs_root_t *root, void *authz_read_baton, apr_pool_t *scratch_pool); -/* Given a PATH which might be a relative repo URL (^/), an absolute - * local repo URL (file://), an absolute path outside of the repo - * or a location in the Windows registry. - * - * Retrieve the configuration data that PATH points at and parse it into - * CFG_P allocated in POOL. - * - * If PATH cannot be parsed as a config file then an error is returned. The - * contents of CFG_P is then undefined. If MUST_EXIST is TRUE, a missing - * authz file is also an error. The CASE_SENSITIVE controls the lookup - * behavior for section and option names alike. +/** + * Non-deprecated alias for svn_repos_get_logs4. * - * REPOS_ROOT points at the root of the repos you are - * going to apply the authz against, can be NULL if you are sure that you - * don't have a repos relative URL in PATH. */ + * Since the mapping of log5 to ra_get_log is would basically duplicate the + * log5->log4 adapter, we provide this log4 wrapper that does not create a + * deprecation warning. + */ svn_error_t * -svn_repos__retrieve_config(svn_config_t **cfg_p, - const char *path, - svn_boolean_t must_exist, - svn_boolean_t case_sensitive, +svn_repos__get_logs_compat(svn_repos_t *repos, + const apr_array_header_t *paths, + svn_revnum_t start, + svn_revnum_t end, + int limit, + svn_boolean_t discover_changed_paths, + svn_boolean_t strict_node_history, + svn_boolean_t include_merged_revisions, + const apr_array_header_t *revprops, + svn_repos_authz_func_t authz_read_func, + void *authz_read_baton, + svn_log_entry_receiver_t receiver, + void *receiver_baton, apr_pool_t *pool); /** @@ -160,7 +186,7 @@ svn_repos__retrieve_config(svn_config_t **cfg_p, * from multiple threads. Configuration objects no longer referenced by * any user may linger for a while before being cleaned up. */ -typedef struct svn_repos__config_pool_t svn_repos__config_pool_t; +typedef svn_object_pool__t svn_repos__config_pool_t; /* Create a new configuration pool object with a lifetime determined by * POOL and return it in *CONFIG_POOL. @@ -177,11 +203,10 @@ svn_repos__config_pool_create(svn_repos__config_pool_t **config_pool, * configuration specified by PATH. If the latter is a URL, we read the * data from a local repository. CONFIG_POOL will store the configuration * and make further callers use the same instance if the content matches. - * If KEY is not NULL, *KEY will be set to a unique ID - if available. + * Section and option names will be case-insensitive. * * If MUST_EXIST is TRUE, a missing config file is also an error, *CFG - * is otherwise simply NULL. The CASE_SENSITIVE controls the lookup - * behavior for section and option names alike. + * is otherwise simply NULL. * * PREFERRED_REPOS is only used if it is not NULL and PATH is a URL. * If it matches the URL, access the repository through this object @@ -194,72 +219,14 @@ svn_repos__config_pool_create(svn_repos__config_pool_t **config_pool, */ svn_error_t * svn_repos__config_pool_get(svn_config_t **cfg, - svn_membuf_t **key, svn_repos__config_pool_t *config_pool, const char *path, svn_boolean_t must_exist, - svn_boolean_t case_sensitive, svn_repos_t *preferred_repos, apr_pool_t *pool); /** @} */ -/** - * @defgroup svn_authz_pool Authz object pool API - * @{ - */ - -/* Opaque thread-safe factory and container for authorization objects. - * - * Instances handed out are read-only and may be given to multiple callers - * from multiple threads. Authorization objects no longer referenced by - * any user may linger for a while before being cleaned up. - */ -typedef struct svn_repos__authz_pool_t svn_repos__authz_pool_t; - -/* Create a new authorization pool object with a lifetime determined by - * POOL and return it in *AUTHZ_POOL. CONFIG_POOL will be the common - * source for the configuration data underlying the authz objects and must - * remain valid at least until POOL cleanup. - * - * The THREAD_SAFE flag indicates whether the pool actually needs to be - * thread-safe and POOL must be also be thread-safe if this flag is set. - */ -svn_error_t * -svn_repos__authz_pool_create(svn_repos__authz_pool_t **authz_pool, - svn_repos__config_pool_t *config_pool, - svn_boolean_t thread_safe, - apr_pool_t *pool); - -/* Set *AUTHZ_P to a read-only reference to the current contents of the - * authorization specified by PATH and GROUPS_PATH. If these are URLs, - * we read the data from a local repository (see #svn_repos_authz_read2). - * AUTHZ_POOL will store the authz data and make further callers use the - * same instance if the content matches. - * - * If MUST_EXIST is TRUE, a missing config file is also an error, *AUTHZ_P - * is otherwise simply NULL. - * - * PREFERRED_REPOS is only used if it is not NULL and PATH is a URL. - * If it matches the URL, access the repository through this object - * instead of creating a new repo instance. Note that this might not - * return the latest content. - * - * POOL determines the minimum lifetime of *AUTHZ_P (may remain cached - * after release) but must not exceed the lifetime of the pool provided to - * svn_repos__authz_pool_create. - */ -svn_error_t * -svn_repos__authz_pool_get(svn_authz_t **authz_p, - svn_repos__authz_pool_t *authz_pool, - const char *path, - const char *groups_path, - svn_boolean_t must_exist, - svn_repos_t *preferred_repos, - apr_pool_t *pool); - -/** @} */ - /* Adjust mergeinfo paths and revisions in ways that are useful when loading * a dump stream. * diff --git a/subversion/include/private/svn_sorts_private.h b/subversion/include/private/svn_sorts_private.h index c358513e9233..2d5f1887f1b7 100644 --- a/subversion/include/private/svn_sorts_private.h +++ b/subversion/include/private/svn_sorts_private.h @@ -53,12 +53,12 @@ struct svn_sort__item_t { /** Sort @a ht according to its keys, return an @c apr_array_header_t * containing @c svn_sort__item_t structures holding those keys and values * (i.e. for each @c svn_sort__item_t @a item in the returned array, - * @a item->key and @a item->size are the hash key, and @a item->value points to + * @a item.key and @a item.size are the hash key, and @a item.value points to * the hash value). * * Storage is shared with the original hash, not copied. * - * @a comparison_func should take two @c svn_sort__item_t's and return an + * @a comparison_func should take pointers to two items and return an * integer greater than, equal to, or less than 0, according as the first item * is greater than, equal to, or less than the second. * diff --git a/subversion/include/private/svn_sqlite.h b/subversion/include/private/svn_sqlite.h index 4c6cb97cd506..cd01348ad595 100644 --- a/subversion/include/private/svn_sqlite.h +++ b/subversion/include/private/svn_sqlite.h @@ -555,8 +555,14 @@ svn_sqlite__hotcopy(const char *src_path, const char *dst_path, apr_pool_t *scratch_pool); -/* Backported version of SVN_ERR_SQLITE_ROLLBACK_FAILED. */ -#define SVN_SQLITE__ERR_ROLLBACK_FAILED (SVN_ERR_MISC_CATEGORY_START + 44) +/* Evaluate the expression EXPR. If any error is returned, close + * the connection in DB. */ +#define SVN_SQLITE__ERR_CLOSE(expr, db) do \ +{ \ + svn_error_t *svn__err = (expr); \ + if (svn__err) \ + return svn_error_compose_create(svn__err, svn_sqlite__close(db)); \ +} while (0) #ifdef __cplusplus } diff --git a/subversion/include/private/svn_string_private.h b/subversion/include/private/svn_string_private.h index 2f162733db81..25e42049db7b 100644 --- a/subversion/include/private/svn_string_private.h +++ b/subversion/include/private/svn_string_private.h @@ -131,6 +131,14 @@ svn_membuf__nzero(svn_membuf_t *membuf, apr_size_t size); svn_string_t * svn_stringbuf__morph_into_string(svn_stringbuf_t *strbuf); +/** Utility macro to define static svn_string_t objects. @a value must + * be a static string; the "" in the macro declaration tries to ensure this. + * + * Usage: + * static const svn_string_t my_string = SVN__STATIC_STRING("my text"); + */ +#define SVN__STATIC_STRING(value) { value "", sizeof(value "") - 1 } + /** Like strtoul but with a fixed base of 10 and without overflow checks. * This allows the compiler to generate massively faster (4x on 64bit LINUX) * code. Overflow checks may be added on the caller side where you might diff --git a/subversion/include/private/svn_subr_private.h b/subversion/include/private/svn_subr_private.h index 095d71c5df2c..d18c564748d0 100644 --- a/subversion/include/private/svn_subr_private.h +++ b/subversion/include/private/svn_subr_private.h @@ -112,12 +112,12 @@ svn_spillbuf__get_size(const svn_spillbuf_t *buf); svn_filesize_t svn_spillbuf__get_memory_size(const svn_spillbuf_t *buf); -/* Retrieve the name of the spill file. The returned value can be NULL - if the file has not been created yet. */ +/* Retrieve the name of the spill file. The returned value will be + NULL if the file has not been created yet. */ const char * svn_spillbuf__get_filename(const svn_spillbuf_t *buf); -/* Retrieve the handle of the spill file. The returned value can be +/* Retrieve the handle of the spill file. The returned value will be NULL if the file has not been created yet. */ apr_file_t * svn_spillbuf__get_file(const svn_spillbuf_t *buf); @@ -133,8 +133,8 @@ svn_spillbuf__write(svn_spillbuf_t *buf, /* Read a block of memory from the spill buffer. @a *data will be set to NULL if no content remains. Otherwise, @a data and @a len will point to data that must be fully-consumed by the caller. This data will remain - valid until another call to svn_spillbuf_write(), svn_spillbuf_read(), - or svn_spillbuf_process(), or if the spill buffer's pool is cleared. */ + valid until another call to svn_spillbuf__write(), svn_spillbuf__read(), + or svn_spillbuf__process(), or if the spill buffer's pool is cleared. */ svn_error_t * svn_spillbuf__read(const char **data, apr_size_t *len, @@ -143,7 +143,7 @@ svn_spillbuf__read(const char **data, /* Callback for reading content out of the spill buffer. Set @a stop if - you want to stop the processing (and will call svn_spillbuf_process + you want to stop the processing (and will call svn_spillbuf__process again, at a later time). */ typedef svn_error_t * (*svn_spillbuf_read_t)(svn_boolean_t *stop, void *baton, @@ -472,7 +472,7 @@ svn_version__parse_version_string(svn_version_t **version, * @since New in 1.8. */ svn_boolean_t -svn_version__at_least(svn_version_t *version, +svn_version__at_least(const svn_version_t *version, int major, int minor, int patch); @@ -525,6 +525,16 @@ svn_version__at_least(svn_version_t *version, unsigned char * svn__encode_uint(unsigned char *p, apr_uint64_t val); +/* Wrapper around svn__encode_uint using the LSB to store the sign: + * + * If VAL >= 0 + * UINT_VAL = 2 * VAL + * else + * UINT_VAL = (- 2 * VAL) - 1 + */ +unsigned char * +svn__encode_int(unsigned char *p, apr_int64_t val); + /* Decode an unsigned 7b/8b-encoded integer into *VAL and return a pointer to the byte after the integer. The bytes to be decoded live in the range [P..END-1]. If these bytes do not contain a whole encoded @@ -537,22 +547,49 @@ svn__decode_uint(apr_uint64_t *val, const unsigned char *p, const unsigned char *end); -/* Get the data from IN, compress it according to the specified - * COMPRESSION_METHOD and write the result to OUT. +/* Wrapper around svn__decode_uint, reversing the transformation performed + * by svn__encode_int. + */ +const unsigned char * +svn__decode_int(apr_int64_t *val, + const unsigned char *p, + const unsigned char *end); + +/* Compress the data from DATA with length LEN, it according to the + * specified COMPRESSION_METHOD and write the result to OUT. * SVN__COMPRESSION_NONE is valid for COMPRESSION_METHOD. */ svn_error_t * -svn__compress(svn_stringbuf_t *in, - svn_stringbuf_t *out, - int compression_method); +svn__compress_zlib(const void *data, apr_size_t len, + svn_stringbuf_t *out, + int compression_method); -/* Get the compressed data from IN, decompress it and write the result to - * OUT. Return an error if the decompressed size is larger than LIMIT. +/* Decompress the compressed data from DATA with length LEN and write the + * result to OUT. Return an error if the decompressed size is larger than + * LIMIT. */ svn_error_t * -svn__decompress(svn_stringbuf_t *in, - svn_stringbuf_t *out, - apr_size_t limit); +svn__decompress_zlib(const void *data, apr_size_t len, + svn_stringbuf_t *out, + apr_size_t limit); + +/* Same as svn__compress_zlib(), but use LZ4 compression. Note that + * while the declaration of this function uses apr_size_t, it expects + * blocks of size not exceeding LZ4_MAX_INPUT_SIZE. The caller should + * ensure that the proper size is passed to this function. + */ +svn_error_t * +svn__compress_lz4(const void *data, apr_size_t len, + svn_stringbuf_t *out); + +/* Same as svn__decompress_zlib(), but use LZ4 compression. The caller + * should ensure that the size and limit passed to this function do not + * exceed INT_MAX. + */ +svn_error_t * +svn__decompress_lz4(const void *data, apr_size_t len, + svn_stringbuf_t *out, + apr_size_t limit); /** @} */ @@ -701,6 +738,14 @@ const char *svn_zlib__compiled_version(void); /* Return the zlib version we run against. */ const char *svn_zlib__runtime_version(void); +/* Return the lz4 version we compiled against. */ +const char *svn_lz4__compiled_version(void); + +/* Return the lz4 version we run against as a composed value: + * major * 100 * 100 + minor * 100 + release + */ +int svn_lz4__runtime_version(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_temp_serializer.h b/subversion/include/private/svn_temp_serializer.h index dd2e0478e21c..6d648b133338 100644 --- a/subversion/include/private/svn_temp_serializer.h +++ b/subversion/include/private/svn_temp_serializer.h @@ -206,7 +206,7 @@ svn_temp_serializer__get(svn_temp_serializer__context_t *context); * the pointer to resolve in @a ptr. */ void -svn_temp_deserializer__resolve(void *buffer, void **ptr); +svn_temp_deserializer__resolve(const void *buffer, void **ptr); /** * Similar to svn_temp_deserializer__resolve() but instead of modifying diff --git a/subversion/include/private/svn_utf_private.h b/subversion/include/private/svn_utf_private.h index 4584944fb47c..473e731141bf 100644 --- a/subversion/include/private/svn_utf_private.h +++ b/subversion/include/private/svn_utf_private.h @@ -150,6 +150,40 @@ svn_utf__normalize(const char **result, const char *str, apr_size_t len, svn_membuf_t *buf); +/* Transform the UTF-8 string to a shape suitable for comparison with + * strcmp(). The tranformation is defined by CASE_INSENSITIVE and + * ACCENT_INSENSITIVE arguments. If CASE_INSENSITIVE is non-zero, + * remove case distinctions from the string. If ACCENT_INSENSITIVE + * is non-zero, remove diacritical marks from the string. + * + * Use BUF as a temporary storage. If LEN is SVN_UTF__UNKNOWN_LENGTH, + * assume STR is null-terminated; otherwise, consider the string only + * up to the given length. Place the tranformed string in *RESULT, which + * shares storage with BUF and is valid only until the next time BUF is + * modified. + * + * A returned error may indicate that STRING contains invalid UTF-8 or + * invalid Unicode codepoints. + */ +svn_error_t * +svn_utf__xfrm(const char **result, + const char *str, apr_size_t len, + svn_boolean_t case_insensitive, + svn_boolean_t accent_insensitive, + svn_membuf_t *buf); + +/* Return TRUE if S matches any of the const char * glob patterns in + * PATTERNS. + * + * S will internally be normalized to lower-case and accents removed + * using svn_utf__xfrm. To get a match, the PATTERNS must have been + * normalized accordingly before calling this function. + */ +svn_boolean_t +svn_utf__fuzzy_glob_match(const char *str, + const apr_array_header_t *patterns, + svn_membuf_t *buf); + /* Check if STRING is a valid, NFC-normalized UTF-8 string. Note that * a FALSE return value may indicate that STRING is not valid UTF-8 at * all. @@ -176,7 +210,7 @@ svn_utf__encode_ucs4_string(svn_membuf_t *buffer, apr_size_t length, apr_size_t *result_length); -/* Pattern matching similar to the the SQLite LIKE and GLOB +/* Pattern matching similar to the SQLite LIKE and GLOB * operators. PATTERN, KEY and ESCAPE must all point to UTF-8 * strings. Furthermore, ESCAPE, if provided, must be a character from * the ASCII subset. diff --git a/subversion/include/private/svn_wc_private.h b/subversion/include/private/svn_wc_private.h index 28d22479118e..521d092be692 100644 --- a/subversion/include/private/svn_wc_private.h +++ b/subversion/include/private/svn_wc_private.h @@ -82,6 +82,8 @@ svn_wc__get_file_external_editor(const svn_delta_editor_t **editor, const char *recorded_url, const svn_opt_revision_t *recorded_peg_rev, const svn_opt_revision_t *recorded_rev, + svn_wc_conflict_resolver_func2_t conflict_func, + void *conflict_baton, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -346,6 +348,20 @@ svn_wc__get_wcroot(const char **wcroot_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool); +/** Set @a *dir to the abspath of the directory in which shelved patches + * are stored, which is inside the WC's administrative directory, and ensure + * the directory exists. + * + * @a local_abspath is any path in the WC, and is used to find the WC root. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_wc__get_shelves_dir(char **dir, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /** * The following are temporary APIs to aid in the transition from wc-1 to * wc-ng. Use them for new development now, but they may be disappearing @@ -1746,6 +1762,207 @@ svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx, void *notify_baton, apr_pool_t *scratch_pool); +/** + * Resolve the text conflict at LOCAL_ABSPATH as per CHOICE, and then + * mark the conflict resolved. + * The working copy must already be locked for resolving, e.g. by calling + * svn_wc__acquire_write_lock_for_resolve() first. + * @since New in 1.10. + */ +svn_error_t * +svn_wc__conflict_text_mark_resolved(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_wc_conflict_choice_t choice, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + +/** + * Resolve the conflicted property PROPNAME at LOCAL_ABSPATH as per CHOICE, + * and then mark the conflict resolved. If MERGED_VALUE is not NULL, this is + * the new merged property, used when choosing #svn_wc_conflict_choose_merged. + * + * The working copy must already be locked for resolving, e.g. by calling + * svn_wc__acquire_write_lock_for_resolve() first. + * @since New in 1.10. + */ +svn_error_t * +svn_wc__conflict_prop_mark_resolved(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *propname, + svn_wc_conflict_choice_t choice, + const svn_string_t *merged_value, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + +/* Resolve a tree conflict where the victim at LOCAL_ABSPATH is a directory + * which was locally deleted, replaced or moved away, and which received an + * arbitrary incoming change during an update or switch operation. + * + * The conflict is resolved by accepting the current working copy state and + * breaking the 'moved-here' link for any files or directories which were + * moved out of the victim directory before the update operation. + * As a result, any such files or directories become copies (rather than moves) + * of content which the victim directory contained before it was updated. + * + * The tree conflict at LOCAL_ABSPATH must have the following properties or + * SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE will be returned: + * + * operation: svn_wc_operation_update or svn_wc_operation_switch + * local change: svn_wc_conflict_reason_deleted or + * svn_wc_conflict_reason_replaced or + * svn_wc_conflict_reason_moved_away + * incoming change: any + * + * The working copy must already be locked for resolving, e.g. by calling + * svn_wc__acquire_write_lock_for_resolve() first. + * + * @since New in 1.10. + */ +svn_error_t * +svn_wc__conflict_tree_update_break_moved_away(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + + +/* Resolve a tree conflict where the victim at LOCAL_ABSPATH is a directory + * which was locally deleted or replaced, and which received an edit (some + * change inside the directory, or a change to the direcotory's properties) + * during an update or switch operation. + * + * The conflict is resolved by keeping the victim deleted, and propagating + * its tree conflict to any children which were moved out of the directory + * before the update operation. + * As a result, any such files or directories become victims of the tree + * conflict as well and must be resolved independently. + * Additionally, LOCAL_ABSPATH itself may become the victim of a different + * tree conflict as a result of resolving the existing tree conflict. + * + * The tree conflict at LOCAL_ABSPATH must have the following properties or + * SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE will be returned: + * + * operation: svn_wc_operation_update or svn_wc_operation_switch + * local change: svn_wc_conflict_reason_deleted or + * svn_wc_conflict_reason_replaced + * incoming change: svn_wc_conflict_action_edit + * + * If this conflict cannot be resolved because the conflict cannot be + * propagated to moved-away children, this function returns + * SVN_ERR_WC_OBSTRUCTED_UPDATE or SVN_ERR_WC_FOUND_CONFLICT. + * The caller should continue by resolving other conflicts and attempt to + * resolve this conflict again later. + * + * The working copy must already be locked for resolving, e.g. by calling + * svn_wc__acquire_write_lock_for_resolve() first. + * + * @since New in 1.10. + */ +svn_error_t * +svn_wc__conflict_tree_update_raise_moved_away(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + +/* Resolve a tree conflict where the victim at LOCAL_ABSPATH is a file or + * directory which was locally moved away, and which received an edit (some + * change inside the directory or file, or a change to properties) during an + * update or switch operation. + * + * The conflict is resolved by keeping the victim moved-away, and propagating + * the incoming edits to the victim's moved-to location. + * + * The tree conflict at LOCAL_ABSPATH must have the following properties or + * SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE will be returned: + * + * operation: svn_wc_operation_update or svn_wc_operation_switch + * local change: svn_wc_conflict_reason_moved_away + * incoming change: svn_wc_conflict_action_edit + * + * If this conflict cannot be resolved this function returns + * SVN_ERR_WC_OBSTRUCTED_UPDATE or SVN_ERR_WC_FOUND_CONFLICT. + * The caller should continue by resolving other conflicts and attempt to + * resolve this conflict again later. + * + * The working copy must already be locked for resolving, e.g. by calling + * svn_wc__acquire_write_lock_for_resolve() first. + * + * @since New in 1.10. + */ +svn_error_t * +svn_wc__conflict_tree_update_moved_away_node(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + +/* Merge local changes from a tree conflict victim of an incoming deletion + * to the specified DEST_ABSPATH added during an update. Both LOCAL_ABSPATH + * and DEST_ABSPATH must be directories. + * + * Assuming DEST_ABSPATH is the correct move destination, this function + * allows local changes to "follow" incoming moves during updates. + * + * @since New in 1.10. */ +svn_error_t * +svn_wc__conflict_tree_update_incoming_move(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *dest_abspath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + +/* Resolve a 'local dir add vs incoming dir add' tree conflict upon update + * by merging the locally added directory with the incoming added directory. + * + * @since New in 1.10. */ +svn_error_t * +svn_wc__conflict_tree_update_local_add(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + +/* Find nodes in the working copy which corresponds to the new location + * MOVED_TO_REPOS_RELPATH of the tree conflict victim at VICTIM_ABSPATH. + * The nodes must be of the same node kind as VICTIM_NODE_KIND. + * If no such node can be found, set *POSSIBLE_TARGETS to an empty array. + * + * The nodes should be useful for conflict resolution, e.g. it should be + * possible to merge changes into these nodes to resolve an incoming-move + * tree conflict. But the exact criteria for selecting a node are left + * to the implementation of this function. + * Note that this function may not necessarily return a node which was + * actually moved. The only hard guarantee is that the node corresponds to + * the repository relpath MOVED_TO_REPOS_RELPATH specified by the caller. + * Users should perform a sanity check on the results returned from this + * function, e.g. establish whether the MOVED_TO_REPOS_RELPATH at its + * current checked-out revision shares ancestry with the conflict victim. + */ +svn_error_t * +svn_wc__guess_incoming_move_target_nodes(apr_array_header_t **possible_targets, + svn_wc_context_t *wc_ctx, + const char *victim_abspath, + svn_node_kind_t victim_node_kind, + const char *moved_to_repos_relpath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /** * Move @a src_abspath to @a dst_abspath, by scheduling @a dst_abspath * for addition to the repository, remembering the history. Mark @a src_abspath @@ -1847,6 +2064,28 @@ svn_wc__diff7(const char **root_relpath, apr_pool_t *result_pool, apr_pool_t *scratch_pool); +/** + * Read all conflicts at LOCAL_ABSPATH into an array containing pointers to + * svn_wc_conflict_description2_t data structures alloated in RESULT_POOL. + */ +svn_error_t * +svn_wc__read_conflict_descriptions2_t(const apr_array_header_t **conflicts, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Internal version of svn_wc_translated_stream(), accepting a working + copy context. */ +svn_error_t * +svn_wc__translated_stream(svn_stream_t **stream, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *versioned_abspath, + apr_uint32_t flags, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/svn_auth.h b/subversion/include/svn_auth.h index 3a78ba6ace5f..ca3b703a4970 100644 --- a/subversion/include/svn_auth.h +++ b/subversion/include/svn_auth.h @@ -1012,11 +1012,13 @@ typedef svn_error_t *(*svn_auth_gnome_keyring_unlock_prompt_func_t)( /** @brief The pointer to function which prompts user for GNOME Keyring * password. - * The type of this pointer should be svn_auth_gnome_keyring_unlock_prompt_func_t. */ + * The type of this pointer should be svn_auth_gnome_keyring_unlock_prompt_func_t. + * @deprecated Only used by old libgnome-keyring implementation. */ #define SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC "gnome-keyring-unlock-prompt-func" /** @brief The baton which is passed to - * @c *SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC. */ + * @c *SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC. + * @deprecated Only used by old libgnome-keyring implementation. */ #define SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON "gnome-keyring-unlock-prompt-baton" #if (!defined(DARWIN) && !defined(WIN32)) || defined(DOXYGEN) @@ -1037,7 +1039,7 @@ svn_auth_gnome_keyring_version(void); * This is like svn_client_get_simple_provider(), except that the * password is stored in GNOME Keyring. * - * If the GNOME Keyring is locked the provider calls + * If the GNOME Keyring is locked the old libgnome-keyring provider calls * @c *SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC in order to unlock * the keyring. * diff --git a/subversion/include/svn_base64.h b/subversion/include/svn_base64.h index cc1820fb93cf..90316afba334 100644 --- a/subversion/include/svn_base64.h +++ b/subversion/include/svn_base64.h @@ -46,11 +46,26 @@ extern "C" { */ /** Return a writable generic stream which will encode binary data in - * base64 format and write the encoded data to @a output. Be sure to - * close the stream when done writing in order to squeeze out the last - * bit of encoded data. The stream is allocated in @a pool. + * base64 format and write the encoded data to @a output. If @a break_lines + * is true, newlines will be inserted periodically; otherwise the output + * stream will only consist of base64 encoding characters. Be sure to close + * the stream when done writing in order to squeeze out the last bit of + * encoded data. The stream is allocated in @a pool. + * + * @since New in 1.10. */ svn_stream_t * +svn_base64_encode2(svn_stream_t *output, + svn_boolean_t break_lines, + apr_pool_t *pool); + +/** + * Same as svn_base64_encode2, but with @a break_lines always TRUE. + * + * @deprecated Provided for backward compatibility with the 1.9 API. + */ +SVN_DEPRECATED +svn_stream_t * svn_base64_encode(svn_stream_t *output, apr_pool_t *pool); diff --git a/subversion/include/svn_checksum.h b/subversion/include/svn_checksum.h index e332e87e328d..1e58167ab068 100644 --- a/subversion/include/svn_checksum.h +++ b/subversion/include/svn_checksum.h @@ -177,6 +177,10 @@ svn_checksum_deserialize(const svn_checksum_t **checksum, * * @since New in 1.6. */ +/* ### TODO: When revving this, make it set @a *checksum to a non-NULL struct + * ### when @a hex is the all-zeroes checksum. See + * ### http://mail-archives.apache.org/mod_mbox/subversion-dev/201609.mbox/%3c00cd26ab-bdb3-67b4-ca6b-063266493874%40apache.org%3e + */ svn_error_t * svn_checksum_parse_hex(svn_checksum_t **checksum, svn_checksum_kind_t kind, @@ -219,6 +223,15 @@ svn_checksum_ctx_create(svn_checksum_kind_t kind, apr_pool_t *pool); /** + * Reset an existing checksum @a ctx to initial state. + * @see svn_checksum_ctx_create() + * + * @since New in 1.10. + */ +svn_error_t * +svn_checksum_ctx_reset(svn_checksum_ctx_t *ctx); + +/** * Update the checksum represented by @a ctx, with @a len bytes starting at * @a data. * diff --git a/subversion/include/svn_client.h b/subversion/include/svn_client.h index cb0f49d98d49..06dbbc35a7b3 100644 --- a/subversion/include/svn_client.h +++ b/subversion/include/svn_client.h @@ -1975,7 +1975,7 @@ typedef svn_error_t *(*svn_client_import_filter_func_t)( * on @a url if @a url is already under versioned control, or the nearest parents * of @a path which are already under version control if not. * - * If @a ignore_unknown_node_types is @c FALSE, ignore files of which the + * If @a ignore_unknown_node_types is @c TRUE, ignore files of which the * node type is unknown, such as device files and pipes. * * If @a filter_callback is non-NULL, call it for each node that isn't ignored @@ -4356,6 +4356,760 @@ svn_client_revert(const apr_array_header_t *paths, /** @} */ /** + * @defgroup Conflicts Dealing with conflicted paths. + * + * @{ + */ + +/** + * An opaque type which represents a conflicted node in the working copy. + * + * @since New in 1.10. + */ +typedef struct svn_client_conflict_t svn_client_conflict_t; + +/** + * An opaque type which represents a resolution option for a conflict. + * + * @since New in 1.10. + */ +typedef struct svn_client_conflict_option_t svn_client_conflict_option_t; + +/** + * A public enumeration of conflict option IDs. + * + * @since New in 1.10, unless noted otherwise. + */ +typedef enum svn_client_conflict_option_id_t { + + /* Options for text and property conflicts. + * These values intentionally mirror svn_wc_conflict_choice_t. */ + svn_client_conflict_option_undefined = -1, /* for private use only */ + svn_client_conflict_option_postpone = 0, + svn_client_conflict_option_base_text, + svn_client_conflict_option_incoming_text, /* "theirs-full" */ + svn_client_conflict_option_working_text, /* "mine-full" */ + svn_client_conflict_option_incoming_text_where_conflicted, + svn_client_conflict_option_working_text_where_conflicted, + svn_client_conflict_option_merged_text, + svn_client_conflict_option_unspecified, + /* Values derived from svn_wc_conflict_choice_t end here. */ + + /* Tree conflict resolution options start here. */ + + /* Accept current working copy state. */ + svn_client_conflict_option_accept_current_wc_state, + + /* Options for local move vs incoming edit on update. */ + svn_client_conflict_option_update_move_destination, + + /* Options for local delete/replace vs incoming edit on update. */ + svn_client_conflict_option_update_any_moved_away_children, + + /* Options for incoming add vs local add or obstruction. */ + svn_client_conflict_option_incoming_add_ignore, + + /* Options for incoming file add vs local file add or obstruction. */ + svn_client_conflict_option_incoming_added_file_text_merge, + svn_client_conflict_option_incoming_added_file_replace_and_merge, + + /* Options for incoming dir add vs local dir add or obstruction. */ + svn_client_conflict_option_incoming_added_dir_merge, + svn_client_conflict_option_incoming_added_dir_replace, + svn_client_conflict_option_incoming_added_dir_replace_and_merge, + + /* Options for incoming delete vs any */ + svn_client_conflict_option_incoming_delete_ignore, + svn_client_conflict_option_incoming_delete_accept, + + /* Options for incoming move vs local edit */ + svn_client_conflict_option_incoming_move_file_text_merge, + svn_client_conflict_option_incoming_move_dir_merge, + + /* Options for local move vs incoming edit on merge. */ + svn_client_conflict_option_local_move_file_text_merge +} svn_client_conflict_option_id_t; + +/** + * Set a merged property value on @a option to @a merged_propval. + * + * Setting the merged value is required before resolving the property + * conflict using an option with ID svn_client_conflict_option_merged_text. + * + * The contents of @a merged_propval are not copied, so the storage it + * points to needs to remain valid until svn_client_conflict_prop_resolve() + * has been called with @a option. + * + * @since New in 1.10. + */ +void +svn_client_conflict_option_set_merged_propval( + svn_client_conflict_option_t *option, + const svn_string_t *merged_propval); + +/** + * Get a list of possible repository paths which can be applied to the + * svn_client_conflict_option_incoming_move_file_text_merge or + * svn_client_conflict_option_incoming_move_dir_merge resolution + * @a option. (If a different option is passed in, this function will + * raise an assertion failure.) + * + * In some situations, there can be multiple possible destinations for an + * incoming move. One such situation is where a file was copied and moved + * in the same revision: svn cp a b; svn mv a c; svn commit + * When this move is merged elsewhere, both b and c will appear as valid move + * destinations to the conflict resolver. To resolve such ambiguity, the client + * may call this function to obtain a list of possible destinations the user + * may choose from. + * + * The array is allocated in @a result_pool and will have "const char *" + * elements pointing to strings also allocated in @a result_pool. + * All paths are relpaths, and relative to the repository root. + * + * @see svn_client_conflict_option_set_moved_to_repos_relpath() + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_option_get_moved_to_repos_relpath_candidates( + apr_array_header_t **possible_moved_to_repos_relpaths, + svn_client_conflict_option_t *option, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Set the preferred moved target repository path for the + * svn_client_conflict_option_incoming_move_file_text_merge or + * svn_client_conflict_option_incoming_move_dir_merge resolution option. + * + * @a preferred_move_target_idx must be a valid index into the list returned + * by svn_client_conflict_option_get_moved_to_repos_relpath_candidates(). + * + * This function can be called multiple times. + * It affects the output of svn_client_conflict_tree_get_description() and + * svn_client_conflict_option_get_description(). Call these functions again + * to get updated descriptions containing the newly selected move target. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_option_set_moved_to_repos_relpath( + svn_client_conflict_option_t *option, + int preferred_move_target_idx, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * Get a list of possible moved-to abspaths in the working copy which can be + * applied to the svn_client_conflict_option_incoming_move_file_text_merge + * or svn_client_conflict_option_incoming_move_dir_merge resolution @a option. + * (If a different option is passed in, this function will raise an assertion + * failure.) + * + * All paths in the returned list correspond to the repository path which + * is assumed to be the destination of the incoming move operation. + * To support cases where this destination path is ambiguous, the client may + * call svn_client_conflict_option_get_moved_to_repos_relpath_candidates() + * before calling this function to let the user select a repository path first. + * + * If no possible moved-to paths can be found, return an empty array. + * This doesn't mean that no move happened in the repository. It is possible + * that the move destination is outside the scope of the current working copy, + * for example, in which case the conflict must be resolved in some other way. + * + * @see svn_client_conflict_option_set_moved_to_abspath() + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_option_get_moved_to_abspath_candidates( + apr_array_header_t **possible_moved_to_abspaths, + svn_client_conflict_option_t *option, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Set the preferred moved target abspath for the + * svn_client_conflict_option_incoming_move_file_text_merge or + * svn_client_conflict_option_incoming_move_dir_merge resolution option. + * + * @a preferred_move_target_idx must be a valid index into the list + * returned by svn_client_conflict_option_get_moved_to_abspath_candidates(). + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_option_set_moved_to_abspath( + svn_client_conflict_option_t *option, + int preferred_move_target_idx, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * Given an @a option_id, try to find the corresponding option in @a options, + * which is an array of svn_client_conflict_option_t * elements. + * + * Return NULL if no corresponding option can be be found. + * + * @since New in 1.10. + */ +svn_client_conflict_option_t * +svn_client_conflict_option_find_by_id( + apr_array_header_t *options, + svn_client_conflict_option_id_t option_id); + +/** + * Return a conflict for the conflicted path @a local_abspath. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_get(svn_client_conflict_t **conflict, + const char *local_abspath, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Callback for svn_client_conflict_conflict_walk(); + * + * The lifetime of @a conflict is limited. Its allocation in + * memory will not persist beyond this callback's execution. + * + * @since New in 1.10. + */ +typedef svn_error_t *(*svn_client_conflict_walk_func_t)( + void *baton, + svn_client_conflict_t *conflict, + apr_pool_t *scratch_pool); + +/** + * Walk all conflicts within the specified @a depth of @a local_abspath. + * Pass each conflict found during the walk to the @conflict_walk_func + * callback, along with @a conflict_walk_func_baton. + * Use cancellation and notification support provided by client context @a ctx. + * + * This callback may choose to resolve the conflict. If the act of resolving + * a conflict creates new conflicts within the walked working copy (as might + * be the case for some tree conflicts), the callback will be invoked for each + * such new conflict as well. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_walk(const char *local_abspath, + svn_depth_t depth, + svn_client_conflict_walk_func_t conflict_walk_func, + void *conflict_walk_func_baton, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** +* Indicate the types of conflicts present on the working copy node +* described by @a conflict. Any output argument may be @c NULL if +* the caller is not interested in the status of a particular type. +* +* The returned @a *props_conflicted array is allocated in @a result_pool. +* It contains the names of conflicted properties. If no property conflict +* exists, the array will contain no elements. +* +* @since New in 1.10. +*/ +svn_error_t * +svn_client_conflict_get_conflicted(svn_boolean_t *text_conflicted, + apr_array_header_t **props_conflicted, + svn_boolean_t *tree_conflicted, + svn_client_conflict_t *conflict, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Return a textual human-readable description of the property conflict + * described by @a conflict, allocated in @a result_pool. The description + * is encoded in UTF-8 and may contain multiple lines separated by + * @c APR_EOL_STR. The last line is not terminated by a newline. + * + * Additionally, the description may be localized to the language used + * by the current locale. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_prop_get_description(const char **description, + svn_client_conflict_t *conflict, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Return a textual human-readable description of the tree conflict + * described by @a conflict, allocated in @a result_pool. The description + * is encoded in UTF-8 and may contain multiple lines separated by + * @c APR_EOL_STR. The last line is not terminated by a newline. + * + * Additionally, the description may be localized to the language used + * by the current locale. + * + * While client implementors are free to enhance descriptions by adding + * additional information to the text, or break up very long lines for + * formatting purposes, there is no syntax defined for descriptions, and + * implementors should not rely on any particular parts of descriptions + * to remain stable over time, apart from what is stated below. + * Descriptions may or may not form complete sentences. They may contain + * paths relative to the repository root; such paths always start with "^/", + * and end with either a peg revision (e.g. "@100") or a colon followed by + * a range of revisions (as in svn:mergeinfo, e.g. ":100-200"). + * Paths may appear on a line of their own to avoid overlong lines. + * Any revision numbers mentioned elsewhere in the description are + * prefixed with the letter 'r' (e.g. "r99"). + * + * The description has two parts: One part describes the "incoming change" + * applied by an update, merge, or switch operation. The other part + * describes the "local change" which occurred in the working copy or + * perhaps in the history of a merge target branch. + * Both parts are provided independently to allow for some flexibility + * when displaying the description. As a convention, displaying the + * "incoming change" first and the "local change" second is recommended. + * + * By default, the description is based only on information available in + * the working copy. If svn_client_conflict_tree_get_details() was already + * called for @a conflict, the description might also contain useful + * information obtained from the repository and provide for a much better + * user experience. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_tree_get_description( + const char **incoming_change_description, + const char **local_change_description, + svn_client_conflict_t *conflict, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Set @a *options to an array of pointers to svn_client_conflict_option_t + * objects applicable to text conflicts described by @a conflict. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_text_get_resolution_options(apr_array_header_t **options, + svn_client_conflict_t *conflict, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Set @a *options to an array of pointers to svn_client_conflict_option_t + * objects applicable to property conflicts described by @a conflict. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_prop_get_resolution_options(apr_array_header_t **options, + svn_client_conflict_t *conflict, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Set @a *options to an array of pointers to svn_client_conflict_option_t + * objects applicable to the tree conflict described by @a conflict. + * + * By default, the list of options is based only on information available in + * the working copy. If svn_client_conflict_tree_get_details() was already + * called for @a conflict, a more useful list of options might be returned. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_tree_get_resolution_options(apr_array_header_t **options, + svn_client_conflict_t *conflict, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Find more information about the tree conflict represented by @a conflict. + * + * A call to svn_client_conflict_tree_get_description() may yield much better + * results after this function has been called. + * + * A call to svn_client_conflict_tree_get_resolution_options() may provide + * more useful resolution options if this function has been called. + * + * This function may contact the repository. Use the authentication baton + * cached in @a ctx for authentication if contacting the repository. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_tree_get_details(svn_client_conflict_t *conflict, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * Return an ID for @a option. This ID can be used by callers to associate + * arbitrary data with a particular conflict resolution option. + * + * The ID of a particular resolution option will never change in future + * revisions of this API. + * + * @since New in 1.10. + */ +svn_client_conflict_option_id_t +svn_client_conflict_option_get_id(svn_client_conflict_option_t *option); + +/** + * Return a textual human-readable label of @a option, allocated in + * @a result_pool. The label is encoded in UTF-8 and usually + * contains up to three words. + * + * Additionally, the label may be localized to the language used + * by the current locale. + * + * @since New in 1.10. + */ +const char * +svn_client_conflict_option_get_label(svn_client_conflict_option_t *option, + apr_pool_t *result_pool); + +/** + * Return a textual human-readable description of @a option, allocated in + * @a result_pool. The description is encoded in UTF-8 and may contain + * multiple lines separated by @c APR_EOL_STR. + * + * Additionally, the description may be localized to the language used + * by the current locale. + * + * @since New in 1.10. + */ +const char * +svn_client_conflict_option_get_description(svn_client_conflict_option_t *option, + apr_pool_t *result_pool); + +/** + * Return the ID of the recommended resolution option. If no specific option + * is recommended, return @c svn_client_conflict_option_unspecified; + * + * Client implementations which aim to avoid excessive interactive prompting + * may wish to try a recommended resolution option before falling back to + * asking the user which option to use. + * + * Conflict resolution with a recommended option is not guaranteed to succeed. + * Clients should check for errors when trying to resolve a conflict and fall + * back to other options and/or interactive prompting when the recommended + * option fails to resolve a conflict. + * + * If @a conflict is a tree conflict, svn_client_conflict_tree_get_details() + * should be called before this function to allow for useful recommendations. + * + * @since New in 1.10. + */ +svn_client_conflict_option_id_t +svn_client_conflict_get_recommended_option_id(svn_client_conflict_t *conflict); + +/** + * Return the absolute path to the conflicted working copy node described + * by @a conflict. + * + * @since New in 1.10. + */ +const char * +svn_client_conflict_get_local_abspath(svn_client_conflict_t *conflict); + +/** + * Return the operation during which the conflict described by @a + * conflict was recorded. + * + * @since New in 1.10. + */ +svn_wc_operation_t +svn_client_conflict_get_operation(svn_client_conflict_t *conflict); + +/** + * Return the action an update, switch, or merge operation attempted to + * perform on the working copy node described by @a conflict. + * + * @since New in 1.10. + */ +svn_wc_conflict_action_t +svn_client_conflict_get_incoming_change(svn_client_conflict_t *conflict); + +/** + * Return the reason why the attempted action performed by an update, switch, + * or merge operation conflicted with the state of the node in the working copy. + * + * During update and switch operations this local change is part of uncommitted + * modifications in the working copy. During merge operations it may + * additionally be part of the history of the merge target branch, anywhere + * between the common ancestor revision and the working copy revision. + * + * @since New in 1.10. + */ +svn_wc_conflict_reason_t +svn_client_conflict_get_local_change(svn_client_conflict_t *conflict); + +/** + * Return information about the repository associated with @a conflict. + * In case of a foreign-repository merge this will differ from the + * repository information associated with the merge target working copy. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_get_repos_info(const char **repos_root_url, + const char **repos_uuid, + svn_client_conflict_t *conflict, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Return the repository-relative location and the node kind of the incoming + * old version of the conflicted node described by @a conflict. + * + * If the repository-relative path is not available, the @a + * *incoming_old_repos_relpath will be set to @c NULL, + * + * If the peg revision is not available, @a *incoming_old_regrev will be + * set to SVN_INVALID_REVNUM. + * + * If the node kind is not available or if the node does not exist at the + * specified path and revision, @a *incoming_old_node_kind will be set to + * svn_node_none. + * ### Should return svn_node_unkown if not available? + * + * Any output parameter may be set to @c NULL by the caller to indicate that + * a particular piece of information should not be returned. + * + * In case of tree conflicts, this path@revision does not necessarily exist + * in the repository, and it does not necessarily represent the incoming + * change which is responsible for the occurance of the tree conflict. + * The responsible incoming change is generally located somewhere between + * the old and new incoming versions. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_get_incoming_old_repos_location( + const char **incoming_old_repos_relpath, + svn_revnum_t *incoming_old_regrev, + svn_node_kind_t *incoming_old_node_kind, + svn_client_conflict_t *conflict, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Like svn_client_conflict_get_incoming_old_repos_location(), expect this + * function returns the same data for the incoming new version. + * + * The same note about tree conflicts applies. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_get_incoming_new_repos_location( + const char **incoming_new_repos_relpath, + svn_revnum_t *incoming_new_regrev, + svn_node_kind_t *incoming_new_node_kind, + svn_client_conflict_t *conflict, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Return the node kind of the tree conflict victim described by @a conflict. + * The victim is the local node in the working copy which was affected by the + * tree conflict at the time the conflict was raised. + * + * @since New in 1.10. + */ +svn_node_kind_t +svn_client_conflict_tree_get_victim_node_kind(svn_client_conflict_t *conflict); + +/** + * Resolve a tree @a conflict using resolution option @a option. + * + * May raise an error in case the tree conflict cannot be resolved yet, for + * instance @c SVN_ERR_WC_OBSTRUCTED_UPDATE, @c SVN_ERR_WC_FOUND_CONFLICT, + * or @c SVN_ERR_WC_CONFLICT_RESOLVER_FAILUE. + * This may happen when other tree conflicts, or unversioned obstructions, + * block the resolution of this tree conflict. In such a case the other + * conflicts should be resolved first and resolution of this conflict should + * be attempted again later. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_tree_resolve(svn_client_conflict_t *conflict, + svn_client_conflict_option_t *option, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * Like svn_client_conflict_tree_resolve(), except that it identifies + * the desired resolution option by ID @a option_id. + * + * If the provided @a option_id is the ID of an option which resolves + * @a conflict, try to resolve the tree conflict using that option. + * Else, return @c SVN_ERR_CLIENT_CONFLICT_OPTION_NOT_APPLICABLE. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_tree_resolve_by_id( + svn_client_conflict_t *conflict, + svn_client_conflict_option_id_t option_id, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * Return the ID of the option this tree @a conflict has been resolved to. + * If the conflict has not been resolved yet, then return + * @c svn_client_conflict_option_unspecified. + * + * @since New in 1.10. + */ +svn_client_conflict_option_id_t +svn_client_conflict_tree_get_resolution(svn_client_conflict_t *conflict); + +/** + * Return the path to the legacy property conflicts reject file + * for the property conflicts represented by @a conflict. + * + * This function exists for backwards compatibility only and should not be + * used in new code. + * + * @since New in 1.10. + */ +const char * +svn_client_conflict_prop_get_reject_abspath(svn_client_conflict_t *conflict); + +/** + * Return the set of property values involved in the conflict of property + * PROPNAME described by @a conflict. If a property value is unavailable the + * corresponding output argument is set to @c NULL. + * + * A 3-way diff of these property values can be generated with + * svn_diff_mem_string_diff3(). A merged version with conflict + * markers can be generated with svn_diff_mem_string_output_merge3(). + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_prop_get_propvals(const svn_string_t **base_propval, + const svn_string_t **working_propval, + const svn_string_t **incoming_old_propval, + const svn_string_t **incoming_new_propval, + svn_client_conflict_t *conflict, + const char *propname, + apr_pool_t *result_pool); + +/** + * Resolve a property @a conflict in property @a propname using resolution + * option @a option. To resolve all properties to the same option at once, + * set @a propname to the empty string "". + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_prop_resolve(svn_client_conflict_t *conflict, + const char *propname, + svn_client_conflict_option_t *option, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); +/** + * If the provided @a option_id is the ID of an option which resolves + * @a conflict, resolve the property conflict in property @a propname + * using that option. + * Else, return @c SVN_ERR_CLIENT_CONFLICT_OPTION_NOT_APPLICABLE. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_prop_resolve_by_id( + svn_client_conflict_t *conflict, + const char *propname, + svn_client_conflict_option_id_t option_id, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * Return the ID of the option this property @a conflict in property + * @a propname has been resolved to. + * If the conflict has not been resolved yet, then return + * @c svn_client_conflict_option_unspecified. + * + * @since New in 1.10. + */ +svn_client_conflict_option_id_t +svn_client_conflict_prop_get_resolution(svn_client_conflict_t *conflict, + const char *propname); + +/** + * Return the MIME-type of the working version of the text-conflicted file + * described by @a conflict. + * + * ### Really needed? What about base/incoming_old/incoming_new values? + * @since: New in 1.10. + */ +const char * +svn_client_conflict_text_get_mime_type(svn_client_conflict_t *conflict); + +/** + * Return absolute paths to the versions of the text-conflicted file + * described by @a conflict. + * + * If a particular content is not available, it is set to @c NULL. + * + * ### Should this be returning svn_stream_t instead of paths? + * @since: New in 1.10. + */ +svn_error_t * +svn_client_conflict_text_get_contents(const char **base_abspath, + const char **working_abspath, + const char **incoming_old_abspath, + const char **incoming_new_abspath, + svn_client_conflict_t *conflict, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Resolve a text @a conflict using resolution option @a option. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_text_resolve(svn_client_conflict_t *conflict, + svn_client_conflict_option_t *option, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * If the provided @a option_id is the ID of an option which resolves + * @a conflict, resolve the text conflict using that option. + * Else, return @c SVN_ERR_CLIENT_CONFLICT_OPTION_NOT_APPLICABLE. + * + * @since New in 1.10. + */ +svn_error_t * +svn_client_conflict_text_resolve_by_id( + svn_client_conflict_t *conflict, + svn_client_conflict_option_id_t option_id, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** + * Return the ID of the option this text @a conflict has been resolved to. + * If the conflict has not been resolved yet, then return + * @c svn_client_conflict_option_unspecified. + * + * @since New in 1.10. + */ +svn_client_conflict_option_id_t +svn_client_conflict_text_get_resolution(svn_client_conflict_t *conflict); + +/** @} */ + +/** * @defgroup Resolved Mark conflicted paths as resolved. * * @{ @@ -4402,7 +5156,11 @@ svn_client_resolved(const char *path, * - svn_wc_conflict_choose_unspecified * invoke @a ctx->conflict_func2 with @a ctx->conflict_baton2 to obtain * a resolution decision for each conflict. This can be used to - * implement interactive conflict resolution. + * implement interactive conflict resolution but is NOT RECOMMENDED for + * new code. To perform conflict resolution based on interactive user + * input on a per-conflict basis, use svn_client_conflict_text_resolve(), + * svn_client_conflict_prop_resolve(), and + * svn_client_conflict_tree_resolve() instead of svn_client_resolve(). * * #svn_wc_conflict_choose_theirs_conflict and * #svn_wc_conflict_choose_mine_conflict are not legal for binary @@ -5493,8 +6251,7 @@ svn_client_revprop_list(apr_hash_t **props, * #svn_opt_revision_unspecified, then it defaults to #svn_opt_revision_head * for URLs or #svn_opt_revision_working for WC targets. * - * @a revision is the revision that should be exported, which is only used - * when exporting from a repository. + * @a revision is the revision that should be exported. * * @a peg_revision and @a revision must not be @c NULL. * @@ -5706,13 +6463,18 @@ typedef svn_error_t *(*svn_client_list_func_t)(void *baton, * its children. If @a path_or_url is non-existent, return * #SVN_ERR_FS_NOT_FOUND. * + * If the @a patterns array of <tt>const char *</tt> is not @c NULL, only + * report paths whose last segment matches one of the specified glob + * patterns. This does not affect the size of the tree nor the number of + * externals being covered. + * * If @a fetch_locks is TRUE, include locks when reporting directory entries. * * If @a include_externals is TRUE, also list all external items * reached by recursion. @a depth value passed to the original list target * applies for the externals also. * - * Use @a pool for temporary allocations. + * Use @a scratch_pool for temporary allocations. * * Use authentication baton cached in @a ctx to authenticate against the * repository. @@ -5728,8 +6490,29 @@ typedef svn_error_t *(*svn_client_list_func_t)(void *baton, * otherwise simply bitwise OR together the combination of @c SVN_DIRENT_ * fields you care about. * + * @since New in 1.10. + */ +svn_error_t * +svn_client_list4(const char *path_or_url, + const svn_opt_revision_t *peg_revision, + const svn_opt_revision_t *revision, + const apr_array_header_t *patterns, + svn_depth_t depth, + apr_uint32_t dirent_fields, + svn_boolean_t fetch_locks, + svn_boolean_t include_externals, + svn_client_list_func2_t list_func, + void *baton, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** Similar to svn_client_list4(), but with @a patterns set to @c NULL. + * * @since New in 1.8. + * + * @deprecated Provided for backwards compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_client_list3(const char *path_or_url, const svn_opt_revision_t *peg_revision, @@ -5747,9 +6530,9 @@ svn_client_list3(const char *path_or_url, /** Similar to svn_client_list3(), but with @a include_externals set * to FALSE, and using a #svn_client_list_func_t as callback. * - * @deprecated Provided for backwards compatibility with the 1.7 API. - * * @since New in 1.5. + * + * @deprecated Provided for backwards compatibility with the 1.7 API. */ SVN_DEPRECATED svn_error_t * @@ -5932,6 +6715,153 @@ svn_client_cat(svn_stream_t *out, +/** Shelving commands + * + * @defgroup svn_client_shelve_funcs Client Shelving Functions + * @{ + */ + +/** Shelve a change. + * + * Shelve as @a name the local modifications found by @a paths, @a depth, + * @a changelists. Revert the shelved change from the WC unless @a keep_local + * is true. + * + * If @a dry_run is true, don't actually do it. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_client_shelve(const char *name, + const apr_array_header_t *paths, + svn_depth_t depth, + const apr_array_header_t *changelists, + svn_boolean_t keep_local, + svn_boolean_t dry_run, + svn_client_ctx_t *ctx, + apr_pool_t *pool); + +/** Unshelve the shelved change @a name. + * + * @a local_abspath is any path in the WC and is used to find the WC root. + * Rename the shelved patch to add a '.bak' extension unless @a keep is true. + * + * If @a dry_run is true, don't actually do it. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_client_unshelve(const char *name, + const char *local_abspath, + svn_boolean_t keep, + svn_boolean_t dry_run, + svn_client_ctx_t *ctx, + apr_pool_t *pool); + +/** Delete the shelved patch @a name. + * + * @a local_abspath is any path in the WC and is used to find the WC root. + * + * If @a dry_run is true, don't actually do it. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_client_shelves_delete(const char *name, + const char *local_abspath, + svn_boolean_t dry_run, + svn_client_ctx_t *ctx, + apr_pool_t *pool); + +/** Information about a shelved patch. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +typedef struct svn_client_shelved_patch_info_t +{ + const char *message; /* first line of log message */ + const char *patch_path; /* abspath of the patch file */ + svn_io_dirent2_t *dirent; /* info about the patch file */ + apr_time_t mtime; /* a copy of dirent->mtime */ +} svn_client_shelved_patch_info_t; + +/** Set @a *shelved_patch_infos to a hash, keyed by patch name, of pointers to + * @c svn_client_shelved_patch_info_t structures. + * + * @a local_abspath is any path in the WC and is used to find the WC root. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_client_shelves_list(apr_hash_t **shelved_patch_infos, + const char *local_abspath, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Set @a *any_shelved to indicate if there are any shelved changes in this WC. + * + * This shall provide the answer fast, regardless of how many changes + * are stored, unlike svn_client_shelves_list(). + * + * ### Initial implementation isn't O(1) fast -- it just calls + * svn_client_shelves_list(). + * + * @a local_abspath is any path in the WC and is used to find the WC root. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_client_shelves_any(svn_boolean_t *any_shelved, + const char *local_abspath, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** Set @a *affected_paths to a hash with one entry for each path affected + * by the shelf @a name. The hash key is the old path and value is + * the new path, both relative to the WC root. The key and value are the + * same except when a path is moved or copied. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_client_shelf_get_paths(apr_hash_t **affected_paths, + const char *name, + const char *local_abspath, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Set @a *has_changes to indicate whether the shelf @a name + * contains any modifications, in other words if svn_client_shelf_get_paths() + * would return a non-empty set of paths. + * + * @since New in 1.10. + * @warning EXPERIMENTAL. + */ +SVN_EXPERIMENTAL +svn_error_t * +svn_client_shelf_has_changes(svn_boolean_t *has_changes, + const char *name, + const char *local_abspath, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + +/** @} */ + /** Changelist commands * * @defgroup svn_client_changelist_funcs Client Changelist Functions diff --git a/subversion/include/svn_cmdline.h b/subversion/include/svn_cmdline.h index 923aeee6235a..2789aa411310 100644 --- a/subversion/include/svn_cmdline.h +++ b/subversion/include/svn_cmdline.h @@ -374,6 +374,7 @@ svn_cmdline_create_auth_baton2(svn_auth_baton_t **ab, * @deprecated Provided for backward compatibility with the 1.8 API. * @since New in 1.6. */ +SVN_DEPRECATED svn_error_t * svn_cmdline_create_auth_baton(svn_auth_baton_t **ab, svn_boolean_t non_interactive, diff --git a/subversion/include/svn_config.h b/subversion/include/svn_config.h index 5ad3b0bae234..d194af09efbf 100644 --- a/subversion/include/svn_config.h +++ b/subversion/include/svn_config.h @@ -63,6 +63,12 @@ typedef struct svn_config_t svn_config_t; * @{ */ +/* If you add a new SVN_CONFIG_* category/section/option macro to this group, + * you have to re-run gen-make.py manually. + * + * ### This should be fixed in the build system; see issue #4581. + */ + /* This list of #defines is intentionally presented as a nested list that matches the in-config hierarchy. */ diff --git a/subversion/include/svn_dav.h b/subversion/include/svn_dav.h index e9092d541938..9af9bc58f7ed 100644 --- a/subversion/include/svn_dav.h +++ b/subversion/include/svn_dav.h @@ -386,6 +386,41 @@ extern "C" { #define SVN_DAV_NS_DAV_SVN_REVERSE_FILE_REVS\ SVN_DAV_PROP_NS_DAV "svn/reverse-file-revs" +/** Presence of this in a DAV header in an OPTIONS response indicates + * that the transmitter (in this case, the server) knows how to handle + * svndiff1 format encoding. + * + * @since New in 1.10. + */ +#define SVN_DAV_NS_DAV_SVN_SVNDIFF1\ + SVN_DAV_PROP_NS_DAV "svn/svndiff1" + +/** Presence of this in a DAV header in an OPTIONS response indicates + * that the transmitter (in this case, the server) knows how to handle + * 'list' requests. + * + * @since New in 1.10. + */ +#define SVN_DAV_NS_DAV_SVN_LIST\ + SVN_DAV_PROP_NS_DAV "svn/list" + +/** Presence of this in a DAV header in an OPTIONS response indicates + * that the transmitter (in this case, the server) knows how to handle + * svndiff2 format encoding. + * + * @since New in 1.10. + */ +#define SVN_DAV_NS_DAV_SVN_SVNDIFF2\ + SVN_DAV_PROP_NS_DAV "svn/svndiff2" + +/** Presence of this in a DAV header in an OPTIONS response indicates + * that the transmitter (in this case, the server) sends the result + * checksum in the response to a successful PUT request. + * + * @since New in 1.10. + */ +#define SVN_DAV_NS_DAV_SVN_PUT_RESULT_CHECKSUM\ + SVN_DAV_PROP_NS_DAV "svn/put-result-checksum" /** @} */ diff --git a/subversion/include/svn_delta.h b/subversion/include/svn_delta.h index d949ced66b8b..c15788ee4d00 100644 --- a/subversion/include/svn_delta.h +++ b/subversion/include/svn_delta.h @@ -330,6 +330,18 @@ typedef svn_error_t * typedef const unsigned char * (*svn_txdelta_md5_digest_fn_t)(void *baton); +/** A typedef for a function that opens an #svn_txdelta_stream_t object, + * allocated in @a result_pool. @a baton is provided by the caller. + * Any temporary allocations may be performed in @a scratch_pool. + * + * @since New in 1.10. + */ +typedef svn_error_t * +(*svn_txdelta_stream_open_func_t)(svn_txdelta_stream_t **txdelta_stream, + void *baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /** Create and return a generic text delta stream with @a baton, @a * next_window and @a md5_digest. Allocate the new stream in @a * pool. @@ -508,7 +520,9 @@ svn_txdelta_apply(svn_stream_t *source, * version is @a svndiff_version. @a compression_level is the zlib * compression level from 0 (no compression) and 9 (maximum compression). * - * @since New in 1.7. + * @since New in 1.7. Since 1.10, @a svndiff_version can be 2 for the + * svndiff2 format. @a compression_level is currently ignored if + * @a svndiff_version is set to 2. */ void svn_txdelta_to_svndiff3(svn_txdelta_window_handler_t *handler, @@ -544,6 +558,20 @@ svn_txdelta_to_svndiff(svn_stream_t *output, svn_txdelta_window_handler_t *handler, void **handler_baton); +/** Return a readable generic stream which will produce svndiff-encoded + * text delta from the delta stream @a txstream. @a svndiff_version and + * @a compression_level are same as in svn_txdelta_to_svndiff3(). + * + * Allocate the stream in @a pool. + * + * @since New in 1.10. + */ +svn_stream_t * +svn_txdelta_to_svndiff_stream(svn_txdelta_stream_t *txstream, + int svndiff_version, + int compression_level, + apr_pool_t *pool); + /** Return a writable generic stream which will parse svndiff-format * data into a text delta, invoking @a handler with @a handler_baton * whenever a new window is ready. @@ -666,8 +694,10 @@ svn_txdelta_skip_svndiff_window(apr_file_t *file, * as it produces the delta. * * @note Don't try to allocate one of these yourself. Instead, always - * use svn_delta_default_editor() or some other constructor, to ensure - * that unused slots are filled in with no-op functions. + * use svn_delta_default_editor() or some other constructor, to avoid + * backwards compatibility problems if the structure is extended in + * future releases and to ensure that unused slots are filled in with + * no-op functions. * * <h3>Function Usage</h3> * @@ -738,10 +768,11 @@ svn_txdelta_skip_svndiff_window(apr_file_t *file, * * The @c add_file and @c open_file callbacks each return a baton * for the file being created or changed. This baton can then be - * passed to @c apply_textdelta to change the file's contents, or - * @c change_file_prop to change the file's properties. When the - * producer is finished making changes to a file, it should call - * @c close_file, to let the consumer clean up and free the baton. + * passed to @c apply_textdelta or @c apply_textdelta_stream to change + * the file's contents, or @c change_file_prop to change the file's + * properties. When the producer is finished making changes to a + * file, it should call @c close_file, to let the consumer clean up + * and free the baton. * * The @c add_file and @c add_directory functions each take arguments * @a copyfrom_path and @a copyfrom_revision. If @a copyfrom_path is @@ -783,15 +814,16 @@ svn_txdelta_skip_svndiff_window(apr_file_t *file, * 5. When the producer calls @c open_file or @c add_file, either: * * (a) The producer must follow with any changes to the file - * (@c change_file_prop and/or @c apply_textdelta, as applicable), - * followed by a @c close_file call, before issuing any other file - * or directory calls, or + * (@c change_file_prop and/or @c apply_textdelta / + * @c apply_textdelta_stream, as applicable), followed by + * a @c close_file call, before issuing any other file or + * directory calls, or * * (b) The producer must follow with a @c change_file_prop call if * it is applicable, before issuing any other file or directory * calls; later, after all directory batons including the root - * have been closed, the producer must issue @c apply_textdelta - * and @c close_file calls. + * have been closed, the producer must issue @c apply_textdelta / + * @c apply_textdelta_stream and @c close_file calls. * * 6. When the producer calls @c apply_textdelta, it must make all of * the window handler calls (including the @c NULL window at the @@ -800,7 +832,7 @@ svn_txdelta_skip_svndiff_window(apr_file_t *file, * So, the producer needs to use directory and file batons as if it * is doing a single depth-first traversal of the tree, with the * exception that the producer may keep file batons open in order to - * make @c apply_textdelta calls at the end. + * make @c apply_textdelta / @c apply_textdelta_stream calls at the end. * * * <h3>Pool Usage</h3> @@ -824,12 +856,13 @@ svn_txdelta_skip_svndiff_window(apr_file_t *file, * Note that close_directory can be called *before* a file in that * directory has been closed. That is, the directory's baton is * closed before the file's baton. The implication is that - * @c apply_textdelta and @c close_file should not refer to a parent - * directory baton UNLESS the editor has taken precautions to - * allocate it in a pool of the appropriate lifetime (the @a dir_pool - * passed to @c open_directory and @c add_directory definitely does not - * have the proper lifetime). In general, it is recommended to simply - * avoid keeping a parent directory baton in a file baton. + * @c apply_textdelta / @c apply_textdelta_stream and @c close_file + * should not refer to a parent directory baton UNLESS the editor has + * taken precautions to allocate it in a pool of the appropriate + * lifetime (the @a dir_pool passed to @c open_directory and + * @c add_directory definitely does not have the proper lifetime). + * In general, it is recommended to simply avoid keeping a parent + * directory baton in a file baton. * * * <h3>Errors</h3> @@ -977,7 +1010,8 @@ typedef struct svn_delta_editor_t /** We are going to add a new file at @a path, a child of the * directory represented by @a parent_baton. The callback can * store a baton for this new file in @a **file_baton; whatever value - * it stores there should be passed through to @c apply_textdelta. + * it stores there should be passed through to @c apply_textdelta or + * @c apply_textdelta_stream. * * If @a copyfrom_path is non-@c NULL, this add has history (i.e., is a * copy), and the origin of the copy may be recorded as @@ -1009,8 +1043,8 @@ typedef struct svn_delta_editor_t * * The callback can store a baton for this new file in @a **file_baton; * whatever value it stores there should be passed through to - * @c apply_textdelta. If a valid revnum, @a base_revision is the - * current revision of the file. + * @c apply_textdelta or @c apply_textdelta_stream. If a valid revnum, + * @a base_revision is the current revision of the file. * * Allocations for the returned @a file_baton should be performed in * @a result_pool. It is also typical to save this pool for later usage @@ -1075,11 +1109,11 @@ typedef struct svn_delta_editor_t * more, so whatever resources it refers to may now be freed. * * @a text_checksum is the hex MD5 digest for the fulltext that - * resulted from a delta application, see @c apply_textdelta. The - * checksum is ignored if NULL. If not null, it is compared to the - * checksum of the new fulltext, and the error - * SVN_ERR_CHECKSUM_MISMATCH is returned if they do not match. If - * there is no new fulltext, @a text_checksum is ignored. + * resulted from a delta application, see @c apply_textdelta and + * @c apply_textdelta_stream. The checksum is ignored if NULL. + * If not null, it is compared to the checksum of the new fulltext, + * and the error SVN_ERR_CHECKSUM_MISMATCH is returned if they do + * not match. If there is no new fulltext, @a text_checksum is ignored. * * Any temporary allocations may be performed in @a scratch_pool. */ @@ -1115,6 +1149,38 @@ typedef struct svn_delta_editor_t svn_error_t *(*abort_edit)(void *edit_baton, apr_pool_t *scratch_pool); + /** Apply a text delta stream, yielding the new revision of a file. + * This callback operates on the passed-in @a editor instance. + * + * @a file_baton indicates the file we're creating or updating, and the + * ancestor file on which it is based; it is the baton set by some + * prior @c add_file or @c open_file callback. + * + * @a open_func is a function that opens a #svn_txdelta_stream_t object. + * @a open_baton is provided by the caller. + * + * @a base_checksum is the hex MD5 digest for the base text against + * which the delta is being applied; it is ignored if NULL, and may + * be ignored even if not NULL. If it is not ignored, it must match + * the checksum of the base text against which svndiff data is being + * applied; if it does not, @c apply_textdelta_stream call which detects + * the mismatch will return the error #SVN_ERR_CHECKSUM_MISMATCH + * (if there is no base text, there may still be an error if + * @a base_checksum is neither NULL nor the hex MD5 checksum of the + * empty string). + * + * Any temporary allocations may be performed in @a scratch_pool. + * + * @since New in 1.10. + */ + svn_error_t *(*apply_textdelta_stream)( + const struct svn_delta_editor_t *editor, + void *file_baton, + const char *base_checksum, + svn_txdelta_stream_open_func_t open_func, + void *open_baton, + apr_pool_t *scratch_pool); + /* Be sure to update svn_delta_get_cancellation_editor() and * svn_delta_default_editor() if you add a new callback here. */ } svn_delta_editor_t; diff --git a/subversion/include/svn_diff.h b/subversion/include/svn_diff.h index 5b8f8d7fc9f2..bd2c97084bfb 100644 --- a/subversion/include/svn_diff.h +++ b/subversion/include/svn_diff.h @@ -1212,7 +1212,43 @@ typedef struct svn_prop_patch_t { } svn_prop_patch_t; /** + * A binary patch representation. This basically describes replacing one + * exact binary representation with another one. + * + * @since New in 1.10. */ +typedef struct svn_diff_binary_patch_t svn_diff_binary_patch_t; + +/** + * Creates a stream allocated in @a result_pool from which the original + * (pre-patch-application) version of the binary patched file can be read. + * + * @note Like many svn_diff_get functions over patches, this is implemented + * as reading from the backing patch file. Therefore it is recommended to + * read the whole stream before using other functions on the same patch file. + * + * @since New in 1.10 */ +svn_stream_t * +svn_diff_get_binary_diff_original_stream(const svn_diff_binary_patch_t *bpatch, + apr_pool_t *result_pool); + +/** + * Creates a stream allocated in @a result_pool from which the resulting + * (post-patch-application) version of the binary patched file can be read. + * + * @note Like many svn_diff_get functions over patches, this is implemented + * as reading from the backing patch file. Therefore it is recommended to + * read the whole stream before using other functions on the same patch file. + * + * @since New in 1.10 */ +svn_stream_t * +svn_diff_get_binary_diff_result_stream(const svn_diff_binary_patch_t *bpatch, + apr_pool_t *result_pool); + +/** * Data type to manage parsing of patches. + * + * Represents a patch to one target file. + * * API users should not allocate structures of this type directly. * * @since New in 1.7. */ @@ -1239,7 +1275,9 @@ typedef struct svn_patch_t { svn_diff_operation_kind_t operation; /** - * Indicates whether the patch is being interpreted in reverse. */ + * Indicates whether the patch is being interpreted in reverse. + * ### If so, how does this affect the interpretation of other fields? + */ svn_boolean_t reverse; /** @@ -1249,6 +1287,45 @@ typedef struct svn_patch_t { * @since New in 1.9. */ svn_mergeinfo_t mergeinfo; svn_mergeinfo_t reverse_mergeinfo; + + /** + * Declares that there is a binary conflict and contains the information + * to apply it as parsed from the file. + * @since New in 1.10. */ + svn_diff_binary_patch_t *binary_patch; + + /** The old and new executability bits, as retrieved from the patch file, from + * the git-like mode headers. + * + * A patch may specify an executability change via @a old_executable_bit and + * @a new_executable_bit, via a #SVN_PROP_EXECUTABLE propchange hunk, or both + * ways. It is upto caller how to decide how conflicting information is + * handled. + * + * #svn_tristate_unknown indicates the patch does not specify the + * corresponding bit. + * + * @since New in 1.10. + */ + svn_tristate_t old_executable_bit; + svn_tristate_t new_executable_bit; + + /** The old and new symlink bits, as retrieved from the patch file, from + * the git-like mode headers. + * + * A patch may specify a symlink change via @a old_symlink_bit and + * @a new_symlink_bit, via a #SVN_PROP_SPECIAL propchange hunk, or both + * ways. It is upto caller how to decide how conflicting information is + * handled. Most implementations will currently just describe a replacement + * of the file though. + * + * #svn_tristate_unknown indicates the patch does not specify the + * corresponding bit. + * + * @since New in 1.10. + */ + svn_tristate_t old_symlink_bit; + svn_tristate_t new_symlink_bit; } svn_patch_t; /** An opaque type representing an open patch file. diff --git a/subversion/include/svn_error.h b/subversion/include/svn_error.h index 5681644fd194..290aaa2cbb22 100644 --- a/subversion/include/svn_error.h +++ b/subversion/include/svn_error.h @@ -165,18 +165,16 @@ svn_error_wrap_apr(apr_status_t status, ...) __attribute__((format(printf, 2, 3))); -/** A quick n' easy way to create a wrapped exception with your own - * message, before throwing it up the stack. (It uses all of the - * @a child's fields.) +/** If @a child is SVN_NO_ERROR, return SVN_NO_ERROR. + * Else, prepend a new error to the error chain of @a child. The new error + * uses @a new_msg as error message but all other error attributes (such + * as the error code) are copied from @a child. */ svn_error_t * svn_error_quick_wrap(svn_error_t *child, const char *new_msg); -/** A quick n' easy way to create a wrapped exception with your own - * printf-style error message produced by passing @a fmt, using - * apr_psprintf(), before throwing it up the stack. (It uses all of the - * @a child's fields.) +/** Like svn_error_quick_wrap(), but with format string support. * * @since New in 1.9. */ diff --git a/subversion/include/svn_error_codes.h b/subversion/include/svn_error_codes.h index f8348f48dec9..f95f0a0f0e84 100644 --- a/subversion/include/svn_error_codes.h +++ b/subversion/include/svn_error_codes.h @@ -240,6 +240,11 @@ SVN_ERROR_START SVN_ERR_BAD_CATEGORY_START + 16, "Invalid compression method") + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_BAD_PROPERTY_VALUE_EOL, + SVN_ERR_BAD_CATEGORY_START + 17, + "Unexpected line ending in the property value") + /* xml errors */ SVN_ERRDEF(SVN_ERR_XML_ATTRIB_NOT_FOUND, @@ -868,6 +873,21 @@ SVN_ERROR_START SVN_ERR_FS_CATEGORY_START + 63, "Invalid generation number data.") + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_FS_CORRUPT_REVPROP_MANIFEST, + SVN_ERR_FS_CATEGORY_START + 64, + "Revprop manifest corrupt.") + + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_FS_CORRUPT_PROPLIST, + SVN_ERR_FS_CATEGORY_START + 65, + "Property list is corrupt.") + + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_FS_AMBIGUOUS_CHECKSUM_REP, + SVN_ERR_FS_CATEGORY_START + 67, + "Content checksums supposedly match but content does not.") + /* repos errors */ SVN_ERRDEF(SVN_ERR_REPOS_LOCKED, @@ -1236,6 +1256,11 @@ SVN_ERROR_START SVN_ERR_CLIENT_CATEGORY_START + 23, "The operation is forbidden by the server") + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_CLIENT_CONFLICT_OPTION_NOT_APPLICABLE, + SVN_ERR_CLIENT_CATEGORY_START + 24, + "The conflict resolution option is not applicable") + /* misc errors */ SVN_ERRDEF(SVN_ERR_BASE, @@ -1442,6 +1467,21 @@ SVN_ERROR_START SVN_ERR_MISC_CATEGORY_START + 43, "Parser error: invalid input") + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_SQLITE_ROLLBACK_FAILED, + SVN_ERR_MISC_CATEGORY_START + 44, + "SQLite transaction rollback failed") + + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_LZ4_COMPRESSION_FAILED, + SVN_ERR_MISC_CATEGORY_START + 45, + "LZ4 compression failed") + + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_LZ4_DECOMPRESSION_FAILED, + SVN_ERR_MISC_CATEGORY_START + 46, + "LZ4 decompression failed") + /* command-line client errors */ SVN_ERRDEF(SVN_ERR_CL_ARG_PARSING_ERROR, @@ -1537,6 +1577,16 @@ SVN_ERROR_START SVN_ERR_RA_SVN_CATEGORY_START + 8, "Editor drive was aborted") + /** @since New in 1.10 */ + SVN_ERRDEF(SVN_ERR_RA_SVN_REQUEST_SIZE, + SVN_ERR_RA_SVN_CATEGORY_START + 9, + "Client request too long") + + /** @since New in 1.10 */ + SVN_ERRDEF(SVN_ERR_RA_SVN_RESPONSE_SIZE, + SVN_ERR_RA_SVN_CATEGORY_START + 10, + "Server response too long") + /* libsvn_auth errors */ /* this error can be used when an auth provider doesn't have @@ -1594,6 +1644,11 @@ SVN_ERROR_START SVN_ERR_DIFF_CATEGORY_START + 0, "Diff data source modified unexpectedly") + /** @since New in 1.10 */ + SVN_ERRDEF(SVN_ERR_DIFF_UNEXPECTED_DATA, + SVN_ERR_DIFF_CATEGORY_START + 1, + "Diff data unexpected") + /* libsvn_ra_serf errors */ /** @since New in 1.5. @deprecated SSPI now handled by serf rather than libsvn_ra_serf. */ @@ -1617,6 +1672,11 @@ SVN_ERROR_START SVN_ERR_RA_SERF_CATEGORY_START + 3, "While handling serf response:") + /** @since New in 1.10. */ + SVN_ERRDEF(SVN_ERR_RA_SERF_STREAM_BUCKET_READ_ERROR, + SVN_ERR_RA_SERF_CATEGORY_START + 4, + "Can't read from stream") + /* malfunctions such as assertion failures */ SVN_ERRDEF(SVN_ERR_ASSERTION_FAIL, diff --git a/subversion/include/svn_fs.h b/subversion/include/svn_fs.h index e34146d16dff..179774e16a1e 100644 --- a/subversion/include/svn_fs.h +++ b/subversion/include/svn_fs.h @@ -113,7 +113,7 @@ typedef struct svn_fs_t svn_fs_t; * * "2" is allowed, too and means "enable if efficient", * i.e. this will not create warning at runtime if there - * if no efficient support for revprop caching. + * is no efficient support for revprop caching. * * @since New in 1.8. */ @@ -134,6 +134,12 @@ typedef struct svn_fs_t svn_fs_t; */ #define SVN_FS_CONFIG_FSFS_CACHE_NS "fsfs-cache-namespace" +/** Enable / disable caching of node properties for a FSFS repository. + * + * @since New in 1.10. + */ +#define SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS "fsfs-cache-nodeprops" + /** Enable / disable the FSFS format 7 "block read" feature. * * @since New in 1.9. @@ -207,6 +213,20 @@ typedef struct svn_fs_t svn_fs_t; * @since New in 1.9. */ #define SVN_FS_CONFIG_COMPATIBLE_VERSION "compatible-version" + +/** Specifies whether the filesystem should be forcing a physical write of + * the data to disk. Enabling the option allows the filesystem to return + * from the API calls without forcing the write to disk. If this option + * is disabled, the changes are always written to disk. + * + * @note Avoiding the forced write to disk usually is more efficient, but + * doesn't guarantee data integrity after a system crash or power failure + * and should be used with caution. + * + * @since New in 1.10. + */ +#define SVN_FS_CONFIG_NO_FLUSH_TO_DISK "no-flush-to-disk" + /** @} */ @@ -269,11 +289,13 @@ svn_fs_set_warning_func(svn_fs_t *fs, * @c NULL, the options it contains modify the behavior of the * filesystem. The interpretation of @a fs_config is specific to the * filesystem back-end. The new filesystem may be closed by - * destroying @a pool. + * destroying @a result_pool. + * + * Use @a scratch_pool for temporary allocations. * * @note The lifetime of @a fs_config must not be shorter than @a - * pool's. It's a good idea to allocate @a fs_config from @a pool or - * one of its ancestors. + * result_pool's. It's a good idea to allocate @a fs_config from + * @a result_pool or one of its ancestors. * * If @a fs_config contains a value for #SVN_FS_CONFIG_FS_TYPE, that * value determines the filesystem type for the new filesystem. @@ -289,8 +311,22 @@ svn_fs_set_warning_func(svn_fs_t *fs, * though the caller should not rely upon any particular default if they * wish to ensure that a filesystem of a specific type is created. * + * @since New in 1.10. + */ +svn_error_t * +svn_fs_create2(svn_fs_t **fs_p, + const char *path, + apr_hash_t *fs_config, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Like svn_fs_create2(), but without @a scratch_pool. + * + * @deprecated Provided for backward compatibility with the 1.9 API. * @since New in 1.1. */ +SVN_DEPRECATED svn_error_t * svn_fs_create(svn_fs_t **fs_p, const char *path, @@ -1060,15 +1096,12 @@ svn_fs_unparse_id(const svn_fs_id_t *id, * set. * * The Subversion filesystem will make a best effort to not reuse - * transaction names. The Berkeley DB backend generates transaction - * names using a sequence, or a counter, which is stored in the BDB + * transaction names. The BDB and FSFS backends generate transaction + * names using a sequence, or a counter, which is stored in the * database. Each new transaction increments the counter. The * current value of the counter is not serialized into a filesystem * dump file, so dumping and restoring the repository will reset the - * sequence and reuse transaction names. The FSFS backend generates a - * transaction name using the hostname, process ID and current time in - * microseconds since 00:00:00 January 1, 1970 UTC. So it is - * extremely unlikely that a transaction name will be reused. + * sequence and so may reuse transaction names. * * @defgroup svn_fs_txns Filesystem transactions * @{ @@ -1425,7 +1458,7 @@ svn_fs_revision_root_revision(svn_fs_root_t *root); * Unicode canonical decomposition and ordering. No directory entry * may be named '.', '..', or the empty string. Given a directory * entry name which fails to meet these requirements, a filesystem - * function returns an SVN_ERR_FS_PATH_SYNTAX error. + * function returns an #SVN_ERR_FS_PATH_SYNTAX error. * * A directory path is a sequence of zero or more directory entry * names, separated by slash characters (U+002f), and possibly ending @@ -1433,7 +1466,7 @@ svn_fs_revision_root_revision(svn_fs_root_t *root); * characters are treated as if they were a single slash. If a path * ends with a slash, it refers to the same node it would without the * slash, but that node must be a directory, or else the function - * returns an SVN_ERR_FS_NOT_DIRECTORY error. + * may return an #SVN_ERR_FS_NOT_DIRECTORY error. * * A path consisting of the empty string, or a string containing only * slashes, refers to the root directory. @@ -1474,7 +1507,75 @@ typedef enum svn_fs_path_change_kind_t * by the commit API; this does not mean the new value is different from * the old value. * - * @since New in 1.6. */ + * @since New in 1.10. */ +typedef struct svn_fs_path_change3_t +{ + /** path of the node that got changed. */ + svn_string_t path; + + /** kind of change */ + svn_fs_path_change_kind_t change_kind; + + /** what node kind is the path? + (Note: it is legal for this to be #svn_node_unknown.) */ + svn_node_kind_t node_kind; + + /** was the text touched? + * For node_kind=dir: always false. For node_kind=file: + * modify: true iff text touched. + * add (copy): true iff text touched. + * add (plain): always true. + * delete: always false. + * replace: as for the add/copy part of the replacement. + */ + svn_boolean_t text_mod; + + /** were the properties touched? + * modify: true iff props touched. + * add (copy): true iff props touched. + * add (plain): true iff props touched. + * delete: always false. + * replace: as for the add/copy part of the replacement. + */ + svn_boolean_t prop_mod; + + /** was the mergeinfo property touched? + * modify: } true iff svn:mergeinfo property add/del/mod + * add (copy): } and fs format supports this flag. + * add (plain): } + * delete: always false. + * replace: as for the add/copy part of the replacement. + * (Note: Pre-1.9 repositories will report #svn_tristate_unknown.) + */ + svn_tristate_t mergeinfo_mod; + + /** Copyfrom revision and path; this is only valid if copyfrom_known + * is true. */ + svn_boolean_t copyfrom_known; + svn_revnum_t copyfrom_rev; + const char *copyfrom_path; + + /* NOTE! Please update svn_fs_path_change3_create() when adding new + fields here. */ +} svn_fs_path_change3_t; + + +/** Similar to #svn_fs_path_change3_t, but with @a node_rev_id and without + * path information. + * + * @note Fields may be added to the end of this structure in future + * versions. Therefore, to preserve binary compatibility, users + * should not directly allocate structures of this type. + * + * @note The @c text_mod, @c prop_mod and @c mergeinfo_mod flags mean the + * text, properties and mergeinfo property (respectively) were "touched" + * by the commit API; this does not mean the new value is different from + * the old value. + * + * @since New in 1.6. + * + * @deprecated Provided for backwards compatibility with the 1.9 API. + */ typedef struct svn_fs_path_change2_t { /** node revision id of changed path */ @@ -1563,22 +1664,94 @@ svn_fs_path_change2_create(const svn_fs_id_t *node_rev_id, svn_fs_path_change_kind_t change_kind, apr_pool_t *pool); +/** + * Allocate an #svn_fs_path_change3_t structure in @a result_pool, + * initialize and return it. + * + * Set the @c change_kind field to @a change_kind. Set all other fields + * to their @c _unknown, @c NULL or invalid value, respectively. + * + * @since New in 1.10. + */ +svn_fs_path_change3_t * +svn_fs_path_change3_create(svn_fs_path_change_kind_t change_kind, + apr_pool_t *result_pool); + +/** + * Return a deep copy of @a *change, allocated in @a result_pool. + * + * @since New in 1.10. + */ +svn_fs_path_change3_t * +svn_fs_path_change3_dup(svn_fs_path_change3_t *change, + apr_pool_t *result_pool); + +/** + * Opaque iterator object type for a changed paths list. + * + * @since New in 1.10. + */ +typedef struct svn_fs_path_change_iterator_t svn_fs_path_change_iterator_t; + +/** + * Set @a *change to the path change that @a iterator currently points to + * and advance the @a iterator. If the change list has been exhausted, + * @a change will be set to @c NULL. + * + * You may modify @a **change but its content becomes invalid as soon as + * either @a iterator becomes invalid or you call this function again. + * + * @note The @c node_kind field in @a change may be #svn_node_unknown and + * the @c copyfrom_known fields may be FALSE. + * + * @since New in 1.10. + */ +svn_error_t * +svn_fs_path_change_get(svn_fs_path_change3_t **change, + svn_fs_path_change_iterator_t *iterator); + + /** Determine what has changed under a @a root. * + * Set @a *iterator to an iterator object, allocated in @a result_pool, + * which will give access to the full list of changed paths under @a root. + * Each call to @a svn_fs_path_change_get will return a new unique path + * change and has amortized O(1) runtime. The iteration order is undefined + * and may change even for the same @a root. + * + * If @a root becomes invalid, @a *iterator becomes invalid, too. + * + * Use @a scratch_pool for temporary allocations. + * + * @note The @a *iterator may be a large object and bind limited system + * resources such as file handles. Be sure to clear the owning + * pool once you don't need that iterator anymore. + * + * @since New in 1.10. + */ +svn_error_t * +svn_fs_paths_changed3(svn_fs_path_change_iterator_t **iterator, + svn_fs_root_t *root, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Same as svn_fs_paths_changed3() but returning all changes in a single, + * large data structure and using a single pool for all allocations. + * * Allocate and return a hash @a *changed_paths2_p containing descriptions * of the paths changed under @a root. The hash is keyed with * <tt>const char *</tt> paths, and has #svn_fs_path_change2_t * values. * - * Callers can assume that this function takes time proportional to - * the amount of data output, and does not need to do tree crawls; - * however, it is possible that some of the @c node_kind fields in the - * #svn_fs_path_change2_t * values will be #svn_node_unknown or - * that and some of the @c copyfrom_known fields will be FALSE. - * * Use @a pool for all allocations, including the hash and its values. * + * @note Retrieving the #node_rev_id element of #svn_fs_path_change2_t may + * be expensive in some FS backends. + * * @since New in 1.6. + * + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_fs_paths_changed2(apr_hash_t **changed_paths2_p, svn_fs_root_t *root, @@ -1989,11 +2162,23 @@ svn_fs_closest_copy(svn_fs_root_t **root_p, const char *path, apr_pool_t *pool); +/** Receives parsed @a mergeinfo for the file system path @a path. + * + * The user-provided @a baton is being passed through by the retrieval + * function and @a scratch_pool will be cleared between invocations. + * + * @since New in 1.10. + */ +typedef svn_error_t * +(*svn_fs_mergeinfo_receiver_t)(const char *path, + svn_mergeinfo_t mergeinfo, + void *baton, + apr_pool_t *scratch_pool); /** Retrieve mergeinfo for multiple nodes. * - * @a *catalog is a catalog for @a paths. It will never be @c NULL, - * but may be empty. + * For each node found with mergeinfo on it, invoke @a receiver with + * the provided @a baton. * * @a root is revision root to use when looking up paths. * @@ -2003,7 +2188,7 @@ svn_fs_closest_copy(svn_fs_root_t **root_p, * explicit-or-inherited, or only inherited mergeinfo. * * If @a adjust_inherited_mergeinfo is @c TRUE, then any inherited - * mergeinfo returned in @a *catalog is normalized to represent the + * mergeinfo reported to @a *receiver is normalized to represent the * inherited mergeinfo on the path which inherits it. This adjusted * mergeinfo is keyed by the path which inherits it. If * @a adjust_inherited_mergeinfo is @c FALSE, then any inherited @@ -2018,13 +2203,31 @@ svn_fs_closest_copy(svn_fs_root_t **root_p, * the #SVN_PROP_MERGEINFO property explicitly set on it. (Note * that inheritance is only taken into account for the elements in @a * paths; descendants of the elements in @a paths which get their - * mergeinfo via inheritance are not included in @a *catalog.) + * mergeinfo via inheritance are not reported to @a receiver.) + * + * Do any necessary temporary allocations in @a scratch_pool. * - * Allocate @a *catalog in result_pool. Do any necessary temporary - * allocations in @a scratch_pool. + * @since New in 1.10. + */ +svn_error_t * +svn_fs_get_mergeinfo3(svn_fs_root_t *root, + const apr_array_header_t *paths, + svn_mergeinfo_inheritance_t inherit, + svn_boolean_t include_descendants, + svn_boolean_t adjust_inherited_mergeinfo, + svn_fs_mergeinfo_receiver_t receiver, + void *baton, + apr_pool_t *scratch_pool); + +/** + * Same as svn_fs_get_mergeinfo3(), but all mergeinfo is being collected + * and returned in @a *catalog. It will never be @c NULL, but may be empty. * * @since New in 1.8. + * + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_fs_get_mergeinfo2(svn_mergeinfo_catalog_t *catalog, svn_fs_root_t *root, @@ -2545,11 +2748,70 @@ svn_fs_deltify_revision(svn_fs_t *fs, svn_revnum_t revision, apr_pool_t *pool); +/** Make sure that all completed revision property changes to the filesystem + * underlying @a fs are actually visible through @a fs. Use @a scratch_pool + * for temporary allocations. + * + * This is an explicit synchronization barrier for revprop changes made + * through different #svn_fs_t for the same underlying filesystem. Any + * revprop change through @a fs acts as an implicit barrier, i.e. that + * object will see all completed revprop changes up to an including its own. + * Only #svn_fs_revision_prop2 and #svn_fs_revision_proplist2 have an option + * to not synchronize with on-disk data and potentially return outdated data + * as old as the last barrier. + * + * The intended use of this is implementing efficient queries in upper layers + * where the result only needs to include all changes up to the start of + * that query but does not need to pick up on changes while the query is + * running: + * + * @code + SVN_ERR(svn_fs_deltify_revision(fs, pool); + for (i = 0; i < n; i++) + SVN_ERR(svn_fs_revision_prop2(&authors[i], fs, revs[i], "svn:author", + FALSE, pool, pool)); @endcode + * + * @see svn_fs_revision_prop2, svn_fs_revision_proplist2 + * + * @since New in 1.10. + */ +svn_error_t * +svn_fs_refresh_revision_props(svn_fs_t *fs, + apr_pool_t *scratch_pool); /** Set @a *value_p to the value of the property named @a propname on * revision @a rev in the filesystem @a fs. If @a rev has no property by - * that name, set @a *value_p to zero. Allocate the result in @a pool. + * that name, set @a *value_p to zero. + * + * If @a refresh is set, this call acts as a read barrier and is guaranteed + * to return the latest value. Otherwise, it may return data as old as the + * last synchronization point but can be much faster to access - in + * particular for packed repositories. + * + * Allocate the result in @a result_pool and use @a scratch_pool for + * temporary allocations. + * + * @see svn_fs_refresh_revision_props + * + * @since New in 1.10. + */ +svn_error_t * +svn_fs_revision_prop2(svn_string_t **value_p, + svn_fs_t *fs, + svn_revnum_t rev, + const char *propname, + svn_boolean_t refresh, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Like #svn_fs_revision_prop2 but using @a pool for @a scratch_pool as + * well as @a result_pool and setting @a refresh to #TRUE. + * + * @see svn_fs_refresh_revision_props + * + * @deprecated For backward compatibility with 1.9. */ +SVN_DEPRECATED svn_error_t * svn_fs_revision_prop(svn_string_t **value_p, svn_fs_t *fs, @@ -2561,15 +2823,41 @@ svn_fs_revision_prop(svn_string_t **value_p, /** Set @a *table_p to the entire property list of revision @a rev in * filesystem @a fs, as an APR hash table allocated in @a pool. The table * maps <tt>char *</tt> property names to #svn_string_t * values; the names - * and values are allocated in @a pool. + * and values are allocated in @a result_pool. Use @a scratch_pool for + * temporary allocations. + * + * If @a refresh is set, this call acts as a read barrier and is guaranteed + * to return the latest value. Otherwise, it may return data as old as the + * last synchronization point but can be much faster to access - in + * particular for packed repositories. + * + * @see svn_fs_refresh_revision_props + * + * @since New in 1.10. + * + */ +svn_error_t * +svn_fs_revision_proplist2(apr_hash_t **table_p, + svn_fs_t *fs, + svn_revnum_t rev, + svn_boolean_t refresh, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Like svn_fs_revision_proplist2 but using @a pool for @a scratch_pool as + * well as @a result_pool and setting @a refresh to #TRUE. + * + * @see svn_fs_refresh_revision_props + * + * @deprecated For backward compatibility with 1.9. */ +SVN_DEPRECATED svn_error_t * svn_fs_revision_proplist(apr_hash_t **table_p, svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool); - /** Change a revision's property's value, or add/delete a property. * * - @a fs is a filesystem, and @a rev is the revision in that filesystem @@ -2992,7 +3280,13 @@ typedef enum svn_fs_pack_notify_action_t /** packing of the shard revprops has completed @since New in 1.7. */ - svn_fs_pack_notify_end_revprop + svn_fs_pack_notify_end_revprop, + + /** pack has been a no-op for this repository. The next / future packable + shard will be given. If the shard is -1, then the repository does not + support packing at all. + @since New in 1.10. */ + svn_fs_pack_notify_noop } svn_fs_pack_notify_action_t; diff --git a/subversion/include/svn_hash.h b/subversion/include/svn_hash.h index 50ed10a4b3f8..8303f077e18e 100644 --- a/subversion/include/svn_hash.h +++ b/subversion/include/svn_hash.h @@ -239,19 +239,44 @@ svn_hash_from_cstring_keys(apr_hash_t **hash, const apr_array_header_t *keys, apr_pool_t *pool); +/* For the Subversion developers, this #define makes the svn_hash_gets and + * svn_hash_sets macros forward their parameters through functions in order to + * gain type checking for the 'key' parameter which the basic apr_hash_* APIs + * declare only as 'void *'. + */ +#ifdef SVN_DEBUG +#define SVN_HASH__GETS_SETS +#endif + +#ifdef SVN_HASH__GETS_SETS +void * +svn_hash__gets_debug(apr_hash_t *ht, const char *key); + +#define svn_hash_gets(ht, key) \ + svn_hash__gets_debug(ht, key) +#else /** Shortcut for apr_hash_get() with a const char * key. * * @since New in 1.8. */ #define svn_hash_gets(ht, key) \ apr_hash_get(ht, key, APR_HASH_KEY_STRING) +#endif + +#ifdef SVN_HASH__GETS_SETS +void +svn_hash__sets_debug(apr_hash_t *ht, const char *key, const void *value); +#define svn_hash_sets(ht, key, val) \ + svn_hash__sets_debug(ht, key, val) +#else /** Shortcut for apr_hash_set() with a const char * key. * * @since New in 1.8. */ #define svn_hash_sets(ht, key, val) \ apr_hash_set(ht, key, APR_HASH_KEY_STRING, val) +#endif /** @} */ diff --git a/subversion/include/svn_io.h b/subversion/include/svn_io.h index 42eb422bfab9..802e5caa5c12 100644 --- a/subversion/include/svn_io.h +++ b/subversion/include/svn_io.h @@ -918,6 +918,17 @@ typedef svn_error_t *(*svn_stream_seek_fn_t)(void *baton, typedef svn_error_t *(*svn_stream_data_available_fn_t)(void *baton, svn_boolean_t *data_available); +/** Readline handler function for a generic stream. @see svn_stream_t and + * svn_stream_readline(). + * + * @since New in 1.10. + */ +typedef svn_error_t *(*svn_stream_readline_fn_t)(void *baton, + svn_stringbuf_t **stringbuf, + const char *eol, + svn_boolean_t *eof, + apr_pool_t *pool); + /** Create a generic stream. @see svn_stream_t. */ svn_stream_t * svn_stream_create(void *baton, @@ -992,6 +1003,14 @@ void svn_stream_set_data_available(svn_stream_t *stream, svn_stream_data_available_fn_t data_available); +/** Set @a stream's readline function to @a readline_fn + * + * @since New in 1.10. + */ +void +svn_stream_set_readline(svn_stream_t *stream, + svn_stream_readline_fn_t readline_fn); + /** Create a stream that is empty for reading and infinite for writing. */ svn_stream_t * svn_stream_empty(apr_pool_t *pool); @@ -1102,11 +1121,29 @@ svn_stream_from_aprfile(apr_file_t *file, apr_pool_t *pool); /** Set @a *in to a generic stream connected to stdin, allocated in - * @a pool. The stream and its underlying APR handle will be closed - * when @a pool is cleared or destroyed. + * @a pool. If @a buffered is set, APR buffering will be enabled. + * The stream and its underlying APR handle will be closed when @a pool + * is cleared or destroyed. + * + * @note APR buffering will try to fill the whole internal buffer before + * serving read requests. This may be inappropriate for interactive + * applications where stdin will not deliver any more data unless + * the application processed the data already received. + * + * @since New in 1.10. + */ +svn_error_t * +svn_stream_for_stdin2(svn_stream_t **in, + svn_boolean_t buffered, + apr_pool_t *pool); + +/** Similar to svn_stream_for_stdin2(), but with buffering being disabled. * * @since New in 1.7. + * + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_stream_for_stdin(svn_stream_t **in, apr_pool_t *pool); @@ -1129,16 +1166,27 @@ svn_error_t * svn_stream_for_stdout(svn_stream_t **out, apr_pool_t *pool); -/** Set @a *str to a string buffer allocated in @a result_pool that contains - * all data from the current position in @a stream to its end. @a len_hint - * specifies the initial capacity of the string buffer and may be 0. The - * buffer gets automatically resized to fit the actual amount of data being - * read from @a stream. +/** Read the contents of @a stream into memory, from its current position + * to its end, returning the data in @a *result. This function does not + * close the @a stream upon completion. + * + * @a len_hint gives a hint about the expected length, in bytes, of the + * actual data that will be read from the stream. It may be 0, meaning no + * hint is being provided. Efficiency in time and/or in space may be + * better (and in general will not be worse) when the actual data length + * is equal or approximately equal to the length hint. + * + * The returned memory is allocated in @a result_pool. + * + * @note The present implementation is efficient when @a len_hint is big + * enough (but not vastly bigger than necessary), and also for actual + * lengths up to 64 bytes when @a len_hint is 0. Otherwise it can incur + * significant time and space overheads. See source code for details. * * @since New in 1.9. */ svn_error_t * -svn_stringbuf_from_stream(svn_stringbuf_t **str, +svn_stringbuf_from_stream(svn_stringbuf_t **result, svn_stream_t *stream, apr_size_t len_hint, apr_pool_t *result_pool); @@ -1200,7 +1248,8 @@ svn_stream_compressed(svn_stream_t *stream, * The @a stream passed into this function is closed when the created * stream is closed. * - * @since New in 1.6. + * @since New in 1.6. Since 1.10, the resulting stream supports reset + * via stream_stream_reset(). */ svn_stream_t * svn_stream_checksummed2(svn_stream_t *stream, @@ -1225,6 +1274,24 @@ svn_stream_checksummed(svn_stream_t *stream, svn_boolean_t read_all, apr_pool_t *pool); +/** Read the contents of the readable stream @a stream and return its + * checksum of type @a kind in @a *checksum. + * + * The stream will be closed before this function returns (regardless + * of the result, or any possible error). + * + * Use @a scratch_pool for temporary allocations and @a result_pool + * to allocate @a *checksum. + * + * @since New in 1.10. + */ +svn_error_t * +svn_stream_contents_checksum(svn_checksum_t **checksum, + svn_stream_t *stream, + svn_checksum_kind_t kind, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /** Read from a generic stream until @a buffer is filled upto @a *len or * until EOF is reached. @see svn_stream_t * @@ -1318,6 +1385,14 @@ svn_stream_reset(svn_stream_t *stream); svn_boolean_t svn_stream_supports_mark(svn_stream_t *stream); +/** Returns @c TRUE if the generic @a stream supports svn_stream_reset(). + * + * @see svn_stream_reset() + * @since New in 1.10. + */ +svn_boolean_t +svn_stream_supports_reset(svn_stream_t *stream); + /** Set a @a mark at the current position of a generic @a stream, * which can later be sought back to using svn_stream_seek(). * The @a mark is allocated in @a pool. @@ -1502,25 +1577,44 @@ svn_stream_contents_same(svn_boolean_t *same, apr_pool_t *pool); -/** Read the contents of @a stream into memory, returning the data in - * @a result. The stream will be closed when it has been successfully and - * completely read. +/** Read the contents of @a stream into memory, from its current position + * to its end, returning the data in @a *result. The stream will be closed + * when it has been successfully and completely read. + * + * @a len_hint gives a hint about the expected length, in bytes, of the + * actual data that will be read from the stream. It may be 0, meaning no + * hint is being provided. Efficiency in time and/or in space may be + * better (and in general will not be worse) when the actual data length + * is equal or approximately equal to the length hint. * * The returned memory is allocated in @a result_pool, and any temporary - * allocations are performed in @a scratch_pool. + * allocations may be performed in @a scratch_pool. * - * @note due to memory pseudo-reallocation behavior (due to pools), this - * can be a memory-intensive operation for large files. + * @note The present implementation is efficient when @a len_hint is big + * enough (but not vastly bigger than necessary), and also for actual + * lengths up to 64 bytes when @a len_hint is 0. Otherwise it can incur + * significant time and space overheads. See source code for details. * - * @since New in 1.6 + * @since New in 1.10 + */ +svn_error_t * +svn_string_from_stream2(svn_string_t **result, + svn_stream_t *stream, + apr_size_t len_hint, + apr_pool_t *result_pool); + +/** Similar to svn_string_from_stream2(), but always passes 0 for + * @a len_hint. + * + * @deprecated Provided for backwards compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_string_from_stream(svn_string_t **result, svn_stream_t *stream, apr_pool_t *result_pool, apr_pool_t *scratch_pool); - /** A function type provided for use as a callback from * @c svn_stream_lazyopen_create(). * @@ -2175,6 +2269,28 @@ svn_io_file_info_get(apr_finfo_t *finfo, apr_pool_t *pool); +/** Set @a *filesize_p to the size of @a file. Use @a pool for temporary + * allocations. + * + * @note Use svn_io_file_info_get() to get more information about + * apr_file_t. + * + * @since New in 1.10 + */ +svn_error_t * +svn_io_file_size_get(svn_filesize_t *filesize_p, apr_file_t *file, + apr_pool_t *pool); + +/** Fetch the current offset of @a file into @a *offset_p. Use @a pool for + * temporary allocations. + * + * @since New in 1.10 + */ +svn_error_t * +svn_io_file_get_offset(apr_off_t *offset_p, + apr_file_t *file, + apr_pool_t *pool); + /** Wrapper for apr_file_read(). */ svn_error_t * svn_io_file_read(apr_file_t *file, @@ -2276,13 +2392,31 @@ svn_io_file_write_full(apr_file_t *file, * If @a copy_perms_path is not NULL, copy the permissions applied on @a * @a copy_perms_path on the temporary file before renaming. * - * @note This function uses advanced file control operations to flush buffers - * to disk that aren't always accessible and can be very expensive. Avoid - * using this function in cases where the file should just work on any - * network filesystem. + * If @a flush_to_disk is non-zero, do not return until the node has + * actually been written on the disk. + * + * @note The flush to disk operation can be very expensive on systems + * that implement flushing on all IO layers, like Windows. Please use + * @a flush_to_disk flag only for critical data. + * + * @since New in 1.10. + */ +svn_error_t * +svn_io_write_atomic2(const char *final_path, + const void *buf, + apr_size_t nbytes, + const char *copy_perms_path, + svn_boolean_t flush_to_disk, + apr_pool_t *scratch_pool); + +/** Similar to svn_io_write_atomic2(), but with @a flush_to_disk set + * to @c TRUE. * * @since New in 1.9. + * + * @deprecated Provided for backward compatibility with the 1.9 API */ +SVN_DEPRECATED svn_error_t * svn_io_write_atomic(const char *final_path, const void *buf, @@ -2332,9 +2466,26 @@ svn_io_stat(apr_finfo_t *finfo, * @a from_path to a new path @a to_path within the same filesystem. * In some cases, an existing node at @a to_path will be overwritten. * - * A wrapper for apr_file_rename(). @a from_path and @a to_path are - * utf8-encoded. + * @a from_path and @a to_path are utf8-encoded. If @a flush_to_disk + * is non-zero, do not return until the node has actually been moved on + * the disk. + * + * @note The flush to disk operation can be very expensive on systems + * that implement flushing on all IO layers, like Windows. Please use + * @a flush_to_disk flag only for critical data. + * + * @since New in 1.10. + */ +svn_error_t * +svn_io_file_rename2(const char *from_path, const char *to_path, + svn_boolean_t flush_to_disk, apr_pool_t *pool); + +/** Similar to svn_io_file_rename2(), but with @a flush_to_disk set + * to @c FALSE. + * + * @deprecated Provided for backward compatibility with the 1.9 API */ +SVN_DEPRECATED svn_error_t * svn_io_file_rename(const char *from_path, const char *to_path, diff --git a/subversion/include/svn_props.h b/subversion/include/svn_props.h index e920b03dee6d..7ea8bba0c048 100644 --- a/subversion/include/svn_props.h +++ b/subversion/include/svn_props.h @@ -475,22 +475,42 @@ svn_prop_name_is_valid(const char *prop_name); /** The files' last modification time. * This is stored as string in the form @c "2008-08-07T07:38:51.008782Z", to * be converted by the functions @c svn_time_to_cstring() and - * @c svn_time_from_cstring(). */ + * @c svn_time_from_cstring(). + * + * @note This property name is reserved for future usage, but currently unused. + * + * @since New in 1.6. + */ #define SVN_PROP_TEXT_TIME SVN_PROP_PREFIX "text-time" /** The files' owner. * Stored as numeric ID, optionally followed by whitespace and the string: * @c "1000 pmarek". Parsers @b should accept any number of whitespace, - * and writers @b should put exactly a single space. */ + * and writers @b should put exactly a single space. + * + * @note This property name is reserved for future usage, but currently unused. + * + * @since New in 1.6. + */ #define SVN_PROP_OWNER SVN_PROP_PREFIX "owner" /** The files' group. - * The same format as for @c SVN_PROP_OWNER, the owner-property. */ + * The same format as for @c SVN_PROP_OWNER, the owner-property. + * + * @note This property name is reserved for future usage, but currently unused. + * + * @since New in 1.6. + */ #define SVN_PROP_GROUP SVN_PROP_PREFIX "group" /** The files' unix-mode. * Stored in octal, with a leading @c 0; may have 5 digits if any of @c setuid, - * @c setgid or @c sticky are set; an example is @c "0644". */ + * @c setgid or @c sticky are set; an example is @c "0644". + * + * @note This property name is reserved for future usage, but currently unused. + * + * @since New in 1.6. + */ #define SVN_PROP_UNIX_MODE SVN_PROP_PREFIX "unix-mode" /** @} */ /* Meta-data properties */ diff --git a/subversion/include/svn_ra.h b/subversion/include/svn_ra.h index a3ab672dda92..030458d0e16a 100644 --- a/subversion/include/svn_ra.h +++ b/subversion/include/svn_ra.h @@ -1089,7 +1089,7 @@ svn_ra_get_file(svn_ra_session_t *session, * @a path is interpreted relative to the URL in @a session. * * If @a revision is @c SVN_INVALID_REVNUM (meaning 'head') and - * @a *fetched_rev is not @c NULL, then this function will set + * @a fetched_rev is not @c NULL, then this function will set * @a *fetched_rev to the actual revision that was retrieved. (Some * callers want to know, and some don't.) * @@ -1130,6 +1130,63 @@ svn_ra_get_dir(svn_ra_session_t *session, apr_pool_t *pool); /** + * Callback type to be used with svn_ra_list(). It will be invoked for + * every directory entry found. + * + * The full path of the entry is given in @a rel_path and @a dirent contains + * various additional information. Only the elements of @a dirent specified + * by the @a dirent_fields argument to svn_ra_list() will be valid. + * + * @a baton is the user-provided receiver baton. @a scratch_pool may be + * used for temporary allocations. + * + * @since New in 1.10. + */ +typedef svn_error_t *(* svn_ra_dirent_receiver_t)(const char *rel_path, + svn_dirent_t *dirent, + void *baton, + apr_pool_t *scratch_pool); + +/** + * Efficiently list everything within a sub-tree. Specify a glob pattern + * to search for specific files and folders. + * + * In @a session, walk the sub-tree starting at @a path at @a revision down + * to the given @a depth. For each directory entry found, @a receiver will + * be called with @a receiver_baton. The starting @a path will be reported + * as well. Because retrieving elements of a #svn_dirent_t can be + * expensive, you need to select them individually via flags set in + * @a dirent_fields. + * + * @a patterns is an optional array of <tt>const char *</tt>. If it is + * not @c NULL, only those directory entries will be reported whose last + * path segment matches at least one of these patterns. This feature uses + * apr_fnmatch() for glob matching and requiring '.' to matched by dots + * in the path. + * + * @a path must point to a directory and @a depth must be at least + * #svn_depth_empty. + * + * If the server doesn't support the 'list' command, return + * #SVN_ERR_UNSUPPORTED_FEATURE in preference to any other error that + * might otherwise be returned. + * + * Use @a scratch_pool for temporary memory allocation. + * + * @since New in 1.10. + */ +svn_error_t * +svn_ra_list(svn_ra_session_t *session, + const char *path, + svn_revnum_t revision, + const apr_array_header_t *patterns, + svn_depth_t depth, + apr_uint32_t dirent_fields, + svn_ra_dirent_receiver_t receiver, + void *receiver_baton, + apr_pool_t *scratch_pool); + +/** * Set @a *catalog to a mergeinfo catalog for the paths in @a paths. * If no mergeinfo is available, set @a *catalog to @c NULL. The * requested mergeinfo hashes are for @a paths (which are relative to @@ -1550,7 +1607,7 @@ svn_ra_do_diff(svn_ra_session_t *session, * revisions in which at least one of @a paths was changed (i.e., if * file, text or props changed; if dir, props changed or an entry * was added or deleted). Each path is an <tt>const char *</tt>, relative - * to the @a session's common parent. + * to the repository root of @a session. * * If @a limit is greater than zero only invoke @a receiver on the first * @a limit logs. @@ -1717,9 +1774,10 @@ svn_ra_get_repos_root(svn_ra_session_t *session, /** * Set @a *locations to the locations (at the repository revisions * @a location_revisions) of the file identified by @a path in - * @a peg_revision. @a path is relative to the URL to which - * @a session was opened. @a location_revisions is an array of - * @c svn_revnum_t's. @a *locations will be a mapping from the revisions to + * @a peg_revision (passing @c SVN_INVALID_REVNUM is an error). + * @a path is relative to the URL to which @a session was opened. + * @a location_revisions is an array of @c svn_revnum_t's. + * @a *locations will be a mapping from the revisions to * their appropriate absolute paths. If the file doesn't exist in a * location_revision, that revision will be ignored. * @@ -1966,7 +2024,7 @@ svn_ra_get_locks(svn_ra_session_t *session, /** * Replay the changes from a range of revisions between @a start_revision - * and @a end_revision. + * and @a end_revision (inclusive). * * When receiving information for one revision, a callback @a revstart_func is * called; this callback will provide an editor and baton through which the @@ -2174,6 +2232,13 @@ svn_ra_has_capability(svn_ra_session_t *session, */ #define SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE "get-file-revs-reversed" +/** + * The capability of a server to understand the list command. + * + * @since New in 1.10. + */ +#define SVN_RA_CAPABILITY_LIST "list" + /* *** PLEASE READ THIS IF YOU ADD A NEW CAPABILITY *** * diff --git a/subversion/include/svn_ra_svn.h b/subversion/include/svn_ra_svn.h index c968e400805f..6293255daba9 100644 --- a/subversion/include/svn_ra_svn.h +++ b/subversion/include/svn_ra_svn.h @@ -49,6 +49,7 @@ extern "C" { /** Currently-defined capabilities. */ #define SVN_RA_SVN_CAP_EDIT_PIPELINE "edit-pipeline" #define SVN_RA_SVN_CAP_SVNDIFF1 "svndiff1" +#define SVN_RA_SVN_CAP_SVNDIFF2_ACCEPTED "accepts-svndiff2" #define SVN_RA_SVN_CAP_ABSENT_ENTRIES "absent-entries" /* maps to SVN_RA_CAPABILITY_COMMIT_REVPROPS: */ #define SVN_RA_SVN_CAP_COMMIT_REVPROPS "commit-revprops" @@ -68,6 +69,8 @@ extern "C" { #define SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS "ephemeral-txnprops" /* maps to SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE */ #define SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE "file-revs-reverse" +/* maps to SVN_RA_CAPABILITY_LIST */ +#define SVN_RA_SVN_CAP_LIST "list" /** ra_svn passes @c svn_dirent_t fields over the wire as a list of @@ -141,16 +144,23 @@ typedef struct svn_ra_svn_cmd_entry_t svn_boolean_t terminate; } svn_ra_svn_cmd_entry_t; +/** Data types defined by the svn:// protocol. + * + * @since The typedef name is new in 1.10; the enumerators are not. */ +typedef enum +{ + SVN_RA_SVN_NUMBER, + SVN_RA_SVN_STRING, + SVN_RA_SVN_WORD, + SVN_RA_SVN_LIST +} svn_ra_svn_item_kind_t; + /** Memory representation of an on-the-wire data item. */ typedef struct svn_ra_svn_item_t { /** Variant indicator. */ - enum { - SVN_RA_SVN_NUMBER, - SVN_RA_SVN_STRING, - SVN_RA_SVN_WORD, - SVN_RA_SVN_LIST - } kind; + svn_ra_svn_item_kind_t kind; + /** Variant data. */ union { apr_uint64_t number; @@ -169,7 +179,9 @@ typedef svn_error_t *(*svn_ra_svn_edit_callback)(void *baton); * * Either @a sock or @a in_stream/@a out_stream must be set, not both. * @a compression_level specifies the desired network data compression - * level (zlib) from 0 (no compression) to 9 (best but slowest). + * level from 0 (no compression) to 9 (best but slowest). The effect + * of the parameter depends on the compression algorithm; for example, + * it is used verbatim by zlib/deflate but ignored by LZ4. * * If @a zero_copy_limit is not 0, cached file contents smaller than the * given limit may be sent directly to the network socket. Otherwise, @@ -184,13 +196,38 @@ typedef svn_error_t *(*svn_ra_svn_edit_callback)(void *baton); * It defines the number of bytes that must have been sent since the last * check before the next check will be made. * + * If @a max_in is not 0, error out and close the connection whenever more + * than @a max_in bytes are received for a command (e.g. a client request). + * If @a max_out is not 0, error out and close the connection whenever more + * than @a max_out bytes have been send as response to some command. + * + * @note The limits enforced may vary slightly by +/- the I/O buffer size. + * * @note If @a out_stream is an wrapped apr_file_t* the backing file will be * used for some operations. * * Allocate the result in @a pool. * + * @since New in 1.10 + */ +svn_ra_svn_conn_t *svn_ra_svn_create_conn5(apr_socket_t *sock, + svn_stream_t *in_stream, + svn_stream_t *out_stream, + int compression_level, + apr_size_t zero_copy_limit, + apr_size_t error_check_interval, + apr_uint64_t max_in, + apr_uint64_t max_out, + apr_pool_t *result_pool); + + +/** Similar to svn_ra_svn_create_conn5() but with @a max_in and @a max_out + * set to 0. + * * @since New in 1.9 + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_ra_svn_conn_t *svn_ra_svn_create_conn4(apr_socket_t *sock, svn_stream_t *in_stream, svn_stream_t *out_stream, diff --git a/subversion/include/svn_repos.h b/subversion/include/svn_repos.h index 45b7a8fe579b..9bb462abbb3c 100644 --- a/subversion/include/svn_repos.h +++ b/subversion/include/svn_repos.h @@ -244,7 +244,13 @@ typedef enum svn_repos_notify_action_t svn_repos_notify_format_bumped, /** A revision range was copied. @since New in 1.9. */ - svn_repos_notify_hotcopy_rev_range + svn_repos_notify_hotcopy_rev_range, + + /** The repository pack did not do anything. @since New in 1.10. */ + svn_repos_notify_pack_noop, + + /** The revision properties got set. @since New in 1.10. */ + svn_repos_notify_load_revprop_set } svn_repos_notify_action_t; /** The type of warning occurring. @@ -369,6 +375,24 @@ typedef void (*svn_repos_notify_func_t)(void *baton, const svn_repos_notify_t *notify, apr_pool_t *scratch_pool); +/** Callback for filtering repository contents during dump. + * + * Set @a *include to TRUE to indicate that node, identified by path + * @a path in @a root should be included in dump, or set it to @c FALSE + * to indicate that node should be excluded (presumably according to state + * stored in @a baton). + * + * Do not assume @a scratch_pool has any lifetime beyond this call. + * + * @since New in 1.10. + */ +typedef svn_error_t * (*svn_repos_dump_filter_func_t)( + svn_boolean_t *include, + svn_fs_root_t *root, + const char *path, + void *baton, + apr_pool_t *scratch_pool); + /** * Allocate an #svn_repos_notify_t structure in @a result_pool, initialize * and return it. @@ -1701,6 +1725,68 @@ svn_repos_stat(svn_dirent_t **dirent, const char *path, apr_pool_t *pool); +/** + * Callback type to be used with svn_repos_list(). It will be invoked for + * every directory entry found. + * + * The full path of the entry is given in @a path and @a dirent contains + * various additional information. If svn_repos_list() has been called + * with @a path_info_only set, only the @a kind element of this struct + * will be valid. + * + * @a baton is the user-provided receiver baton. @a scratch_pool may be + * used for temporary allocations. + * + * @since New in 1.10. + */ +typedef svn_error_t *(* svn_repos_dirent_receiver_t)(const char *path, + svn_dirent_t *dirent, + void *baton, + apr_pool_t *scratch_pool); + +/** + * Efficiently list everything within a sub-tree. Specify glob patterns + * to search for specific files and folders. + * + * Walk the sub-tree starting at @a path under @a root up to the given + * @a depth. For each directory entry found, @a receiver will be called + * with @a receiver_baton. The starting @a path will be reported as well. + * Because retrieving all elements of a #svn_dirent_t can be expensive, + * you may set @a path_info_only to receive only the path name and the node + * kind. The entries will be reported ordered by their path. + * + * @a patterns is an optional array of <tt>const char *</tt>. If it is + * not @c NULL, only those directory entries will be reported whose last + * path segment matches at least one of these patterns. This feature uses + * apr_fnmatch() for glob matching and requiring '.' to matched by dots + * in the path. + * + * If @a authz_read_func is not @c NULL, this function will neither report + * entries nor recurse into directories that the user has no access to. + * + * Cancellation support is provided in the usual way through the optional + * @a cancel_func and @a cancel_baton. + * + * @a path must point to a directory and @a depth must be at least + * #svn_depth_empty. + * + * Use @a scratch_pool for temporary memory allocation. + * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_list(svn_fs_root_t *root, + const char *path, + const apr_array_header_t *patterns, + svn_depth_t depth, + svn_boolean_t path_info_only, + svn_repos_authz_func_t authz_read_func, + void *authz_read_baton, + svn_repos_dirent_receiver_t receiver, + void *receiver_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool); /** * Given @a path which exists at revision @a start in @a fs, set @@ -1864,13 +1950,181 @@ svn_repos_node_location_segments(svn_repos_t *repos, /* Retrieving log messages. */ +/** Path change descriptor. + * + * @note Identical to #svn_fs_path_change3_t but with all information + * known, i.e. @a node_kind is never #svn_node_unknown and + * @a copyfrom_known is always @c TRUE. + * + * @note To allow for extending this structure in future releases, + * always use svn_repos_path_change_create() to allocate the stucture. + * + * @see svn_fs_path_change3_t + * + * @since New in 1.10. + */ +typedef svn_fs_path_change3_t svn_repos_path_change_t; + +/** + * Return an #svn_repos_path_change_t structure, allocated in @a result_pool, + * with all fields initialized to their respective null/none/empty/invalid + * values. + * + * @note To allow for extending the #svn_repos_path_change_t structure in + * future releases, this function should always be used to allocate it. + * + * @since New in 1.10. + */ +svn_repos_path_change_t * +svn_repos_path_change_create(apr_pool_t *result_pool); + +/** + * Return a deep copy of @a change, allocated in @a result_pool. + * + * @since New in 1.10. + */ +svn_repos_path_change_t * +svn_repos_path_change_dup(svn_repos_path_change_t *change, + apr_pool_t *result_pool); + +/** The callback invoked by log message loopers, such as + * svn_repos_get_logs5(). + * + * This function is invoked once on each changed path, in a potentially + * random order that may even change between invocations for the same + * revisions. + * + * @a baton is what you think it is, and @a change contains relevant + * information for the changed path. Please note that @a change may be + * modified within this callback but it will become invalid as soon as + * the callback returns. + * + * Use @a scratch_pool for temporary allocation. The caller may clear it + * between or after invocations. + * + * @since New in 1.10. + */ +typedef svn_error_t *(*svn_repos_path_change_receiver_t)( + void *baton, + svn_repos_path_change_t *change, + apr_pool_t *scratch_pool); + /** - * Invoke @a receiver with @a receiver_baton on each log message from - * @a start to @a end in @a repos's filesystem. @a start may be greater - * or less than @a end; this just controls whether the log messages are + * A structure to represent all the information about a particular log entry. + * + * @note To allow for extending this structure in future releases, + * always use svn_repos_log_entry_create() to allocate the stucture. + * + * @since New in 1.10. + */ +typedef struct svn_repos_log_entry_t +{ + /** The revision of the commit. */ + svn_revnum_t revision; + + /** The hash of requested revision properties, which may be NULL if it + * would contain no revprops. Maps (const char *) property name to + * (svn_string_t *) property value. */ + apr_hash_t *revprops; + + /** + * Whether or not this message has children. + * + * When a log operation requests additional merge information, extra log + * entries may be returned as a result of this entry. The new entries, are + * considered children of the original entry, and will follow it. When + * the HAS_CHILDREN flag is set, the receiver should increment its stack + * depth, and wait until an entry is provided with SVN_INVALID_REVNUM which + * indicates the end of the children. + * + * For log operations which do not request additional merge information, the + * HAS_CHILDREN flag is always FALSE. + * + * For more information see: + * https://svn.apache.org/repos/asf/subversion/trunk/notes/merge-tracking/design.html#commutative-reporting + */ + svn_boolean_t has_children; + + /** + * Whether @a revision should be interpreted as non-inheritable in the + * same sense of #svn_merge_range_t. + * + * Currently always FALSE. + */ + svn_boolean_t non_inheritable; + + /** + * Whether @a revision is a merged revision resulting from a reverse merge. + */ + svn_boolean_t subtractive_merge; + + /* NOTE: Add new fields at the end to preserve binary compatibility. */ +} svn_repos_log_entry_t; + +/** + * Return an #svn_repos_log_entry_t, allocated in @a result_pool, + * with all fields initialized to their respective null/none/empty/invalid + * values. + * + * @note To allow for extending the #svn_repos_log_entry_t structure in + * future releases, this function should always be used to allocate it. + * + * @since New in 1.10. + */ +svn_repos_log_entry_t * +svn_repos_log_entry_create(apr_pool_t *result_pool); + +/** Return a deep copy of @a log_entry, allocated in @a result_pool. + * + * @since New in 1.10. + */ +svn_repos_log_entry_t * +svn_repos_log_entry_dup(const svn_repos_log_entry_t *log_entry, + apr_pool_t *result_pool); + + +/** The callback invoked by log message loopers, such as + * svn_repos_get_logs5(). + * + * This function is invoked once on each log message, in the order + * determined by the caller (see above-mentioned functions). + * + * @a baton is what you think it is, and @a log_entry contains relevant + * information for the log message. + * + * If @a log_entry->has_children is @c TRUE, the message will be followed + * immediately by any number of merged revisions (child messages), which are + * terminated by an invocation with SVN_INVALID_REVNUM. This usage may + * be recursive. + * + * Use @a scratch_pool for temporary allocation. The caller may clear it + * between or after invocations. + * + * @since New in 1.10. + */ +typedef svn_error_t *(*svn_repos_log_entry_receiver_t)( + void *baton, + svn_repos_log_entry_t *log_entry, + apr_pool_t *scratch_pool); + + +/** + * Invoke @a revision_receiver with @a revision_receiver_baton on each + * revision from @a start to @a end in @a repos's filesystem. @a start may + * be greater or less than @a end; this just controls whether the log is * processed in descending or ascending revision number order. * + * If not @c NULL, @a path_change_receiver will be invoked with + * @a path_change_receiver_baton for each changed path in the respective + * revision. These changes will be reported before the @a revision_receiver + * is invoked for that revision. So, for each revision in the log, there + * is a number of calls to @a path_change_receiver followed by a single + * invocation of @a revision_receiver, implicitly marking the end of the + * changes list for that revision. If a revision does not contain any + * changes (or if none are visible due to @a authz_read_func), + * @a path_change_receiver will not be called for that revision. + * * If @a start or @a end is #SVN_INVALID_REVNUM, it defaults to youngest. * * If @a paths is non-NULL and has one or more elements, then only show @@ -1881,13 +2135,8 @@ svn_repos_node_location_segments(svn_repos_t *repos, * show all revisions regardless of what paths were changed in those * revisions. * - * If @a limit is greater than zero then only invoke @a receiver on the first - * @a limit logs. - * - * If @a discover_changed_paths, then each call to @a receiver passes a - * hash mapping paths committed in that revision to information about them - * as the receiver's @a changed_paths argument. - * Otherwise, each call to @a receiver passes NULL for @a changed_paths. + * If @a limit is greater than zero then only invoke @a revision_receiver + * on the first @a limit logs. * * If @a strict_node_history is set, copy history (if any exists) will * not be traversed while harvesting revision logs for each path. @@ -1902,28 +2151,64 @@ svn_repos_node_location_segments(svn_repos_t *repos, * only the revision properties named by the (const char *) array elements * (i.e. retrieve none if the array is empty). * - * If any invocation of @a receiver returns error, return that error - * immediately and without wrapping it. + * If any invocation of @a revision_receiver or @a path_change_receiver + * returnn an error, return that error immediately and without wrapping it. * * If @a start or @a end is a non-existent revision, return the error - * #SVN_ERR_FS_NO_SUCH_REVISION, without ever invoking @a receiver. + * #SVN_ERR_FS_NO_SUCH_REVISION, without ever invoking @a revision_receiver. * * If optional @a authz_read_func is non-NULL, then use this function * (along with optional @a authz_read_baton) to check the readability * of each changed-path in each revision about to be "pushed" at - * @a receiver. If a revision has some changed-paths readable and - * others unreadable, unreadable paths are omitted from the - * changed_paths field and only svn:author and svn:date will be - * available in the revprops field. If a revision has no - * changed-paths readable at all, then all paths are omitted and no - * revprops are available. + * @a path_change_receiver. If a revision has some changed-paths readable + * and others unreadable, unreadable paths are omitted from the + * @a path_change_receiver invocations and only svn:author and svn:date + * will be available in the revprops field in the @a revision_receiver + * callback. If a revision has no changed-paths readable at all, then all + * paths are omitted and no revprops are available. If + * @a path_change_receiver is @c NULL, the same filtering is performed + * just without reporting any path changes. * - * See also the documentation for #svn_log_entry_receiver_t. + * Use @a scratch_pool for temporary allocations. * - * Use @a pool for temporary allocations. + * @see svn_repos_path_change_receiver_t, svn_repos_log_entry_receiver_t + * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_get_logs5(svn_repos_t *repos, + const apr_array_header_t *paths, + svn_revnum_t start, + svn_revnum_t end, + int limit, + svn_boolean_t strict_node_history, + svn_boolean_t include_merged_revisions, + const apr_array_header_t *revprops, + svn_repos_authz_func_t authz_read_func, + void *authz_read_baton, + svn_repos_path_change_receiver_t path_change_receiver, + void *path_change_receiver_baton, + svn_repos_log_entry_receiver_t revision_receiver, + void *revision_receiver_baton, + apr_pool_t *scratch_pool); + +/** + * Similar to svn_repos_get_logs5 but using a #svn_log_entry_receiver_t + * @a receiver to receive revision properties and changed paths through a + * single callback and the @a discover_changed_paths flag to control it. + * + * If @a discover_changed_paths, then each call to @a receiver passes a + * hash mapping paths committed in that revision to information about them + * as the receiver's @a changed_paths argument. + * Otherwise, each call to @a receiver passes NULL for @a changed_paths. + * + * @see svn_log_entry_receiver_t * * @since New in 1.5. + * + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_repos_get_logs4(svn_repos_t *repos, const apr_array_header_t *paths, @@ -2009,12 +2294,20 @@ svn_repos_get_logs(svn_repos_t *repos, /* Retrieving mergeinfo. */ +/** Receives parsed @a mergeinfo for the file system path @a path. + * + * The user-provided @a baton is being passed through by the retrieval + * function and @a scratch_pool will be cleared between invocations. + * + * @since New in 1.10. + */ +typedef svn_fs_mergeinfo_receiver_t svn_repos_mergeinfo_receiver_t; + /** - * Fetch the mergeinfo for @a paths at @a revision in @a repos, and - * set @a *catalog to a catalog of this mergeinfo. @a *catalog will - * never be @c NULL but may be empty. + * For each node found with mergeinfo on it, invoke @a receiver with + * the provided @a receiver_baton. * - * The paths in @a paths, and the keys of @a catalog, start with '/'. + * The paths in @a paths start with '/'. * * @a inherit indicates whether explicit, explicit or inherited, or * only inherited mergeinfo for @a paths is fetched. @@ -2026,17 +2319,38 @@ svn_repos_get_logs(svn_repos_t *repos, * the #SVN_PROP_MERGEINFO property explicitly set on it. (Note * that inheritance is only taken into account for the elements in @a * paths; descendants of the elements in @a paths which get their - * mergeinfo via inheritance are not included in @a *catalog.) + * mergeinfo via inheritance are not reported to @a receiver.) * * If optional @a authz_read_func is non-NULL, then use this function * (along with optional @a authz_read_baton) to check the readability * of each path which mergeinfo was requested for (from @a paths). * Silently omit unreadable paths from the request for mergeinfo. * - * Use @a pool for all allocations. + * Use @a scratch_pool for temporary allocations. + * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_fs_get_mergeinfo2(svn_repos_t *repos, + const apr_array_header_t *paths, + svn_revnum_t revision, + svn_mergeinfo_inheritance_t inherit, + svn_boolean_t include_descendants, + svn_repos_authz_func_t authz_read_func, + void *authz_read_baton, + svn_repos_mergeinfo_receiver_t receiver, + void *receiver_baton, + apr_pool_t *scratch_pool); + +/** + * Same as svn_repos_fs_get_mergeinfo2(), but all mergeinfo is being collected + * and returned in @a *catalog. It will never be @c NULL, but may be empty. * * @since New in 1.5. + * + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_repos_fs_get_mergeinfo(svn_mergeinfo_catalog_t *catalog, svn_repos_t *repos, @@ -2983,6 +3297,12 @@ svn_repos_verify_fs(svn_repos_t *repos, * be done with full plain text. A dump with @a use_deltas set cannot * be loaded by Subversion 1.0.x. * + * If @a include_revprops is @c TRUE, output the revision properties as + * well, otherwise omit them. + * + * If @a include_changes is @c TRUE, output the revision contents, i.e. + * tree and node changes. + * * If @a notify_func is not null, then call it with @a notify_baton and * with a notification structure in which the fields are set as follows. * (For a warning or error notification that does not apply to a specific @@ -3008,14 +3328,43 @@ svn_repos_verify_fs(svn_repos_t *repos, * reiterating the existence of previous warnings * ### This is a presentation issue. Caller could do this itself. * + * If @a filter_func is not @c NULL, it is called for each node being + * dumped, allowing the caller to exclude it from dump. + * * If @a cancel_func is not @c NULL, it is called periodically with * @a cancel_baton as argument to see if the client wishes to cancel * the dump. * * Use @a scratch_pool for temporary allocation. * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_dump_fs4(svn_repos_t *repos, + svn_stream_t *stream, + svn_revnum_t start_rev, + svn_revnum_t end_rev, + svn_boolean_t incremental, + svn_boolean_t use_deltas, + svn_boolean_t include_revprops, + svn_boolean_t include_changes, + svn_repos_notify_func_t notify_func, + void *notify_baton, + svn_repos_dump_filter_func_t filter_func, + void *filter_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool); + +/** + * Similar to svn_repos_dump_fs4(), but with @a include_revprops and + * @a include_changes both set to @c TRUE and @a filter_func and + * @a filter_baton set to @c NULL. + * * @since New in 1.7. + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_repos_dump_fs3(svn_repos_t *repos, svn_stream_t *dumpstream, @@ -3111,6 +3460,15 @@ svn_repos_dump_fs(svn_repos_t *repos, * to be stamped as if they were newly created via the normal commit * process. * + * If @a normalize_props is set, attempt to normalize invalid Subversion + * revision and node properties (those in the svn: namespace) so that + * their values would follow the established rules for them. For example, + * for such properties, typically the value must be in UTF-8 with LF + * line endings. + * + * @note The details or the performed normalizations are deliberately + * left unspecified and may change in the future. + * * If non-NULL, use @a notify_func and @a notify_baton to send notification * of events to the caller. * @@ -3118,8 +3476,34 @@ svn_repos_dump_fs(svn_repos_t *repos, * @a cancel_baton as argument to see if the client wishes to cancel * the load. * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_load_fs6(svn_repos_t *repos, + svn_stream_t *dumpstream, + svn_revnum_t start_rev, + svn_revnum_t end_rev, + enum svn_repos_load_uuid uuid_action, + const char *parent_dir, + svn_boolean_t use_pre_commit_hook, + svn_boolean_t use_post_commit_hook, + svn_boolean_t validate_props, + svn_boolean_t ignore_dates, + svn_boolean_t normalize_props, + svn_repos_notify_func_t notify_func, + void *notify_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool); + +/** + * Similar to svn_repos_load_fs6(), but with the @a normalize_props + * parameter always set to @c FALSE. + * * @since New in 1.9. + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_repos_load_fs5(svn_repos_t *repos, svn_stream_t *dumpstream, @@ -3219,6 +3603,62 @@ svn_repos_load_fs(svn_repos_t *repos, void *cancel_baton, apr_pool_t *pool); +/** + * Read and parse dumpfile-formatted @a dumpstream, extracting the + * revision properties from it and apply them to the already-open + * @a repos. Use @a scratch_pool for temporary allocations. + * + * If, after filtering by the @a start_rev and @a end_rev, the dumpstream + * contains revisions missing in @a repos, an error will be thrown. + * + * @a start_rev and @a end_rev act as filters, the lower and upper + * (inclusive) range values of revisions in @a dumpstream which will + * be loaded. Either both of these values are #SVN_INVALID_REVNUM (in + * which case no revision-based filtering occurs at all), or both are + * valid revisions (where @a start_rev is older than or equivalent to + * @a end_rev). + * + * If @a validate_props is set, then validate Subversion revision + * properties (those in the svn: namespace) against established + * rules for those things. + * + * If @a ignore_dates is set, ignore any revision datestamps found in + * @a dumpstream, keeping whatever timestamps the revisions currently + * have. + * + * If @a normalize_props is set, attempt to normalize invalid Subversion + * revision and node properties (those in the svn: namespace) so that + * their values would follow the established rules for them. For example, + * for such properties, typically the value must be in UTF-8 with LF + * line endings. + * + * @note The details or the performed normalizations are deliberately + * left unspecified and may change in the future. + * + * If non-NULL, use @a notify_func and @a notify_baton to send notification + * of events to the caller. + * + * If @a cancel_func is not @c NULL, it is called periodically with + * @a cancel_baton as argument to see if the client wishes to cancel + * the load. + * + * @remark No repository hooks will be triggered. + * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_load_fs_revprops(svn_repos_t *repos, + svn_stream_t *dumpstream, + svn_revnum_t start_rev, + svn_revnum_t end_rev, + svn_boolean_t validate_props, + svn_boolean_t ignore_dates, + svn_boolean_t normalize_props, + svn_repos_notify_func_t notify_func, + void *notify_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool); /** * A vtable that is driven by svn_repos_parse_dumpstream3(). @@ -3362,6 +3802,9 @@ typedef struct svn_repos_parse_fns3_t * could stop reading entirely after the youngest required rev. * * @since New in 1.8. + + * @since Starting in 1.10, @a parse_fns may contain #NULL pointers for + * those callbacks that the caller is not interested in. */ svn_error_t * svn_repos_parse_dumpstream3(svn_stream_t *stream, @@ -3414,12 +3857,47 @@ svn_repos_parse_dumpstream3(svn_stream_t *stream, * to be stamped as if they were newly created via the normal commit * process. * + * If @a normalize_props is set, attempt to normalize invalid Subversion + * revision and node properties (those in the svn: namespace) so that + * their values would follow the established rules for them. For example, + * for such properties, typically the value must be in UTF-8 with LF + * line endings. + * + * @note The details or the performed normalizations are deliberately + * left unspecified and may change in the future. + * * If @a parent_dir is not NULL, then the parser will reparent all the * loaded nodes, from root to @a parent_dir. The directory @a parent_dir * must be an existing directory in the repository. * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_get_fs_build_parser6(const svn_repos_parse_fns3_t **parser, + void **parse_baton, + svn_repos_t *repos, + svn_revnum_t start_rev, + svn_revnum_t end_rev, + svn_boolean_t use_history, + svn_boolean_t validate_props, + enum svn_repos_load_uuid uuid_action, + const char *parent_dir, + svn_boolean_t use_pre_commit_hook, + svn_boolean_t use_post_commit_hook, + svn_boolean_t ignore_dates, + svn_boolean_t normalize_props, + svn_repos_notify_func_t notify_func, + void *notify_baton, + apr_pool_t *pool); + +/** + * Similar to svn_repos_get_fs_build_parser6(), but with the + * @a normalize_props parameter always set to @c FALSE. + * * @since New in 1.9. + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_repos_get_fs_build_parser5(const svn_repos_parse_fns3_t **parser, void **parse_baton, @@ -3655,6 +4133,17 @@ svn_repos_get_fs_build_parser(const svn_repos_parser_fns_t **parser, typedef struct svn_authz_t svn_authz_t; /** + * This should be called before any other authz function. + * + * @a pool must support multi-threaded access if the application will use + * authz from multiple threads. + * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_authz_initialize(apr_pool_t *pool); + +/** * Read authz configuration data from @a path (a dirent, an absolute file url * or a registry path) into @a *authz_p, allocated in @a pool. * @@ -3667,8 +4156,29 @@ typedef struct svn_authz_t svn_authz_t; * is also an error other than #SVN_ERR_AUTHZ_INVALID_CONFIG (exact error * depends on the access type). * + * For efficient access of in-repository authz, you may provide @a repos_hint + * which will be tried first and may remove the need to open a temporary + * repository instance. Otherwise, set it to NULL and the repositories will + * be opened as needed. + * + * @since New in 1.10. + */ +svn_error_t * +svn_repos_authz_read3(svn_authz_t **authz_p, + const char *path, + const char *groups_path, + svn_boolean_t must_exist, + svn_repos_t *repos_hint, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Similar to svn_repos_authz_read3(), but with @a repos_hint set to @c NULL. + * * @since New in 1.8. + * @deprecated Provided for backward compatibility with the 1.9 API. */ +SVN_DEPRECATED svn_error_t * svn_repos_authz_read2(svn_authz_t **authz_p, const char *path, diff --git a/subversion/include/svn_string.h b/subversion/include/svn_string.h index 82c6fd693e20..9b0cf5cf7f8f 100644 --- a/subversion/include/svn_string.h +++ b/subversion/include/svn_string.h @@ -294,6 +294,14 @@ svn_stringbuf_isempty(const svn_stringbuf_t *str); void svn_stringbuf_chop(svn_stringbuf_t *str, apr_size_t nbytes); +/** + * Chop @a nbytes bytes off the start of @a str, but not more than @a str->len. + * + * @since New in 1.10. + */ +void +svn_stringbuf_leftchop(svn_stringbuf_t *str, apr_size_t nbytes); + /** Fill @a str with character @a c. */ void svn_stringbuf_fillchar(svn_stringbuf_t *str, unsigned char c); @@ -404,6 +412,16 @@ svn_stringbuf_replace(svn_stringbuf_t *str, const char *bytes, apr_size_t new_count); +/** Replace all occurrences of @a to_find in @a str with @a replacement. + * Return the number of replacements made. + * + * @since New in 1.10. + */ +apr_size_t +svn_stringbuf_replace_all(svn_stringbuf_t *str, + const char *to_find, + const char *replacement); + /** Return a duplicate of @a original_string. */ svn_stringbuf_t * svn_stringbuf_dup(const svn_stringbuf_t *original_string, apr_pool_t *pool); @@ -512,12 +530,27 @@ svn_cstring_count_newlines(const char *msg); /** * Return a cstring which is the concatenation of @a strings (an array - * of char *) each followed by @a separator (that is, @a separator - * will also end the resulting string). Allocate the result in @a pool. + * of char *) joined by @a separator. Allocate the result in @a pool. * If @a strings is empty, then return the empty string. + * If @a trailing_separator is non-zero, also append the separator + * after the last joined element. + * + * @since New in 1.10. + */ +char * +svn_cstring_join2(const apr_array_header_t *strings, + const char *separator, + svn_boolean_t trailing_separator, + apr_pool_t *pool); + +/** + * Similar to svn_cstring_join2(), but always includes the trailing + * separator. * * @since New in 1.2. + * @deprecated Provided for backwards compatibility with the 1.9 API. */ +SVN_DEPRECATED char * svn_cstring_join(const apr_array_header_t *strings, const char *separator, @@ -541,7 +574,17 @@ svn_cstring_casecmp(const char *str1, const char *str2); * Assume that the number is represented in base @a base. * Raise an error if conversion fails (e.g. due to overflow), or if the * converted number is smaller than @a minval or larger than @a maxval. + * * Leading whitespace in @a str is skipped in a locale-dependent way. + * After that, the string may contain an optional '+' (positive, default) + * or '-' (negative) character, followed by an optional '0x' prefix if + * @a base is 0 or 16, followed by numeric digits appropriate for the base. + * If there are any more characters after the numeric digits, an error is + * returned. + * + * If @a base is zero, then a leading '0x' or '0X' prefix means hexadecimal, + * else a leading '0' means octal (implemented, though not documented, in + * apr_strtoi64() in APR 0.9.0 through 1.5.0), else use base ten. * * @since New in 1.7. */ @@ -554,7 +597,8 @@ svn_cstring_strtoi64(apr_int64_t *n, const char *str, * Parse the C string @a str into a 64 bit number, and return it in @a *n. * Assume that the number is represented in base 10. * Raise an error if conversion fails (e.g. due to overflow). - * Leading whitespace in @a str is skipped in a locale-dependent way. + * + * The behaviour otherwise is as described for svn_cstring_strtoi64(). * * @since New in 1.7. */ @@ -565,7 +609,8 @@ svn_cstring_atoi64(apr_int64_t *n, const char *str); * Parse the C string @a str into a 32 bit number, and return it in @a *n. * Assume that the number is represented in base 10. * Raise an error if conversion fails (e.g. due to overflow). - * Leading whitespace in @a str is skipped in a locale-dependent way. + * + * The behaviour otherwise is as described for svn_cstring_strtoi64(). * * @since New in 1.7. */ @@ -577,7 +622,21 @@ svn_cstring_atoi(int *n, const char *str); * it in @a *n. Assume that the number is represented in base @a base. * Raise an error if conversion fails (e.g. due to overflow), or if the * converted number is smaller than @a minval or larger than @a maxval. + * * Leading whitespace in @a str is skipped in a locale-dependent way. + * After that, the string may contain an optional '+' (positive, default) + * or '-' (negative) character, followed by an optional '0x' prefix if + * @a base is 0 or 16, followed by numeric digits appropriate for the base. + * If there are any more characters after the numeric digits, an error is + * returned. + * + * If @a base is zero, then a leading '0x' or '0X' prefix means hexadecimal, + * else a leading '0' means octal (implemented, though not documented, in + * apr_strtoi64() in APR 0.9.0 through 1.5.0), else use base ten. + * + * @warning The implementation used since version 1.7 returns an error + * if the parsed number is greater than APR_INT64_MAX, even if it is not + * greater than @a maxval. * * @since New in 1.7. */ @@ -590,7 +649,9 @@ svn_cstring_strtoui64(apr_uint64_t *n, const char *str, * Parse the C string @a str into an unsigned 64 bit number, and return * it in @a *n. Assume that the number is represented in base 10. * Raise an error if conversion fails (e.g. due to overflow). - * Leading whitespace in @a str is skipped in a locale-dependent way. + * + * The behaviour otherwise is as described for svn_cstring_strtoui64(), + * including the upper limit of APR_INT64_MAX. * * @since New in 1.7. */ @@ -601,7 +662,9 @@ svn_cstring_atoui64(apr_uint64_t *n, const char *str); * Parse the C string @a str into an unsigned 32 bit number, and return * it in @a *n. Assume that the number is represented in base 10. * Raise an error if conversion fails (e.g. due to overflow). - * Leading whitespace in @a str is skipped in a locale-dependent way. + * + * The behaviour otherwise is as described for svn_cstring_strtoui64(), + * including the upper limit of APR_INT64_MAX. * * @since New in 1.7. */ diff --git a/subversion/include/svn_types.h b/subversion/include/svn_types.h index f1a0850bcf8a..394eda866937 100644 --- a/subversion/include/svn_types.h +++ b/subversion/include/svn_types.h @@ -416,7 +416,7 @@ svn_tristate__from_word(const char * word); * 2. Creating a new textual name similar to * SVN_SUBST__SPECIAL_LINK_STR in libsvn_subr/subst.c. * 3. Handling the translation/detranslation case for the new type in - * create_special_file and detranslate_special_file, using the + * create_special_file_from_stream and detranslate_special_file, using the * routines from 1. */ @@ -652,7 +652,7 @@ typedef struct svn_dirent_t /** node kind */ svn_node_kind_t kind; - /** length of file text, or 0 for directories */ + /** length of file text, otherwise SVN_INVALID_FILESIZE */ svn_filesize_t size; /** does the node have props? */ @@ -1078,6 +1078,11 @@ typedef svn_error_t *(*svn_log_message_receiver_t)( * @a commit_info, along with the @a baton closure. * @a pool can be used for temporary allocations. * + * @note Implementers of this callback that pass this callback to + * svn_ra_get_commit_editor3() should be careful with returning errors + * as these might be returned as commit errors. See the documentation + * of svn_ra_get_commit_editor3() for more details. + * * @since New in 1.4. */ typedef svn_error_t *(*svn_commit_callback2_t)( diff --git a/subversion/include/svn_user.h b/subversion/include/svn_user.h index 65e28200b6d0..922fdcf0a175 100644 --- a/subversion/include/svn_user.h +++ b/subversion/include/svn_user.h @@ -45,6 +45,9 @@ svn_user_get_name(apr_pool_t *pool); * any necessary allocation, returning NULL on error. * * @since New in 1.4. + * @since 1.10 returns a canonical path. Earlier versions returned a + * non-canonical path if the operating system reported a non-canonical + * path such as "/home/user/" or "//home/user". */ const char * svn_user_get_homedir(apr_pool_t *pool); diff --git a/subversion/include/svn_version.h b/subversion/include/svn_version.h index 39f7154847e5..9c88b5b2f71d 100644 --- a/subversion/include/svn_version.h +++ b/subversion/include/svn_version.h @@ -61,7 +61,7 @@ extern "C" { * Modify when new functionality is added or new interfaces are * defined, but all changes are backward compatible. */ -#define SVN_VER_MINOR 9 +#define SVN_VER_MINOR 10 /** * Patch number. @@ -70,7 +70,7 @@ extern "C" { * * @since New in 1.1. */ -#define SVN_VER_PATCH 7 +#define SVN_VER_PATCH 0 /** @deprecated Provided for backward compatibility with the 1.0 API. */ @@ -93,7 +93,7 @@ extern "C" { * * Always change this at the same time as SVN_VER_NUMTAG. */ -#define SVN_VER_TAG " (r1800392)" +#define SVN_VER_TAG " (r1827917)" /** Number tag: a string describing the version. @@ -117,7 +117,7 @@ extern "C" { * file version. Its value remains 0 in the repository except in release * tags where it is the revision from which the tag was created. */ -#define SVN_VER_REVISION 1800392 +#define SVN_VER_REVISION 1827917 /* Version strings composed from the above definitions. */ diff --git a/subversion/include/svn_wc.h b/subversion/include/svn_wc.h index 010597bd6eeb..e632673e0ae4 100644 --- a/subversion/include/svn_wc.h +++ b/subversion/include/svn_wc.h @@ -998,7 +998,10 @@ typedef enum svn_wc_notify_action_t /** A revert operation has failed. */ svn_wc_notify_failed_revert, - /** Resolving a conflict. */ + /** All conflicts on a path were marked as resolved. + * @note As of 1.10, separate notifications are sent for individually + * resolved text, property, and tree conflicts. This notification is used + * only if all conflicts on a path were marked resolved at once. */ svn_wc_notify_resolved, /** Skipping a path. */ @@ -1274,7 +1277,34 @@ typedef enum svn_wc_notify_action_t /** Finalizing commit. * @since New in 1.9. */ - svn_wc_notify_commit_finalizing + svn_wc_notify_commit_finalizing, + + /** All text conflicts in a file were marked as resolved. + * @since New in 1.10. */ + svn_wc_notify_resolved_text, + + /** A property conflict on a path was marked as resolved. + * The name of the property is specified in #svn_wc_notify_t.prop_name. + * @since New in 1.10. */ + svn_wc_notify_resolved_prop, + + /** A tree conflict on a path was marked as resolved. + * @since New in 1.10. */ + svn_wc_notify_resolved_tree, + + /** Starting to search the repository for details about a tree conflict. + * @since New in 1.10. */ + svn_wc_notify_begin_search_tree_conflict_details, + + /** Progressing in search of repository for details about a tree conflict. + * The revision being searched is specified in #svn_wc_notify_t.revision. + * @since New in 1.10. */ + svn_wc_notify_tree_conflict_details_progress, + + /** Done searching the repository for details about a conflict. + * @since New in 1.10. */ + svn_wc_notify_end_search_tree_conflict_details + } svn_wc_notify_action_t; @@ -1911,8 +1941,9 @@ typedef struct svn_wc_conflict_description_t /** The path that is in conflict (for a tree conflict, it is the victim) */ const char *path; - /** The node type of the path being operated on (for a tree conflict, - * ### which version?) */ + /** The local node type of the path being operated on (for a tree conflict, + * this specifies the local node kind, which may be (and typically is) + * different than the left and right kind) */ svn_node_kind_t node_kind; /** What sort of conflict are we describing? */ @@ -2063,7 +2094,7 @@ svn_wc_conflict_description_create_prop(const char *path, * * Set the @c local_abspath field of the created struct to @a local_abspath * (which must be an absolute path), the @c kind field to - * #svn_wc_conflict_kind_tree, the @c local_node_kind to @a local_node_kind, + * #svn_wc_conflict_kind_tree, the @c node_kind to @a node_kind, * the @c operation to @a operation, the @c src_left_version field to * @a src_left_version, and the @c src_right_version field to * @a src_right_version. @@ -2131,8 +2162,11 @@ svn_wc__conflict_description2_dup( */ typedef enum svn_wc_conflict_choice_t { - /** Undefined; for internal use only. - This value is never returned in svn_wc_conflict_result_t. + /** Undefined; for private use only. + This value must never be returned in svn_wc_conflict_result_t, + but a separate value, unequal to all other pre-defined values may + be useful in conflict resolver implementations to signal that no + choice is made yet. * @since New in 1.9 */ svn_wc_conflict_choose_undefined = -1, @@ -4544,7 +4578,7 @@ svn_wc_move(svn_wc_context_t *wc_ctx, * and everything below @a local_abspath. * * If @a keep_local is FALSE, this function immediately deletes all files, - * modified and unmodified, versioned and of @a delete_unversioned is TRUE, + * modified and unmodified, versioned and if @a delete_unversioned is TRUE, * unversioned from the working copy. * It also immediately deletes unversioned directories and directories that * are scheduled to be added below @a local_abspath. Only versioned may @@ -5050,7 +5084,11 @@ svn_wc_remove_from_revision_control(svn_wc_adm_access_t *adm_access, * Temporary allocations will be performed in @a scratch_pool. * * @since New in 1.7. + * @deprecated Provided for backward compatibility with the 1.9 API. + * Use svn_client_conflict_text_resolve(), svn_client_conflict_prop_resolve(), + * and svn_client_conflict_tree_resolve() instead. */ +SVN_DEPRECATED svn_error_t * svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx, const char *local_abspath, diff --git a/subversion/include/svn_x509.h b/subversion/include/svn_x509.h index eabe3ed46c8b..e3cb7941d357 100644 --- a/subversion/include/svn_x509.h +++ b/subversion/include/svn_x509.h @@ -166,7 +166,7 @@ svn_x509_certinfo_get_valid_from(const svn_x509_certinfo_t *certinfo); * * @since New in 1.9. */ -const apr_time_t +apr_time_t svn_x509_certinfo_get_valid_to(const svn_x509_certinfo_t *certinfo); /** @@ -188,7 +188,7 @@ svn_x509_certinfo_get_hostnames(const svn_x509_certinfo_t *certinfo); * Given an @a oid return a null-terminated C string representation. * For example an OID with the bytes "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" * would be converted to the string "1.2.840.113549.1.9.1". Returns - * NULL if the @oid can't be represented as a string. + * NULL if the @a oid can't be represented as a string. * * @since New in 1.9. */ const char * diff --git a/subversion/include/svn_xml.h b/subversion/include/svn_xml.h index 8791b143750c..1a52166feaea 100644 --- a/subversion/include/svn_xml.h +++ b/subversion/include/svn_xml.h @@ -169,7 +169,15 @@ typedef void (*svn_xml_char_data)(void *baton, apr_size_t len); -/** Create a general Subversion XML parser */ +/** Create a general Subversion XML parser. + * + * The @c svn_xml_parser_t object itself will be allocated from @a pool, + * but some internal structures may be allocated out of pool. Use + * svn_xml_free_parser() to free all memory used by the parser. + * + * @since Since Subversion 1.10 parser will be freed automatically on pool + * cleanup or by svn_xml_free_parser() call. + */ svn_xml_parser_t * svn_xml_make_parser(void *baton, svn_xml_start_elem start_handler, |
