From commits-return-48883-archive-asf-public=cust-asf.ponee.io@subversion.apache.org Sat May 19 18:26:31 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 087D118063B for ; Sat, 19 May 2018 18:26:30 +0200 (CEST) Received: (qmail 4622 invoked by uid 500); 19 May 2018 16:26:30 -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 4610 invoked by uid 99); 19 May 2018 16:26:30 -0000 Received: from Unknown (HELO svn01-us-west.apache.org) (209.188.14.144) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 19 May 2018 16:26:30 +0000 Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 490553A00C5 for ; Sat, 19 May 2018 16:26:29 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1831908 - in /subversion/trunk/subversion: include/svn_client.h libsvn_client/shelf.c libsvn_client/status.c tests/cmdline/shelf_tests.py Date: Sat, 19 May 2018 16:26:28 -0000 To: commits@subversion.apache.org From: julianfoad@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20180519162629.490553A00C5@svn01-us-west.apache.org> Author: julianfoad Date: Sat May 19 16:26:28 2018 New Revision: 1831908 URL: http://svn.apache.org/viewvc?rev=1831908&view=rev Log: Shelving: implement 'svn status' for a shelf. The interface uses a special form of changelist name, 'svn:shelf:SHELFNAME', to request operating on a shelf. Example: $ svn st --cl svn:shelf:foo --- Changelist 'svn:shelf:foo': A add.txt MM mod.txt D del.txt TODO: specialize the command-line syntax and output format to say 'shelf' and hide the 'svn:shelf:' prefix. * subversion/include/svn_client.h (svn_client_shelf_version_status_walk): New. * subversion/libsvn_client/shelf.c (wc_status_unserialize): Rename the unused pool parameter. (status_read): Fill in the changelist name as 'svn:shelf:SHELFNAME'. (shelf_status_baton_t, shelf_status_visitor, shelf_status_visit_path, shelf_status_walk): Allow starting the walk at a given top relpath. (wc_status_baton_t, wc_status_visitor, svn_client_shelf_version_status_walk): New. (shelf_paths_changed, svn_client_shelf_apply, svn_client_shelf_export_patch): Adjust callers (top relpath = ""). * subversion/libsvn_client/status.c (shelf_status, shelves_status): New. (svn_client_status6): Run status on any requested shelves, before the main WC. * subversion/tests/cmdline/shelf_tests.py (shelf_status): New test. (test_list): Run it. Modified: subversion/trunk/subversion/include/svn_client.h subversion/trunk/subversion/libsvn_client/shelf.c subversion/trunk/subversion/libsvn_client/status.c subversion/trunk/subversion/tests/cmdline/shelf_tests.py Modified: subversion/trunk/subversion/include/svn_client.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1831908&r1=1831907&r2=1831908&view=diff ============================================================================== --- subversion/trunk/subversion/include/svn_client.h (original) +++ subversion/trunk/subversion/include/svn_client.h Sat May 19 16:26:28 2018 @@ -7274,6 +7274,15 @@ svn_client_shelf_list(apr_hash_t **shelf apr_pool_t *result_pool, apr_pool_t *scratch_pool); +/* Report the shelved status of all the shelved paths in SHELF_VERSION + * via WALK_FUNC(WALK_BATON, ...). + */ +svn_error_t * +svn_client_shelf_version_status_walk(svn_client_shelf_version_t *shelf_version, + const char *wc_relpath, + svn_wc_status_func4_t walk_func, + void *walk_baton, + apr_pool_t *scratch_pool); /** @} */ /** Changelist commands Modified: subversion/trunk/subversion/libsvn_client/shelf.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/shelf.c?rev=1831908&r1=1831907&r2=1831908&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/shelf.c (original) +++ subversion/trunk/subversion/libsvn_client/shelf.c Sat May 19 16:26:28 2018 @@ -485,7 +485,7 @@ wc_status_serialize(svn_stream_t *stream static svn_error_t * wc_status_unserialize(svn_wc_status3_t *status, svn_stream_t *stream, - apr_pool_t *scratch_pool) + apr_pool_t *result_pool) { char string[5]; apr_size_t len = 5; @@ -527,9 +527,10 @@ static svn_error_t * status_read(svn_wc_status3_t **status, svn_client_shelf_version_t *shelf_version, const char *relpath, + apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_wc_status3_t *s = apr_pcalloc(scratch_pool, sizeof(*s)); + svn_wc_status3_t *s = apr_pcalloc(result_pool, sizeof(*s)); char *file_abspath; svn_stream_t *stream; @@ -537,9 +538,11 @@ status_read(svn_wc_status3_t **status, scratch_pool, scratch_pool)); SVN_ERR(svn_stream_open_readonly(&stream, file_abspath, scratch_pool, scratch_pool)); - SVN_ERR(wc_status_unserialize(s, stream, scratch_pool)); + SVN_ERR(wc_status_unserialize(s, stream, result_pool)); SVN_ERR(svn_stream_close(stream)); + s->changelist = apr_psprintf(result_pool, "svn:shelf:%s", + shelf_version->shelf->name); *status = s; return SVN_NO_ERROR; } @@ -557,6 +560,7 @@ typedef svn_error_t *(*shelf_status_visi struct shelf_status_baton_t { svn_client_shelf_version_t *shelf_version; + const char *top_relpath; const char *walk_root_abspath; shelf_status_visitor_t walk_func; void *walk_baton; @@ -581,7 +585,11 @@ shelf_status_visitor(void *baton, svn_wc_status3_t *s; relpath = apr_pstrndup(scratch_pool, relpath, strlen(relpath) - 5); - SVN_ERR(status_read(&s, b->shelf_version, relpath, scratch_pool)); + if (!svn_relpath_skip_ancestor(b->top_relpath, relpath)) + return SVN_NO_ERROR; + + SVN_ERR(status_read(&s, b->shelf_version, relpath, + scratch_pool, scratch_pool)); SVN_ERR(b->walk_func(b->walk_baton, relpath, s, scratch_pool)); } return SVN_NO_ERROR; @@ -602,6 +610,7 @@ shelf_status_visit_path(svn_client_shelf apr_finfo_t finfo; baton.shelf_version = shelf_version; + baton.top_relpath = wc_relpath; baton.walk_root_abspath = shelf_version->files_dir_abspath; baton.walk_func = walk_func; baton.walk_baton = walk_baton; @@ -617,6 +626,7 @@ shelf_status_visit_path(svn_client_shelf */ static svn_error_t * shelf_status_walk(svn_client_shelf_version_t *shelf_version, + const char *wc_relpath, shelf_status_visitor_t walk_func, void *walk_baton, apr_pool_t *scratch_pool) @@ -625,6 +635,7 @@ shelf_status_walk(svn_client_shelf_versi svn_error_t *err; baton.shelf_version = shelf_version; + baton.top_relpath = wc_relpath; baton.walk_root_abspath = shelf_version->files_dir_abspath; baton.walk_func = walk_func; baton.walk_baton = walk_baton; @@ -639,6 +650,45 @@ shelf_status_walk(svn_client_shelf_versi return SVN_NO_ERROR; } +typedef struct wc_status_baton_t +{ + svn_client_shelf_version_t *shelf_version; + svn_wc_status_func4_t walk_func; + void *walk_baton; +} wc_status_baton_t; + +static svn_error_t * +wc_status_visitor(void *baton, + const char *relpath, + svn_wc_status3_t *status, + apr_pool_t *scratch_pool) +{ + struct wc_status_baton_t *b = baton; + svn_client_shelf_t *shelf = b->shelf_version->shelf; + const char *abspath = svn_dirent_join(shelf->wc_root_abspath, relpath, + scratch_pool); + SVN_ERR(b->walk_func(b->walk_baton, abspath, status, scratch_pool)); + return SVN_NO_ERROR; +} + +svn_error_t * +svn_client_shelf_version_status_walk(svn_client_shelf_version_t *shelf_version, + const char *wc_relpath, + svn_wc_status_func4_t walk_func, + void *walk_baton, + apr_pool_t *scratch_pool) +{ + wc_status_baton_t baton; + + baton.shelf_version = shelf_version; + baton.walk_func = walk_func; + baton.walk_baton = walk_baton; + SVN_ERR(shelf_status_walk(shelf_version, wc_relpath, + wc_status_visitor, &baton, + scratch_pool)); + return SVN_NO_ERROR; +} + /* A baton for use with walk_callback(). */ typedef struct write_changes_baton_t { const char *wc_root_abspath; @@ -1158,7 +1208,7 @@ shelf_paths_changed(apr_hash_t **paths_h baton.as_abspath = as_abspath; baton.wc_root_abspath = shelf->wc_root_abspath; baton.pool = result_pool; - SVN_ERR(shelf_status_walk(shelf_version, + SVN_ERR(shelf_status_walk(shelf_version, "", paths_changed_visitor, &baton, scratch_pool)); @@ -1508,7 +1558,7 @@ svn_client_shelf_apply(svn_client_shelf_ baton.shelf_version = shelf_version; baton.ctx = shelf_version->shelf->ctx; - SVN_ERR(shelf_status_walk(shelf_version, + SVN_ERR(shelf_status_walk(shelf_version, "", apply_file_visitor, &baton, scratch_pool)); @@ -1579,7 +1629,7 @@ svn_client_shelf_export_patch(svn_client baton.shelf_version = shelf_version; baton.outstream = outstream; - SVN_ERR(shelf_status_walk(shelf_version, + SVN_ERR(shelf_status_walk(shelf_version, "", diff_visitor, &baton, scratch_pool)); return SVN_NO_ERROR; Modified: subversion/trunk/subversion/libsvn_client/status.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/status.c?rev=1831908&r1=1831907&r2=1831908&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/status.c (original) +++ subversion/trunk/subversion/libsvn_client/status.c Sat May 19 16:26:28 2018 @@ -329,6 +329,77 @@ do_external_status(svn_client_ctx_t *ctx return SVN_NO_ERROR; } + +/* Run status on shelf SHELF_NAME, if it exists. + */ +static svn_error_t * +shelf_status(const char *shelf_name, + const char *target_abspath, + svn_wc_status_func4_t status_func, + void *status_baton, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) +{ + svn_error_t *err; + svn_client_shelf_t *shelf; + svn_client_shelf_version_t *shelf_version; + const char *wc_relpath; + + err = svn_client_shelf_open_existing(&shelf, + shelf_name, target_abspath, + ctx, scratch_pool); + if (err && err->apr_err == SVN_ERR_ILLEGAL_TARGET) + { + svn_error_clear(err); + return SVN_NO_ERROR; + } + else + SVN_ERR(err); + + SVN_ERR(svn_client_shelf_version_open(&shelf_version, + shelf, shelf->max_version, + scratch_pool, scratch_pool)); + wc_relpath = svn_dirent_skip_ancestor(shelf->wc_root_abspath, target_abspath); + SVN_ERR(svn_client_shelf_version_status_walk(shelf_version, wc_relpath, + status_func, status_baton, + scratch_pool)); + SVN_ERR(svn_client_shelf_close(shelf, scratch_pool)); + + return SVN_NO_ERROR; +} + +/* Run status on all shelves named in CHANGELISTS by a changelist name + * of the form "svn:shelf:SHELF_NAME", if they exist. + */ +static svn_error_t * +shelves_status(const apr_array_header_t *changelists, + const char *target_abspath, + svn_wc_status_func4_t status_func, + void *status_baton, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) +{ + static const char PREFIX[] = "svn:shelf:"; + static const int PREFIX_LEN = 10; + int i; + + for (i = 0; i < changelists->nelts; i++) + { + const char *cl = APR_ARRAY_IDX(changelists, i, const char *); + + if (strncmp(cl, PREFIX, PREFIX_LEN) == 0) + { + const char *shelf_name = cl + PREFIX_LEN; + + SVN_ERR(shelf_status(shelf_name, target_abspath, + status_func, status_baton, + ctx, scratch_pool)); + } + } + + return SVN_NO_ERROR; +} + /*** Public Interface. ***/ @@ -586,6 +657,9 @@ svn_client_status6(svn_revnum_t *result_ } else { + SVN_ERR(shelves_status(changelists, target_abspath, + tweak_status, &sb, + ctx, pool)); err = svn_wc_walk_status(ctx->wc_ctx, target_abspath, depth, get_all, no_ignore, FALSE, ignores, tweak_status, &sb, Modified: subversion/trunk/subversion/tests/cmdline/shelf_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/shelf_tests.py?rev=1831908&r1=1831907&r2=1831908&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/shelf_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/shelf_tests.py Sat May 19 16:26:28 2018 @@ -414,6 +414,29 @@ def shelve_with_log_message(sbox): os.chdir(was_cwd) +#---------------------------------------------------------------------- + +def shelf_status(sbox): + "shelf status" + + sbox.build(empty=True) + was_cwd = os.getcwd() + os.chdir(sbox.wc_dir) + sbox.wc_dir = '' + + sbox.simple_add_text('New file', 'f') + svntest.actions.run_and_verify_svn(None, [], + 'shelve', 'foo') + expected_output = svntest.verify.RegexListOutput( + ["", + "--- Changelist 'svn:shelf:foo':", + "A f", + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'status', '--cl=svn:shelf:foo') + + os.chdir(was_cwd) + ######################################################################## # Run the tests @@ -436,6 +459,7 @@ test_list = [ None, shelve_binary_file_del, shelve_binary_file_replace, shelve_with_log_message, + shelf_status, ] if __name__ == '__main__':