FreeBSD/contrib/subversion/subversion/libsvn_fs_x/tree.c
/* Merge changes between two nodes into a third node.  Given nodes
   SOURCE_PATH under SOURCE_ROOT, TARGET_PATH under TARGET_ROOT and
   ANCESTOR_PATH under ANCESTOR_ROOT, modify target to contain all the
   changes between the ancestor and source.  If there are conflicts,
   return SVN_ERR_FS_CONFLICT and set *CONFLICT_P to a textual
   description of the offending changes.  Perform any temporary
   allocations in POOL. */
Merge changes between two nodes into a third node.  Given nodes
SOURCE_PATH under SOURCE_ROOT, TARGET_PATH under TARGET_ROOT and
ANCESTOR_PATH under ANCESTOR_ROOT, modify target to contain all the
changes between the ancestor and source.  If there are conflicts,
return SVN_ERR_FS_CONFLICT and set *CONFLICT_P to a textual
description of the offending changes.  Perform any temporary
allocations in POOL.
Merge changes between two nodes into a third node . Given nodes SOURCE_PATH under SOURCE_ROOT TARGET_PATH under TARGET_ROOT and ANCESTOR_PATH under ANCESTOR_ROOT modify target to contain all the changes between the ancestor and source . If there are conflicts return SVN_ERR_FS_CONFLICT and set * CONFLICT_P to a textual description of the offending changes . Perform any temporary allocations in POOL .
static svn_error_t *
x_merge(const char **conflict_p,
        svn_fs_root_t *source_root,
        const char *source_path,
        svn_fs_root_t *target_root,
        const char *target_path,
        svn_fs_root_t *ancestor_root,
        const char *ancestor_path,
        apr_pool_t *pool)
{
  dag_node_t *source, *ancestor;
  svn_fs_txn_t *txn;
  svn_error_t *err;
  svn_stringbuf_t *conflict = svn_stringbuf_create_empty(pool);
  if (! target_root->is_txn_root)
    return SVN_FS__NOT_TXN(target_root);
  if ((source_root->fs != ancestor_root->fs)
      || (target_root->fs != ancestor_root->fs))
    {
      return svn_error_create
        (SVN_ERR_FS_CORRUPT, NULL,
         _("Bad merge; ancestor, source, and target not all in same fs"));
    }
  SVN_ERR(get_root(&ancestor, ancestor_root, pool));
  SVN_ERR(get_root(&source, source_root, pool));
  SVN_ERR(svn_fs_x__open_txn(&txn, ancestor_root->fs, target_root->txn,
                             pool));
  err = merge_changes(ancestor, source, txn, conflict, pool);
  if (err)
    {
      if ((err->apr_err == SVN_ERR_FS_CONFLICT) && conflict_p)
        *conflict_p = conflict->data;
      return svn_error_trace(err);
    }
  return SVN_NO_ERROR;
}
static svn_error_t * x_merge ( const char * * conflict_p , svn_fs_root_t * source_root , const char * source_path , svn_fs_root_t * target_root , const char * target_path , svn_fs_root_t * ancestor_root , const char * ancestor_path , apr_pool_t * pool ) { dag_node_t * source , * ancestor ; svn_fs_txn_t * txn ; svn_error_t * err ; svn_stringbuf_t * conflict = svn_stringbuf_create_empty ( pool ) ; if ( ! target_root -> is_txn_root ) return SVN_FS__NOT_TXN ( target_root ) ; if ( ( source_root -> fs != ancestor_root -> fs ) || ( target_root -> fs != ancestor_root -> fs ) ) { return svn_error_create ( SVN_ERR_FS_CORRUPT , NULL , _ ( " " ) ) ; } SVN_ERR ( get_root ( & ancestor , ancestor_root , pool ) ) ; SVN_ERR ( get_root ( & source , source_root , pool ) ) ; SVN_ERR ( svn_fs_x__open_txn ( & txn , ancestor_root -> fs , target_root -> txn , pool ) ) ; err = merge_changes ( ancestor , source , txn , conflict , pool ) ; if ( err ) { if ( ( err -> apr_err == SVN_ERR_FS_CONFLICT ) && conflict_p ) * conflict_p = conflict -> data ; return svn_error_trace ( err ) ; } return SVN_NO_ERROR ; }
Merge changes between two nodes into a third node.
Merge changes between two nodes into a third node .
/* Paranoia. */ /* ### kff todo: is there any compelling reason to get the nodes in
     one db transaction?  Right now we don't; txn_body_get_root() gets
     one node at a time.  This will probably need to change:

     Jim Blandy <jimb@zwingli.cygnus.com> writes:
     > svn_fs_merge needs to be a single transaction, to protect it against
     > people deleting parents of nodes it's working on, etc.
  */ /* Get the ancestor node. */ /* Get the source node. */ /* Open a txn for the txn root into which we're merging. */ /* Merge changes between ANCESTOR and SOURCE into TXN. */