static svn_error_t *
ev2_close_edit(void *edit_baton,
               apr_pool_t *scratch_pool)
{
  struct ev2_edit_baton *eb = edit_baton;
  apr_array_header_t *sorted_hash;
  apr_pool_t *iterpool;
  int i;

  /* Sort the paths touched by this edit.
   * Ev2 doesn't really have any particular need for depth-first-ness, but
   * we want to ensure all parent directories are handled before children in
   * the case of adds (which does introduce an element of depth-first-ness). */
  sorted_hash = svn_sort__hash(eb->paths, svn_sort_compare_items_as_paths,
                               scratch_pool);

  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < sorted_hash->nelts; i++)
    {
      svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i, svn_sort__item_t);
      apr_array_header_t *actions = item->value;
      const char *path = item->key;

      svn_pool_clear(iterpool);
      SVN_ERR(process_actions(edit_baton, path, actions, iterpool));
    }
  svn_pool_destroy(iterpool);

  return svn_error_trace(svn_editor_complete(eb->editor));
}
示例#2
0
文件: editor.c 项目: Ranga123/test1
svn_error_t *
svn_fs__editor_commit(svn_revnum_t *revision,
                      svn_error_t **post_commit_err,
                      const char **conflict_path,
                      svn_editor_t *editor,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = svn_editor_get_baton(editor);
    const char *inner_conflict_path;
    svn_error_t *err = NULL;

    /* make sure people are using the correct sequencing.  */
    if (eb->completed)
        return svn_error_create(SVN_ERR_FS_INCORRECT_EDITOR_COMPLETION,
                                NULL, NULL);

    *revision = SVN_INVALID_REVNUM;
    *post_commit_err = NULL;
    *conflict_path = NULL;

    /* Clean up internal resources (eg. eb->root). This also allows the
       editor infrastructure to know this editor is "complete".  */
    err = svn_editor_complete(editor);

    /* Note: docco for svn_fs_commit_txn() states that CONFLICT_PATH will
       be allocated in the txn's pool. But it lies. Regardless, we want
       it placed into RESULT_POOL.  */

    if (!err)
        err = svn_fs_commit_txn(&inner_conflict_path,
                                revision,
                                eb->txn,
                                scratch_pool);
    if (SVN_IS_VALID_REVNUM(*revision))
    {
        if (err)
        {
            /* Case 3. ERR is a post-commit (cleanup) error.  */

            /* Pass responsibility via POST_COMMIT_ERR.  */
            *post_commit_err = err;
            err = SVN_NO_ERROR;
        }
        /* else: Case 1.  */
    }
    else
    {
        SVN_ERR_ASSERT(err != NULL);
        if (err->apr_err == SVN_ERR_FS_CONFLICT)
        {
            /* Case 2.  */

            /* Copy this into the correct pool (see note above).  */
            *conflict_path = apr_pstrdup(result_pool, inner_conflict_path);

            /* Return sucess. The caller should inspect CONFLICT_PATH to
               determine this particular case.  */
            svn_error_clear(err);
            err = SVN_NO_ERROR;
        }
        /* else: Case 4.  */

        /* Abort the TXN. Nobody wants to use it.  */
        /* ### should we examine the error and attempt svn_fs_purge_txn() ?  */
        err = svn_error_compose_create(
                  err,
                  svn_fs_abort_txn(eb->txn, scratch_pool));
    }

    /* For safety, clear the now-useless txn.  */
    eb->txn = NULL;

    return svn_error_trace(err);
}