Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_fs_fs/tree.c view on Meta::CPAN
that is null, TXN's base node.
If the merge is successful, TXN's base will become
SOURCE_NODE, and its root node will have a new ID, a
successor of SOURCE_NODE.
If a conflict results, update *CONFLICT to the path in the txn that
conflicted; see the CONFLICT_P parameter of merge() for details. */
static svn_error_t *
merge_changes(dag_node_t *ancestor_node,
dag_node_t *source_node,
svn_fs_txn_t *txn,
svn_stringbuf_t *conflict,
apr_pool_t *pool)
{
dag_node_t *txn_root_node;
svn_fs_t *fs = txn->fs;
const char *txn_id = txn->id;
SVN_ERR(svn_fs_fs__dag_txn_root(&txn_root_node, fs, txn_id, pool));
if (ancestor_node == NULL)
{
SVN_ERR(svn_fs_fs__dag_txn_base_root(&ancestor_node, fs,
txn_id, pool));
}
if (svn_fs_fs__id_eq(svn_fs_fs__dag_get_id(ancestor_node),
svn_fs_fs__dag_get_id(txn_root_node)))
{
/* If no changes have been made in TXN since its current base,
then it can't conflict with any changes since that base.
The caller isn't supposed to call us in that case. */
SVN_ERR_MALFUNCTION();
}
else
SVN_ERR(merge(conflict, "/", txn_root_node,
source_node, ancestor_node, txn_id, NULL, pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_fs__commit_txn(const char **conflict_p,
svn_revnum_t *new_rev,
svn_fs_txn_t *txn,
apr_pool_t *pool)
{
/* How do commits work in Subversion?
*
* When you're ready to commit, here's what you have:
*
* 1. A transaction, with a mutable tree hanging off it.
* 2. A base revision, against which TXN_TREE was made.
* 3. A latest revision, which may be newer than the base rev.
*
* The problem is that if latest != base, then one can't simply
* attach the txn root as the root of the new revision, because that
* would lose all the changes between base and latest. It is also
* not acceptable to insist that base == latest; in a busy
* repository, commits happen too fast to insist that everyone keep
* their entire tree up-to-date at all times. Non-overlapping
* changes should not interfere with each other.
*
* The solution is to merge the changes between base and latest into
* the txn tree [see the function merge()]. The txn tree is the
* only one of the three trees that is mutable, so it has to be the
* one to adjust.
*
* You might have to adjust it more than once, if a new latest
* revision gets committed while you were merging in the previous
* one. For example:
*
* 1. Jane starts txn T, based at revision 6.
* 2. Someone commits (or already committed) revision 7.
* 3. Jane's starts merging the changes between 6 and 7 into T.
* 4. Meanwhile, someone commits revision 8.
* 5. Jane finishes the 6-->7 merge. T could now be committed
* against a latest revision of 7, if only that were still the
* latest. Unfortunately, 8 is now the latest, so...
* 6. Jane starts merging the changes between 7 and 8 into T.
* 7. Meanwhile, no one commits any new revisions. Whew.
* 8. Jane commits T, creating revision 9, whose tree is exactly
* T's tree, except immutable now.
*
* Lather, rinse, repeat.
*/
svn_error_t *err = SVN_NO_ERROR;
svn_stringbuf_t *conflict = svn_stringbuf_create_empty(pool);
svn_fs_t *fs = txn->fs;
/* Limit memory usage when the repository has a high commit rate and
needs to run the following while loop multiple times. The memory
growth without an iteration pool is very noticeable when the
transaction modifies a node that has 20,000 sibling nodes. */
apr_pool_t *iterpool = svn_pool_create(pool);
/* Initialize output params. */
*new_rev = SVN_INVALID_REVNUM;
if (conflict_p)
*conflict_p = NULL;
while (1729)
{
svn_revnum_t youngish_rev;
svn_fs_root_t *youngish_root;
dag_node_t *youngish_root_node;
svn_pool_clear(iterpool);
/* Get the *current* youngest revision. We call it "youngish"
because new revisions might get committed after we've
obtained it. */
SVN_ERR(svn_fs_fs__youngest_rev(&youngish_rev, fs, iterpool));
SVN_ERR(svn_fs_fs__revision_root(&youngish_root, fs, youngish_rev,
iterpool));
/* Get the dag node for the youngest revision. Later we'll use
( run in 0.531 second using v1.01-cache-2.11-cpan-140bd7fdf52 )