Author: rhuijben
Date: Wed Aug 4 20:08:39 2010
New Revision: 982386
URL: http://svn.apache.org/viewvc?rev=982386&view=rev
Log:
Remove the assumption that deleted directories must still exist from the
merge code in libsvn_client. This fixes several tests for Single-DB.
After we switch to single-db we should remove the assumption that directories
can still exist when deleted.
* subversion/libsvn_client/merge.c
(obstructed_or_missing): Make this function return errors for easier
(future) debugging. When a node is a deleted directory and it's missing
check if it is obstructed and if not assume that no directory is ok.
(merge_props_changed,
merge_file_changed,
merge_file_added,
merge_file_deleted,
merge_dir_added,
merge_dir_deleted,
merge_dir_opened): Update callers.
Modified:
subversion/trunk/subversion/libsvn_client/merge.c
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=982386&r1=982385&r2=982386&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Wed Aug 4 20:08:39 2010
@@ -378,8 +378,9 @@ is_path_conflicted_by_merge(merge_cmd_ba
* different kind is expected, or if the disk node cannot be read.
* - Return 'missing' if there is no node on disk but one is expected.
* Also return 'missing' for absent nodes (not here due to authz).*/
-static svn_wc_notify_state_t
-obstructed_or_missing(const char *local_abspath,
+static svn_error_t *
+obstructed_or_missing(svn_wc_notify_state_t *obstr_state,
+ const char *local_abspath,
const char *local_dir_abspath,
const merge_cmd_baton_t *merge_b,
apr_pool_t *pool)
@@ -391,20 +392,14 @@ obstructed_or_missing(const char *local_
/* In a dry run, make as if nodes "deleted" by the dry run appear so. */
if (merge_b->dry_run && dry_run_deleted_p(merge_b, local_abspath))
- return svn_wc_notify_state_inapplicable;
-
- /* Since this function returns no svn_error_t, we make all errors look like
- * no node found in the wc. */
-
- err = svn_wc_read_kind(&kind_expected, merge_b->ctx->wc_ctx,
- local_abspath, FALSE, pool);
-
- if (err)
{
- svn_error_clear(err);
- kind_expected = svn_node_none;
+ *obstr_state = svn_wc_notify_state_inapplicable;
+ return SVN_NO_ERROR;
}
+ SVN_ERR(svn_wc_read_kind(&kind_expected, merge_b->ctx->wc_ctx,
+ local_abspath, FALSE, pool));
+
/* Report absent nodes as 'missing'. First of all, they count as 'hidden',
* and since we pass show_hidden == FALSE above, they will show up as
* 'none' here. */
@@ -413,44 +408,66 @@ obstructed_or_missing(const char *local_
svn_boolean_t is_absent;
err = svn_wc__node_is_status_absent(&is_absent, merge_b->ctx->wc_ctx,
local_abspath, pool);
- if (err)
- svn_error_clear(err);
- else if (is_absent)
- return svn_wc_notify_state_missing;
+ if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_return(err);
+ else if (!err && is_absent)
+ {
+ *obstr_state = svn_wc_notify_state_missing;
+ return SVN_NO_ERROR;
+ }
+
+ svn_error_clear(err);
}
- /* If a node is deleted, we will still get its kind from the working copy.
+ SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, pool));
+
+ /* If a node is deleted, the node might be gone in the working copy (and
+ * it probably is gone after we switch to single-db
+ *
* But to compare with disk state, we want to consider deleted nodes as
- * svn_node_none instead of their original kind.
- * ### Not necessary with central DB:
- * Because deleted directories are expected to remain on disk until commit
- * to keep the metadata available, we only do this for files, not dirs. */
- if (kind_expected == svn_node_file)
+ * svn_node_none instead of their original kind. */
+
+ if (kind_expected == svn_node_file
+ || kind_expected == svn_node_dir)
{
svn_boolean_t is_deleted;
- err = svn_wc__node_is_status_deleted(&is_deleted,
- merge_b->ctx->wc_ctx,
- local_abspath,
- pool);
- if (err)
- svn_error_clear(err);
- else if (is_deleted)
- kind_expected = svn_node_none;
- }
- err = svn_io_check_path(local_abspath, &kind_on_disk, pool);
- if (err)
- {
- svn_error_clear(err);
- kind_on_disk = svn_node_unknown;
+ SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted,
+ merge_b->ctx->wc_ctx,
+ local_abspath,
+ pool));
+ if (is_deleted)
+ {
+ /* ### While we are not at single-db: detect missing .svn dirs.
+ ### Once we switch to single db expected kind should be always
+ ### none, just like for files */
+ if (kind_expected == svn_node_dir)
+ {
+ if (kind_on_disk == svn_node_none)
+ {
+ svn_boolean_t is_obstructed;
+
+ SVN_ERR(svn_wc__node_is_status_obstructed(&is_obstructed,
+
merge_b->ctx->wc_ctx,
+ local_abspath,
+ pool));
+ if (!is_obstructed)
+ kind_expected = svn_node_none;
+ }
+ }
+ else
+ kind_expected = svn_node_none;
+ }
}
if (kind_expected == kind_on_disk)
- return svn_wc_notify_state_inapplicable;
+ *obstr_state = svn_wc_notify_state_inapplicable;
else if (kind_on_disk == svn_node_none)
- return svn_wc_notify_state_missing;
+ *obstr_state = svn_wc_notify_state_missing;
else
- return svn_wc_notify_state_obstructed;
+ *obstr_state = svn_wc_notify_state_obstructed;
+
+ return SVN_NO_ERROR;
}
/* Create *LEFT and *RIGHT conflict versions for conflict victim
@@ -1083,8 +1100,9 @@ merge_props_changed(const char *local_di
{
svn_wc_notify_state_t obstr_state;
- obstr_state = obstructed_or_missing(local_abspath, local_dir_abspath,
- merge_b, subpool);
+ SVN_ERR(obstructed_or_missing(&obstr_state,
+ local_abspath, local_dir_abspath,
+ merge_b, subpool));
if (obstr_state != svn_wc_notify_state_inapplicable)
{
if (state)
@@ -1319,8 +1337,9 @@ merge_file_changed(const char *local_dir
{
svn_wc_notify_state_t obstr_state;
- obstr_state = obstructed_or_missing(mine_abspath, local_dir_abspath,
- merge_b, subpool);
+ SVN_ERR(obstructed_or_missing(&obstr_state,
+ mine_abspath, local_dir_abspath,
+ merge_b, subpool));
if (obstr_state != svn_wc_notify_state_inapplicable)
{
if (content_state)
@@ -1637,8 +1656,9 @@ merge_file_added(const char *local_dir_a
{
svn_wc_notify_state_t obstr_state;
- obstr_state = obstructed_or_missing(mine_abspath, local_dir_abspath,
- merge_b, subpool);
+ SVN_ERR(obstructed_or_missing(&obstr_state,
+ mine_abspath, local_dir_abspath,
+ merge_b, subpool));
if (obstr_state != svn_wc_notify_state_inapplicable)
{
if (content_state)
@@ -1923,8 +1943,9 @@ merge_file_deleted(const char *local_dir
{
svn_wc_notify_state_t obstr_state;
- obstr_state = obstructed_or_missing(mine_abspath, local_dir_abspath,
- merge_b, subpool);
+ SVN_ERR(obstructed_or_missing(&obstr_state,
+ mine_abspath, local_dir_abspath,
+ merge_b, subpool));
if (obstr_state != svn_wc_notify_state_inapplicable)
{
if (state)
@@ -2111,8 +2132,9 @@ merge_dir_added(const char *local_dir_ab
{
svn_wc_notify_state_t obstr_state;
- obstr_state = obstructed_or_missing(local_abspath, local_dir_abspath,
- merge_b, subpool);
+ SVN_ERR(obstructed_or_missing(&obstr_state,
+ local_abspath, local_dir_abspath,
+ merge_b, subpool));
/* In this case of adding a directory, we have an exception to the usual
* "skip if it's inconsistent" rule. If the directory exists on disk
@@ -2140,7 +2162,7 @@ merge_dir_added(const char *local_dir_ab
merge_b->added_path = apr_pstrdup(merge_b->pool, local_abspath);
else
{
- SVN_ERR(svn_io_make_dir_recursively(local_abspath, subpool));
+ SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, subpool));
SVN_ERR(svn_wc_add4(merge_b->ctx->wc_ctx, local_abspath,
svn_depth_infinity,
copyfrom_url, copyfrom_rev,
@@ -2300,8 +2322,9 @@ merge_dir_deleted(const char *local_dir_
{
svn_wc_notify_state_t obstr_state;
- obstr_state = obstructed_or_missing(local_abspath, local_dir_abspath,
- merge_b, subpool);
+ SVN_ERR(obstructed_or_missing(&obstr_state,
+ local_abspath, local_dir_abspath,
+ merge_b, subpool));
if (obstr_state != svn_wc_notify_state_inapplicable)
{
if (state)
@@ -2432,8 +2455,9 @@ merge_dir_opened(const char *local_dir_a
}
/* Check for an obstructed or missing node on disk. */
- obstr_state = obstructed_or_missing(path, local_dir_abspath, merge_b,
- subpool);
+ SVN_ERR(obstructed_or_missing(&obstr_state,
+ path, local_dir_abspath,
+ merge_b, subpool));
if (obstr_state != svn_wc_notify_state_inapplicable)
{
if (skip_children)