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)); }
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); }