static svn_error_t * change_rev_prop(const char *url, svn_revnum_t revision, const char *propname, const svn_string_t *propval, const svn_string_t *old_value, const char *http_library, svn_boolean_t want_error, apr_pool_t *pool) { svn_ra_callbacks2_t *callbacks; svn_ra_session_t *sess; apr_hash_t *config; svn_boolean_t capable; svn_error_t *err; SVN_ERR(svn_ra_create_callbacks(&callbacks, pool)); SVN_ERR(construct_auth_baton(&callbacks->auth_baton, pool)); SVN_ERR(construct_config(&config, http_library, pool)); SVN_ERR(svn_ra_open4(&sess, NULL, url, NULL, callbacks, NULL /* baton */, config, pool)); SVN_ERR(svn_ra_has_capability(sess, &capable, SVN_RA_CAPABILITY_ATOMIC_REVPROPS, pool)); if (capable) { err = svn_ra_change_rev_prop2(sess, revision, propname, &old_value, propval, pool); if (want_error && err && svn_error_find_cause(err, SVN_ERR_FS_PROP_BASEVALUE_MISMATCH)) { /* Expectation was matched. Get out. */ svn_error_clear(err); return SVN_NO_ERROR; } else if (! want_error && ! err) /* Expectation was matched. Get out. */ return SVN_NO_ERROR; else if (want_error && ! err) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "An error was expected but not seen"); else /* A real (non-SVN_ERR_FS_PROP_BASEVALUE_MISMATCH) error. */ return svn_error_trace(err); } else /* Running under --server-minor-version? */ return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Server doesn't advertise " "SVN_RA_CAPABILITY_ATOMIC_REVPROPS"); }
CString SVNBase::GetErrorString(svn_error_t * Err, int wrap /* = 80 */) { CString msg; CString temp; if (Err != NULL) { char errbuf[256] = { 0 }; svn_error_t * ErrPtr = Err; if (ErrPtr->message) msg = CUnicodeUtils::GetUnicode(ErrPtr->message); else { /* Is this a Subversion-specific error code? */ if ((ErrPtr->apr_err > APR_OS_START_USEERR) && (ErrPtr->apr_err <= APR_OS_START_CANONERR)) msg = svn_strerror (ErrPtr->apr_err, errbuf, _countof (errbuf)); /* Otherwise, this must be an APR error code. */ else { svn_error_t *temp_err = NULL; const char * err_string = NULL; temp_err = svn_utf_cstring_to_utf8(&err_string, apr_strerror (ErrPtr->apr_err, errbuf, _countof (errbuf)-1), ErrPtr->pool); if (temp_err) { svn_error_clear (temp_err); msg = L"Can't recode error string from APR"; } else { msg = CUnicodeUtils::GetUnicode(err_string); } } } msg = CStringUtils::LinesWrap(msg, wrap); while (ErrPtr->child) { ErrPtr = ErrPtr->child; msg += L"\n"; if (ErrPtr->message) temp = CUnicodeUtils::GetUnicode(ErrPtr->message); else { /* Is this a Subversion-specific error code? */ if ((ErrPtr->apr_err > APR_OS_START_USEERR) && (ErrPtr->apr_err <= APR_OS_START_CANONERR)) temp = svn_strerror (ErrPtr->apr_err, errbuf, _countof (errbuf)); /* Otherwise, this must be an APR error code. */ else { svn_error_t *temp_err = NULL; const char * err_string = NULL; temp_err = svn_utf_cstring_to_utf8(&err_string, apr_strerror (ErrPtr->apr_err, errbuf, _countof (errbuf)-1), ErrPtr->pool); if (temp_err) { svn_error_clear (temp_err); temp = L"Can't recode error string from APR"; } else { temp = CUnicodeUtils::GetUnicode(err_string); } } } temp = CStringUtils::LinesWrap(temp, wrap); msg += temp; } temp.Empty(); if (svn_error_find_cause(Err, SVN_ERR_WC_LOCKED) && (Err->apr_err != SVN_ERR_WC_CLEANUP_REQUIRED)) temp.LoadString(IDS_SVNERR_RUNCLEANUP); #ifdef IDS_SVNERR_CHECKPATHORURL // add some hint text for some of the error messages switch (Err->apr_err) { case SVN_ERR_BAD_FILENAME: case SVN_ERR_BAD_URL: // please check the path or URL you've entered. temp.LoadString(IDS_SVNERR_CHECKPATHORURL); break; case SVN_ERR_WC_CLEANUP_REQUIRED: // do a "cleanup" temp.LoadString(IDS_SVNERR_RUNCLEANUP); break; case SVN_ERR_WC_NOT_UP_TO_DATE: case SVN_ERR_FS_TXN_OUT_OF_DATE: // do an update first temp.LoadString(IDS_SVNERR_UPDATEFIRST); break; case SVN_ERR_WC_CORRUPT: case SVN_ERR_WC_CORRUPT_TEXT_BASE: // do a "cleanup". If that doesn't work you need to do a fresh checkout. temp.LoadString(IDS_SVNERR_CLEANUPORFRESHCHECKOUT); break; case SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED: temp.LoadString(IDS_SVNERR_POSTCOMMITHOOKFAILED); break; case SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED: temp.LoadString(IDS_SVNERR_POSTLOCKHOOKFAILED); break; case SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED: temp.LoadString(IDS_SVNERR_POSTUNLOCKHOOKFAILED); break; case SVN_ERR_REPOS_HOOK_FAILURE: temp.LoadString(IDS_SVNERR_HOOKFAILED); break; case SVN_ERR_SQLITE_BUSY: temp.LoadString(IDS_SVNERR_SQLITEBUSY); break; default: break; } if ((Err->apr_err == SVN_ERR_FS_PATH_NOT_LOCKED)|| (Err->apr_err == SVN_ERR_FS_NO_SUCH_LOCK)|| (Err->apr_err == SVN_ERR_RA_NOT_LOCKED)) { // the lock has already been broken from another working copy temp.LoadString(IDS_SVNERR_UNLOCKFAILEDNOLOCK); } else if (SVN_ERR_IS_UNLOCK_ERROR(Err)) { // if you want to break the lock, use the "check for modifications" dialog temp.LoadString(IDS_SVNERR_UNLOCKFAILED); } if (!temp.IsEmpty()) { msg += L"\n" + temp; } #endif return msg; } return L""; }
/* The guts of svn_wc_copy3() and svn_wc_move(). * The additional parameter IS_MOVE indicates whether this is a copy or * a move operation. * * If MOVE_DEGRADED_TO_COPY is not NULL and a move had to be degraded * to a copy, then set *MOVE_DEGRADED_TO_COPY. */ static svn_error_t * copy_or_move(svn_boolean_t *move_degraded_to_copy, svn_wc_context_t *wc_ctx, const char *src_abspath, const char *dst_abspath, svn_boolean_t metadata_only, svn_boolean_t is_move, svn_boolean_t allow_mixed_revisions, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, void *notify_baton, apr_pool_t *scratch_pool) { svn_wc__db_t *db = wc_ctx->db; svn_node_kind_t src_db_kind; const char *dstdir_abspath; svn_boolean_t conflicted; const char *tmpdir_abspath; const char *src_wcroot_abspath; const char *dst_wcroot_abspath; svn_boolean_t within_one_wc; svn_wc__db_status_t src_status; svn_error_t *err; SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath)); SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath)); dstdir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool); /* Ensure DSTDIR_ABSPATH belongs to the same repository as SRC_ABSPATH; throw an error if not. */ { svn_wc__db_status_t dstdir_status; const char *src_repos_root_url, *dst_repos_root_url; const char *src_repos_uuid, *dst_repos_uuid; const char *src_repos_relpath; err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL, &src_repos_relpath, &src_repos_root_url, &src_repos_uuid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &conflicted, NULL, NULL, NULL, NULL, NULL, NULL, db, src_abspath, scratch_pool, scratch_pool); if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) { /* Replicate old error code and text */ svn_error_clear(err); return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL, _("'%s' is not under version control"), svn_dirent_local_style(src_abspath, scratch_pool)); } else SVN_ERR(err); /* Do this now, as we know the right data is cached */ SVN_ERR(svn_wc__db_get_wcroot(&src_wcroot_abspath, db, src_abspath, scratch_pool, scratch_pool)); switch (src_status) { case svn_wc__db_status_deleted: return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, _("Deleted node '%s' can't be copied."), svn_dirent_local_style(src_abspath, scratch_pool)); case svn_wc__db_status_excluded: case svn_wc__db_status_server_excluded: case svn_wc__db_status_not_present: return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL, _("The node '%s' was not found."), svn_dirent_local_style(src_abspath, scratch_pool)); default: break; } if (is_move && ! strcmp(src_abspath, src_wcroot_abspath)) { return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, _("'%s' is the root of a working copy and " "cannot be moved"), svn_dirent_local_style(src_abspath, scratch_pool)); } if (is_move && src_repos_relpath && !src_repos_relpath[0]) { return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, _("'%s' represents the repository root " "and cannot be moved"), svn_dirent_local_style(src_abspath, scratch_pool)); } err = svn_wc__db_read_info(&dstdir_status, NULL, NULL, NULL, &dst_repos_root_url, &dst_repos_uuid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, db, dstdir_abspath, scratch_pool, scratch_pool); if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) { /* An unversioned destination directory exists on disk. */ svn_error_clear(err); return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL, _("'%s' is not under version control"), svn_dirent_local_style(dstdir_abspath, scratch_pool)); } else SVN_ERR(err); /* Do this now, as we know the right data is cached */ SVN_ERR(svn_wc__db_get_wcroot(&dst_wcroot_abspath, db, dstdir_abspath, scratch_pool, scratch_pool)); if (!src_repos_root_url) { if (src_status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, &src_repos_root_url, &src_repos_uuid, NULL, NULL, NULL, NULL, db, src_abspath, scratch_pool, scratch_pool)); else /* If not added, the node must have a base or we can't copy */ SVN_ERR(svn_wc__db_scan_base_repos(NULL, &src_repos_root_url, &src_repos_uuid, db, src_abspath, scratch_pool, scratch_pool)); } if (!dst_repos_root_url) { if (dstdir_status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, &dst_repos_root_url, &dst_repos_uuid, NULL, NULL, NULL, NULL, db, dstdir_abspath, scratch_pool, scratch_pool)); else /* If not added, the node must have a base or we can't copy */ SVN_ERR(svn_wc__db_scan_base_repos(NULL, &dst_repos_root_url, &dst_repos_uuid, db, dstdir_abspath, scratch_pool, scratch_pool)); } if (strcmp(src_repos_root_url, dst_repos_root_url) != 0 || strcmp(src_repos_uuid, dst_repos_uuid) != 0) return svn_error_createf( SVN_ERR_WC_INVALID_SCHEDULE, NULL, _("Cannot copy to '%s', as it is not from repository '%s'; " "it is from '%s'"), svn_dirent_local_style(dst_abspath, scratch_pool), src_repos_root_url, dst_repos_root_url); if (dstdir_status == svn_wc__db_status_deleted) return svn_error_createf( SVN_ERR_WC_INVALID_SCHEDULE, NULL, _("Cannot copy to '%s' as it is scheduled for deletion"), svn_dirent_local_style(dst_abspath, scratch_pool)); /* ### should report dstdir_abspath instead of dst_abspath? */ } /* TODO(#2843): Rework the error report. */ /* Check if the copy target is missing or hidden and thus not exist on the disk, before actually doing the file copy. */ { svn_wc__db_status_t dst_status; err = svn_wc__db_read_info(&dst_status, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, db, dst_abspath, scratch_pool, scratch_pool); if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) return svn_error_trace(err); svn_error_clear(err); if (!err) switch (dst_status) { case svn_wc__db_status_excluded: return svn_error_createf( SVN_ERR_ENTRY_EXISTS, NULL, _("'%s' is already under version control " "but is excluded."), svn_dirent_local_style(dst_abspath, scratch_pool)); case svn_wc__db_status_server_excluded: return svn_error_createf( SVN_ERR_ENTRY_EXISTS, NULL, _("'%s' is already under version control"), svn_dirent_local_style(dst_abspath, scratch_pool)); case svn_wc__db_status_deleted: case svn_wc__db_status_not_present: break; /* OK to add */ default: return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL, _("There is already a versioned item '%s'"), svn_dirent_local_style(dst_abspath, scratch_pool)); } } /* Check that the target path is not obstructed, if required. */ if (!metadata_only) { svn_node_kind_t dst_kind; /* (We need only to check the root of the copy, not every path inside copy_versioned_file/_dir.) */ SVN_ERR(svn_io_check_path(dst_abspath, &dst_kind, scratch_pool)); if (dst_kind != svn_node_none) return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL, _("'%s' already exists and is in the way"), svn_dirent_local_style(dst_abspath, scratch_pool)); } SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dstdir_abspath, scratch_pool, scratch_pool)); within_one_wc = (strcmp(src_wcroot_abspath, dst_wcroot_abspath) == 0); if (is_move && !within_one_wc) { if (move_degraded_to_copy) *move_degraded_to_copy = TRUE; is_move = FALSE; } if (!within_one_wc) SVN_ERR(svn_wc__db_pristine_transfer(db, src_abspath, dst_wcroot_abspath, cancel_func, cancel_baton, scratch_pool)); if (src_db_kind == svn_node_file || src_db_kind == svn_node_symlink) { err = copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath, tmpdir_abspath, metadata_only, conflicted, is_move, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool); } else { if (is_move && src_status == svn_wc__db_status_normal) { svn_revnum_t min_rev; svn_revnum_t max_rev; /* Verify that the move source is a single-revision subtree. */ SVN_ERR(svn_wc__db_min_max_revisions(&min_rev, &max_rev, db, src_abspath, FALSE, scratch_pool)); if (SVN_IS_VALID_REVNUM(min_rev) && SVN_IS_VALID_REVNUM(max_rev) && min_rev != max_rev) { if (!allow_mixed_revisions) return svn_error_createf(SVN_ERR_WC_MIXED_REVISIONS, NULL, _("Cannot move mixed-revision " "subtree '%s' [%ld:%ld]; " "try updating it first"), svn_dirent_local_style(src_abspath, scratch_pool), min_rev, max_rev); is_move = FALSE; if (move_degraded_to_copy) *move_degraded_to_copy = TRUE; } } err = copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath, tmpdir_abspath, metadata_only, is_move, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool); } if (err && svn_error_find_cause(err, SVN_ERR_CANCELLED)) return svn_error_trace(err); if (is_move) err = svn_error_compose_create(err, svn_wc__db_op_handle_move_back(NULL, db, dst_abspath, src_abspath, NULL /* work_items */, scratch_pool)); /* Run the work queue with the remaining work */ SVN_ERR(svn_error_compose_create( err, svn_wc__wq_run(db, dst_abspath, cancel_func, cancel_baton, scratch_pool))); return SVN_NO_ERROR; }
const char * svn_repos__post_commit_error_str(svn_error_t *err, apr_pool_t *pool) { svn_error_t *hook_err1, *hook_err2; const char *msg; if (! err) return _("(no error)"); err = svn_error_purge_tracing(err); /* hook_err1 is the SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED wrapped error from the post-commit script, if any, and hook_err2 should be the original error, but be defensive and handle a case where SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED doesn't wrap an error. */ hook_err1 = svn_error_find_cause(err, SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED); if (hook_err1 && hook_err1->child) hook_err2 = hook_err1->child; else hook_err2 = hook_err1; /* This implementation counts on svn_repos_fs_commit_txn() returning svn_fs_commit_txn() as the parent error with a child SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED error. If the parent error is SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED then there was no error in svn_fs_commit_txn(). The post-commit hook error message is already self describing, so it can be dropped into an error message without any additional text. */ if (hook_err1) { if (err == hook_err1) { if (hook_err2->message) msg = apr_pstrdup(pool, hook_err2->message); else msg = _("post-commit hook failed with no error message."); } else { msg = hook_err2->message ? apr_pstrdup(pool, hook_err2->message) : _("post-commit hook failed with no error message."); msg = apr_psprintf( pool, _("post commit FS processing had error:\n%s\n%s"), err->message ? err->message : _("(no error message)"), msg); } } else { msg = apr_psprintf(pool, _("post commit FS processing had error:\n%s"), err->message ? err->message : _("(no error message)")); } return msg; }
svn_error_t * svn_ra_serf__get_locks(svn_ra_session_t *ra_session, apr_hash_t **locks, const char *path, svn_depth_t depth, apr_pool_t *pool) { lock_context_t *lock_ctx; svn_ra_serf__session_t *session = ra_session->priv; svn_ra_serf__handler_t *handler; svn_ra_serf__xml_context_t *xmlctx; const char *req_url, *rel_path; svn_error_t *err; req_url = svn_path_url_add_component2(session->session_url.path, path, pool); SVN_ERR(svn_ra_serf__get_relative_path(&rel_path, req_url, session, pool)); lock_ctx = apr_pcalloc(pool, sizeof(*lock_ctx)); lock_ctx->pool = pool; lock_ctx->path = apr_pstrcat(pool, "/", rel_path, SVN_VA_NULL); lock_ctx->requested_depth = depth; lock_ctx->hash = apr_hash_make(pool); xmlctx = svn_ra_serf__xml_context_create(getlocks_ttable, NULL, getlocks_closed, NULL, lock_ctx, pool); handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool); handler->method = "REPORT"; handler->path = req_url; handler->body_type = "text/xml"; handler->body_delegate = create_getlocks_body; handler->body_delegate_baton = lock_ctx; err = svn_ra_serf__context_run_one(handler, pool); if (err) { if (svn_error_find_cause(err, SVN_ERR_UNSUPPORTED_FEATURE)) { /* The server told us that it doesn't support this report type. We return the documented error for svn_ra_get_locks(), but with the original error report */ return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL); } else if (err->apr_err == SVN_ERR_FS_NOT_FOUND) { /* File doesn't exist in HEAD: Not an error */ svn_error_clear(err); } else return svn_error_trace(err); } /* We get a 404 when a path doesn't exist in HEAD, but it might have existed earlier (E.g. 'svn ls http://s/svn/trunk/file@1' */ if (handler->sline.code != 200 && handler->sline.code != 404) { return svn_error_trace(svn_ra_serf__unexpected_status(handler)); } *locks = lock_ctx->hash; return SVN_NO_ERROR; }