Author: stsp
Date: Tue May 18 15:42:57 2010
New Revision: 945708
URL: http://svn.apache.org/viewvc?rev=945708&view=rev
Log:
On the 1.6.x-issue3469 branch, fix issue #3469 "tree conflict inside of
directory external causes assertion to fail".
In addition to fixing the assertion failure, make 'svn revert' and
'svn resolved' actually work for tree conflicted externals.
* subversion/libsvn_wc/adm_ops.c
(revert_internal): Do not error out if directories cannot be locked as
part of the current access baton set. Just ignore such directories.
The attempt to revert tree-conflicted externals led to an "Unable to
lock <external>" error which we never saw before because the assertion
failure described in issue #3469 prevented us from entering this situation.
* subversion/libsvn_wc/entries.c
(svn_wc__walk_entries_and_tc): Don't give up right away if a directory
cannot be locked. Try retrieving a lock for the parent directory instead,
and only give up if that fails, too. Prevents 'svn resolved -R' from
silently skipping tree-conflicted externals.
* subversion/libsvn_wc/tree_conflicts.c
(svn_wc__del_tree_conflict): If the tree conflict victim's parent is not
already locked as part of the current access baton set, try to
independently lock the parent (just like svn_wc__get_tree_conflict()
already does). This makes it possible to revert or resolve tree-conflicted
externals, since the operation needs to be carried out in the external's
parent working copy where the tree conflict is actually recorded, rather
than within the external itself. This part is what fixes the assertion
failure described in issue #3469.
Modified:
subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/adm_ops.c
subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/entries.c
subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/tree_conflicts.c
Modified: subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/adm_ops.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/adm_ops.c?rev=945708&r1=945707&r2=945708&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/adm_ops.c
(original)
+++ subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/adm_ops.c Tue May
18 15:42:57 2010
@@ -2198,13 +2198,23 @@ revert_internal(const char *path,
const svn_wc_entry_t *entry;
svn_wc_adm_access_t *dir_access;
svn_wc_conflict_description_t *tree_conflict;
+ svn_error_t *err;
/* Check cancellation here, so recursive calls get checked early. */
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
/* Fetch the access baton for this path. */
- SVN_ERR(svn_wc_adm_probe_retrieve(&dir_access, parent_access, path, pool));
+ err = svn_wc_adm_probe_retrieve(&dir_access, parent_access, path, pool);
+ if (err && (err->apr_err == SVN_ERR_WC_NOT_LOCKED))
+ {
+ /* The path is unversioned, or it could be an external.
+ * Do not recurse into it. */
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+ }
+ else if (err)
+ return err;
/* Safeguard 1: the item must be versioned for any reversion to make sense,
except that a tree conflict can exist on an unversioned item. */
Modified: subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/entries.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/entries.c?rev=945708&r1=945707&r2=945708&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/entries.c
(original)
+++ subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/entries.c Tue May
18 15:42:57 2010
@@ -3314,10 +3314,21 @@ svn_wc__walk_entries_and_tc(const char *
err = svn_wc_adm_probe_retrieve(&path_adm_access, adm_access, path, pool);
if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)
{
- /* Item is unversioned and doesn't have a versioned parent so there is
- * nothing to walk. */
svn_error_clear(err);
- return SVN_NO_ERROR;
+
+ /* Hmmm... maybe the subdirectory is an external?
+ * Try to access the parent dir explicitly. */
+ err = svn_wc_adm_probe_retrieve(&path_adm_access, adm_access,
+ svn_path_dirname(path, pool), pool);
+ if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)
+ {
+ /* Item is unversioned and doesn't have a versioned parent
+ * so there is nothing to walk. */
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+ }
+ else if (err)
+ return err;
}
else if (err)
return err;
Modified:
subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/tree_conflicts.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/tree_conflicts.c?rev=945708&r1=945707&r2=945708&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/tree_conflicts.c
(original)
+++ subversion/branches/1.6.x-issue3469/subversion/libsvn_wc/tree_conflicts.c
Tue May 18 15:42:57 2010
@@ -487,16 +487,41 @@ svn_wc__del_tree_conflict(const char *vi
apr_pool_t *pool)
{
svn_stringbuf_t *log_accum = NULL;
+ const char *parent_path;
+ svn_wc_adm_access_t *parent_adm_access;
+ svn_boolean_t parent_adm_access_is_temporary = FALSE;
+ svn_error_t *err;
- SVN_ERR(svn_wc__loggy_del_tree_conflict(&log_accum, victim_path, adm_access,
- pool));
+ parent_path = svn_path_dirname(victim_path, pool);
+ /* Try to get the parent's admin access baton from the baton set. */
+ err = svn_wc_adm_retrieve(&parent_adm_access, adm_access, parent_path,
+ pool);
+ if (err && (err->apr_err == SVN_ERR_WC_NOT_LOCKED))
+ {
+ svn_error_clear(err);
+ /* Try to access the parent dir independently.
+ * Maybe the victim is the root of a directory external,
+ * and the parent working copy isn't locked. */
+ SVN_ERR(svn_wc_adm_open3(&parent_adm_access, NULL, parent_path,
+ TRUE, 0, NULL, NULL, pool));
+ parent_adm_access_is_temporary = TRUE;
+ }
+ else if (err)
+ return err;
+
+ SVN_ERR(svn_wc__loggy_del_tree_conflict(&log_accum, victim_path,
+ parent_adm_access, pool));
if (log_accum != NULL)
{
- SVN_ERR(svn_wc__write_log(adm_access, 0, log_accum, pool));
- SVN_ERR(svn_wc__run_log(adm_access, NULL, pool));
+ SVN_ERR(svn_wc__write_log(parent_adm_access, 0, log_accum, pool));
+ SVN_ERR(svn_wc__run_log(parent_adm_access, NULL, pool));
}
+ /* If we opened a temporary admin access baton, close it. */
+ if (parent_adm_access_is_temporary)
+ SVN_ERR(svn_wc_adm_close2(parent_adm_access, pool));
+
return SVN_NO_ERROR;
}