You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2018/05/19 16:26:28 UTC
svn commit: r1831908 - in /subversion/trunk/subversion: include/svn_client.h
libsvn_client/shelf.c libsvn_client/status.c tests/cmdline/shelf_tests.py
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__':