static svn_error_t * can_be_cleaned(int *wc_format, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *scratch_pool) { SVN_ERR(svn_wc__internal_check_wc(wc_format, db, local_abspath, FALSE, scratch_pool)); /* a "version" of 0 means a non-wc directory */ if (*wc_format == 0) return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL, _("'%s' is not a working copy directory"), svn_dirent_local_style(local_abspath, scratch_pool)); if (*wc_format < SVN_WC__WC_NG_VERSION) return svn_error_create(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, _("Log format too old, please use " "Subversion 1.6 or earlier")); return SVN_NO_ERROR; }
svn_error_t * svn_wc__internal_ensure_adm(svn_wc__db_t *db, const char *local_abspath, const char *url, const char *repos_root_url, const char *repos_uuid, svn_revnum_t revision, svn_depth_t depth, apr_pool_t *scratch_pool) { int format; const char *repos_relpath; svn_wc__db_status_t status; const char *db_repos_relpath, *db_repos_root_url, *db_repos_uuid; svn_revnum_t db_revision; SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); SVN_ERR_ASSERT(url != NULL); SVN_ERR_ASSERT(repos_root_url != NULL); SVN_ERR_ASSERT(repos_uuid != NULL); SVN_ERR_ASSERT(svn_uri__is_ancestor(repos_root_url, url)); SVN_ERR(svn_wc__internal_check_wc(&format, db, local_abspath, TRUE, scratch_pool)); repos_relpath = svn_uri__is_child(repos_root_url, url, scratch_pool); if (repos_relpath == NULL) repos_relpath = ""; /* Early out: we know we're not dealing with an existing wc, so just create one. */ if (format == 0) return svn_error_trace(init_adm(db, local_abspath, repos_relpath, repos_root_url, repos_uuid, revision, depth, scratch_pool)); SVN_ERR(svn_wc__db_read_info(&status, NULL, &db_revision, &db_repos_relpath, &db_repos_root_url, &db_repos_uuid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); /* When the directory exists and is scheduled for deletion or is not-present * do not check the revision or the URL. The revision can be any * arbitrary revision and the URL may differ if the add is * being driven from a merge which will have a different URL. */ if (status != svn_wc__db_status_deleted && status != svn_wc__db_status_not_present) { /* ### Should we match copyfrom_revision? */ if (db_revision != revision) return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL, _("Revision %ld doesn't match existing " "revision %ld in '%s'"), revision, db_revision, local_abspath); if (!db_repos_root_url) { if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &db_repos_relpath, &db_repos_root_url, &db_repos_uuid, NULL, NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); else SVN_ERR(svn_wc__db_scan_base_repos(&db_repos_relpath, &db_repos_root_url, &db_repos_uuid, db, local_abspath, scratch_pool, scratch_pool)); } /* The caller gives us a URL which should match the entry. However, some callers compensate for an old problem in entry->url and pass the copyfrom_url instead. See ^/notes/api-errata/wc002.txt. As a result, we allow the passed URL to match copyfrom_url if it does not match the entry's primary URL. */ /* ### comparing URLs, should they be canonicalized first? */ if (strcmp(db_repos_uuid, repos_uuid) || strcmp(db_repos_root_url, repos_root_url) || !svn_relpath__is_ancestor(db_repos_relpath, repos_relpath)) { const char *copyfrom_root_url, *copyfrom_repos_relpath; SVN_ERR(svn_wc__internal_get_copyfrom_info(©from_root_url, ©from_repos_relpath, NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); if (copyfrom_root_url == NULL || strcmp(copyfrom_root_url, repos_root_url) || strcmp(copyfrom_repos_relpath, repos_relpath)) return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL, _("URL '%s' (uuid: '%s') doesn't match existing " "URL '%s' (uuid: '%s') in '%s'"), url, db_repos_uuid, svn_path_url_add_component2(db_repos_root_url, db_repos_relpath, scratch_pool), repos_uuid, local_abspath); } } return SVN_NO_ERROR; }