Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 16AB8E277 for ; Thu, 17 Jan 2013 15:03:15 +0000 (UTC) Received: (qmail 30565 invoked by uid 500); 17 Jan 2013 15:03:14 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 30448 invoked by uid 500); 17 Jan 2013 15:03:14 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 30415 invoked by uid 99); 17 Jan 2013 15:03:13 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Jan 2013 15:03:13 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Jan 2013 15:03:10 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id C1D5323889DA; Thu, 17 Jan 2013 15:02:49 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1434705 - /subversion/trunk/subversion/libsvn_client/externals.c Date: Thu, 17 Jan 2013 15:02:49 -0000 To: commits@subversion.apache.org From: rhuijben@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130117150249.C1D5323889DA@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: rhuijben Date: Thu Jan 17 15:02:49 2013 New Revision: 1434705 URL: http://svn.apache.org/viewvc?rev=1434705&view=rev Log: Use the common working copy lock pattern when removing externals. There should be no noticable different behavior. * subversion/libsvn_client/externals.c (remove_external2, remove_external): New functions, implementing the common lock obtain and release. (handle_external_item_removal): Use remove_external as cleaner way to ensure a lock. Drive the removal on the information in the store to avoid deleting unrelated nodes. (svn_client__handle_externals): Remove obsolete comment. Modified: subversion/trunk/subversion/libsvn_client/externals.c Modified: subversion/trunk/subversion/libsvn_client/externals.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/externals.c?rev=1434705&r1=1434704&r2=1434705&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/externals.c (original) +++ subversion/trunk/subversion/libsvn_client/externals.c Thu Jan 17 15:02:49 2013 @@ -516,46 +516,102 @@ switch_file_external(const char *local_a return SVN_NO_ERROR; } +/* Wrappers around svn_wc__external_remove, obtaining and releasing a lock for + directory externals */ +static svn_error_t * +remove_external2(svn_boolean_t *removed, + svn_wc_context_t *wc_ctx, + const char *wri_abspath, + const char *local_abspath, + svn_node_kind_t external_kind, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool) +{ + SVN_ERR(svn_wc__external_remove(wc_ctx, wri_abspath, + local_abspath, + (external_kind == svn_node_none), + cancel_func, cancel_baton, + scratch_pool)); + + *removed = TRUE; + return SVN_NO_ERROR; +} + + +static svn_error_t * +remove_external(svn_boolean_t *removed, + svn_wc_context_t *wc_ctx, + const char *wri_abspath, + const char *local_abspath, + svn_node_kind_t external_kind, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool) +{ + *removed = FALSE; + switch (external_kind) + { + case svn_node_dir: + SVN_WC__CALL_WITH_WRITE_LOCK( + remove_external2(removed, + wc_ctx, wri_abspath, + local_abspath, external_kind, + cancel_func, cancel_baton, + scratch_pool), + wc_ctx, local_abspath, FALSE, scratch_pool); + break; + case svn_node_file: + default: + SVN_ERR(remove_external2(removed, + wc_ctx, wri_abspath, + local_abspath, external_kind, + cancel_func, cancel_baton, + scratch_pool)); + break; + } + + *removed = TRUE; + return SVN_NO_ERROR; +} + +/* Called when an external that is in the EXTERNALS table is no longer + referenced from an svn:externals property */ static svn_error_t * handle_external_item_removal(const svn_client_ctx_t *ctx, const char *defining_abspath, const char *local_abspath, apr_pool_t *scratch_pool) { - /* This branch is only used when an external is deleted from the - repository and the working copy is updated or committed. */ - svn_error_t *err; - svn_boolean_t lock_existed; + svn_node_kind_t external_kind; svn_node_kind_t kind; - const char *lock_root_abspath = NULL; + svn_boolean_t removed = FALSE; /* local_abspath should be a wcroot or a file external */ + SVN_ERR(svn_wc__read_external_info(&external_kind, NULL, NULL, NULL, NULL, + ctx->wc_ctx, defining_abspath, + local_abspath, FALSE, + scratch_pool, scratch_pool)); + SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, local_abspath, FALSE, scratch_pool)); - if (kind != svn_node_none) - { - SVN_ERR(svn_wc_locked2(&lock_existed, NULL, ctx->wc_ctx, - local_abspath, scratch_pool)); + if (external_kind != kind) + external_kind = svn_node_none; /* Only remove the registration */ - if (! lock_existed) - { - SVN_ERR(svn_wc__acquire_write_lock(&lock_root_abspath, - ctx->wc_ctx, local_abspath, - FALSE, - scratch_pool, scratch_pool)); - } - } + err = remove_external(&removed, + ctx->wc_ctx, defining_abspath, local_abspath, + external_kind, + ctx->cancel_func, ctx->cancel_baton, + scratch_pool); - /* We don't use relegate_dir_external() here, because we know that - nothing else in this externals description (at least) is - going to need this directory, and therefore it's better to - leave stuff where the user expects it. */ - err = svn_wc__external_remove(ctx->wc_ctx, defining_abspath, - local_abspath, (kind == svn_node_none), - ctx->cancel_func, ctx->cancel_baton, - scratch_pool); + if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED && removed) + { + svn_error_clear(err); + err = NULL; /* We removed the working copy, so we can't release the + lock that was stored inside */ + } if (ctx->notify_func2) { @@ -587,23 +643,6 @@ handle_external_item_removal(const svn_c err = NULL; } - - /* Unlock if we acquired the lock */ - if (lock_root_abspath != NULL) - { - svn_error_t *err2 = svn_wc__release_write_lock(ctx->wc_ctx, - lock_root_abspath, - scratch_pool); - - if (err2 && err2->apr_err == SVN_ERR_WC_NOT_LOCKED) - { - /* We removed the lock by removing the node, how nice! */ - svn_error_clear(err2); - } - else - err = svn_error_compose_create(err, err2); - } - return svn_error_trace(err); } @@ -891,8 +930,6 @@ svn_client__handle_externals(apr_hash_t iterpool = svn_pool_create(scratch_pool); - /* Parse the old externals. This part will be replaced by reading EXTERNALS - from the DB. */ SVN_ERR(svn_wc__externals_defined_below(&old_external_defs, ctx->wc_ctx, target_abspath, scratch_pool, iterpool));