Julian Foad <julian.f...@wandisco.com> wrote on 07/14/2011 06:58:24 AM: > The attached patch makes some improvements to how we report that the WC > is locked or busy (the 'run cleanup' messages). I need a sanity check > to make sure I've understood the relationship between how we want to > handle 'the work queue is busy' and 'there is a write lock on a WC > directory'.
I'm all for removing the overloaded "lock" terminology. We see a lot of confused users who think they somehow incorrectly locked a file in the repository when they see the old messages... Kevin R. > When the WC is locked we may (depending on the timing) see: > > $ svn up -q & svn up -q > svn: E155004: Working copy '/home/...' locked. > svn: E155004: '/home/...' is already locked. > svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for > details) > > (or, depending on the timing, there may be two 'database is locked' > lines instead of the 'is already locked' line), or > > $ svn up & svn commit > svn: E155004: Commit failed (details follow): > svn: E155004: Working copy '/home/...' locked. > svn: E155004: '/home/...' is already locked. > svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for > details) > > When the work queue is not empty, we see: > > $ svn status > svn: E155037: Previous operation has not finished; run 'cleanup' if it > was interrupted > > > My recommendations, mainly for the WQ-not-empty case: > > 1. The 'E155037' message shown above comes from libsvn_wc. But the > part about running 'cleanup' should be added by 'svn', since in other > clients it may have a different name or may not be applicable at all, > especially if the client can find out that in fact the other operation > is still running. So libsvn_wc would say just: > > "A previous operation on the working copy has not finished" > > and 'svn' would wrap that in: > > "Run 'svn cleanup' if the previous operation was interrupted" > > See also point (2). > > 2. Consider wrapping this SVN_ERR_WC_CLEANUP_REQUIRED (E155037) error > in a SVN_ERR_WC_LOCKED (E155004) error to preserve API compatibility > w.r.t. this kind of situation. Inside libsvn_wc, of course the > condition being reported here is not the same as a 'lock', but to an > outside caller the net effect is basically that it's a lock. > > If we don't wrap this in SVN_ERR_WC_LOCKED, then in order to support > (1), 'svn' should learn to recognize the new error code as well, at the > point where it determines whether to suggest the user should run > 'cleanup'. > > 3. The error code SVN_ERR_WC_CLEANUP_REQUIRED is misnamed, since > libsvn_wc does not know whether cleanup is required. Rename it to > SVN_ERR_WC_BUSY or SVN_ERR_WC_WORK_QUEUE_NOT_EMPTY. > > 4. libsvn_wc should include the WC root in the error message: > > "A previous operation on the working copy at '<wcroot_abspath>' has > not finished" > > 5. 'svn' should print its message about running 'cleanup' via the > standard error message mechanism instead of using cmdline_fputs(), so > that the message appears in the standard (new) format with the > 'Ennnnnn:' prefix. This suggestion is independent of the others so I'll > commit it separately, but it's included in this patch for you to see. > > > With this patch, typical results are: > > $ svn up -q & svn up -q > svn: E155004: Run 'svn cleanup' to remove locks (type 'svn help > cleanup' for details) > svn: E155004: Working copy '/home/...' locked. > svn: E155004: '/home/...' is already locked. > > $ svn up -q & svn commit > svn: E155004: Run 'svn cleanup' to remove locks (type 'svn help > cleanup' for details) > svn: E155004: Commit failed (details follow): > svn: E155004: Working copy '/home/...' locked. > svn: E155004: '/home/...' is already locked. > > and for the more interesting, WQ-not-empty, case: > > $ svn status > svn: E155037: Run 'svn cleanup' to remove locks (type 'svn help > cleanup' for details) > svn: E155037: A previous operation on the working copy at '/home/...' > has not finished > > > I would propose all of this for 1.7.0 back-port. > > Concerns? > > - Julian > > Improve how we report that the WC is locked or busy (the 'run cleanup' > messages). > > * subversion/include/svn_error_codes.h > (SVN_ERR_WC_CLEANUP_REQUIRED): Rename to SVN_ERR_WC_BUSY and remove the > words about running 'cleanup', since libsvn_wc doesn't know whether > cleanup is required. > > * subversion/libsvn_wc/wc_db_wcroot.c > (verify_no_work): Take the WC root path and include that in the error > message. Add a doc string. > (svn_wc__db_pdh_create_wcroot): Adjust accordingly. > > * subversion/svn/main.c > (main): Print the message about running 'cleanup' when the subcommand > returned SVN_ERR_WC_BUSY as well as when it returned SVN_ERR_WC_LOCKED. > Print the message about running 'cleanup' using the standard mechanism > for error messages (so, for example, the error code will be displayed). > --This line, and those below, will be ignored-- > > Index: subversion/include/svn_error_codes.h > =================================================================== > --- subversion/include/svn_error_codes.h (revision 1145998) > +++ subversion/include/svn_error_codes.h (working copy) > @@ -520,10 +520,9 @@ SVN_ERROR_START > "The working copy needs to be upgraded") > > /** @since New in 1.7. */ > - SVN_ERRDEF(SVN_ERR_WC_CLEANUP_REQUIRED, > + SVN_ERRDEF(SVN_ERR_WC_BUSY, > SVN_ERR_WC_CATEGORY_START + 37, > - "Previous operation has not finished; " > - "run 'cleanup' if it was interrupted") > + "A previous operation on the working copy has not finished") > > /** @since New in 1.7. */ > SVN_ERRDEF(SVN_ERR_WC_INVALID_OPERATION_DEPTH, > Index: subversion/libsvn_wc/wc_db_wcroot.c > =================================================================== > --- subversion/libsvn_wc/wc_db_wcroot.c (revision 1145998) > +++ subversion/libsvn_wc/wc_db_wcroot.c (working copy) > @@ -139,9 +139,12 @@ get_path_kind(svn_wc__db_t *db, > } > > > -/* */ > +/* Return an error if the work queue in SDB is non-empty. WCROOT_ABSPATH > + * is used in the error message. */ > static svn_error_t * > -verify_no_work(svn_sqlite__db_t *sdb) > +verify_no_work(svn_sqlite__db_t *sdb, > + const char *wcroot_abspath, > + apr_pool_t *scratch_pool) > { > svn_sqlite__stmt_t *stmt; > svn_boolean_t have_row; > @@ -151,8 +154,11 @@ verify_no_work(svn_sqlite__db_t *sdb) > SVN_ERR(svn_sqlite__reset(stmt)); > > if (have_row) > - return svn_error_create(SVN_ERR_WC_CLEANUP_REQUIRED, NULL, > - NULL /* nothing to add. */); > + return svn_error_createf(SVN_ERR_WC_BUSY, NULL, > + _("A previous operation on the working " > + "copy at '%s' has not finished"), > + svn_dirent_local_style(wcroot_abspath, > + scratch_pool)); > > return SVN_NO_ERROR; > } > @@ -275,12 +281,12 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_ > if (format >= SVN_WC__HAS_WORK_QUEUE > && (enforce_empty_wq || (format < SVN_WC__VERSION && auto_upgrade))) > { > - svn_error_t *err = verify_no_work(sdb); > + svn_error_t *err = verify_no_work(sdb, wcroot_abspath, scratch_pool); > if (err) > { > /* Special message for attempts to upgrade a 1.7-dev wc with > outstanding workqueue items. */ > - if (err->apr_err == SVN_ERR_WC_CLEANUP_REQUIRED > + if (err->apr_err == SVN_ERR_WC_BUSY > && format < SVN_WC__VERSION && auto_upgrade) > err = svn_error_quick_wrap(err, _("Cleanup with an older 1.7 " > "client before upgrading with " > Index: subversion/svn/main.c > =================================================================== > --- subversion/svn/main.c (revision 1145998) > +++ subversion/svn/main.c (working copy) > @@ -2596,6 +2596,14 @@ main(int argc, const char *argv[]) > _("Please see the 'svn > upgrade' command")); > } > > + /* Tell the user about 'svn cleanup' if any error on the stack > + was about locked working copies. */ > + if (svn_error_find_cause(err, SVN_ERR_WC_LOCKED) > + || svn_error_find_cause(err, SVN_ERR_WC_BUSY)) > + err = svn_error_quick_wrap(err, > + _("Run 'svn cleanup' to remove locks " > + "(type 'svn help cleanup' for > details)")); > + > /* Issue #3014: > * Don't print anything on broken pipes. The pipe was likely > * closed by the process at the other end. We expect that > @@ -2606,14 +2614,6 @@ main(int argc, const char *argv[]) > if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR) > svn_handle_error2(err, stderr, FALSE, "svn: "); > > - /* Tell the user about 'svn cleanup' if any error on the stack > - was about locked working copies. */ > - if (svn_error_find_cause(err, SVN_ERR_WC_LOCKED)) > - svn_error_clear(svn_cmdline_fputs(_("svn: run 'svn cleanup' to " > - "remove locks (type 'svn help " > - "cleanup' for details)\n"), > - stderr, pool)); > - > svn_error_clear(err); > svn_pool_destroy(pool); > return EXIT_FAILURE;