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 2017/07/26 12:44:34 UTC
svn commit: r1803040 - in /subversion/branches/shelve-checkpoint3: ./
subversion/include/ subversion/libsvn_client/ subversion/svn/
tools/client-side/
Author: julianfoad
Date: Wed Jul 26 12:44:33 2017
New Revision: 1803040
URL: http://svn.apache.org/viewvc?rev=1803040&view=rev
Log:
On the 'shelve-checkpoint3' branch: Initial prototype of Checkpointing
backed by a local repository embedded within the WC.
* BRANCH-README
Update.
* build.conf
(libsvn_client): Now depends on libsvn_repos and libsvn_fs.
* subversion/include/svn_client.h
(svn_client_checkpoint_init,
svn_client_checkpoint_uninit,
svn_client_checkpoint_squash,
svn_client_checkpoint_get_current,
svn_client_checkpoint_save,
svn_client_checkpoint_revert,
svn_client_checkpoint_list): New.
* subversion/libsvn_client/checkpoint3.c
New file.
* subversion/libsvn_client/client.h
* subversion/libsvn_client/import.c
(svn_client__import_internal): Expose this internal interface.
* subversion/svn/checkpoint3-cmd.c
New file.
* subversion/svn/cl.h
(svn_cl__checkpoint): New.
* subversion/svn/svn.c
(svn_cl__cmd_table): Add the 'checkpoint' command.
* tools/client-side/bash_completion
(_svn): Add the 'checkpoint' command.
Added:
subversion/branches/shelve-checkpoint3/subversion/libsvn_client/checkpoint3.c (with props)
subversion/branches/shelve-checkpoint3/subversion/svn/checkpoint3-cmd.c (with props)
Modified:
subversion/branches/shelve-checkpoint3/BRANCH-README
subversion/branches/shelve-checkpoint3/build.conf
subversion/branches/shelve-checkpoint3/subversion/include/svn_client.h
subversion/branches/shelve-checkpoint3/subversion/libsvn_client/client.h
subversion/branches/shelve-checkpoint3/subversion/libsvn_client/import.c
subversion/branches/shelve-checkpoint3/subversion/svn/cl.h
subversion/branches/shelve-checkpoint3/subversion/svn/svn.c
subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion
Modified: subversion/branches/shelve-checkpoint3/BRANCH-README
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/BRANCH-README?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/BRANCH-README (original)
+++ subversion/branches/shelve-checkpoint3/BRANCH-README Wed Jul 26 12:44:33 2017
@@ -1,13 +1,12 @@
-This branch is for development of Shelving and Checkpointing.
-
-Specifically, this branch is for Checkpointing backed by a local repository
+This branch is for prototyping Checkpointing backed by a local repository
embedded within the WC, referred to as design "option 3" in [1].
-Branch type: dev branch off trunk; updated by full merges from trunk.
+Branch type: dev branch off 'shelve' branch; updated by full merges from
+there; not intended to be merged to trunk.
-Initially this is prototyping, to explore the general shape of the design and
-user interface. As such, it does not take care over details of APIs and error
-handling and so on.
+Initially this is prototyping, to explore the general shape of the design
+and user interface. As such, the coding style is hacky and does not comply
+with Subversion coding requirements.
References:
[0] dev@ thread "[RFC] Shelving and Checkpointing", J Foad, 2017-07-10.
Modified: subversion/branches/shelve-checkpoint3/build.conf
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/build.conf?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/build.conf (original)
+++ subversion/branches/shelve-checkpoint3/build.conf Wed Jul 26 12:44:33 2017
@@ -243,7 +243,7 @@ link-cmd = $(LINK_CXX_LIB)
description = Subversion Client Library
type = lib
path = subversion/libsvn_client
-libs = libsvn_wc libsvn_ra libsvn_delta libsvn_diff libsvn_subr apriconv apr
+libs = libsvn_wc libsvn_ra libsvn_delta libsvn_diff libsvn_repos libsvn_fs libsvn_subr apriconv apr
install = lib
msvc-export = svn_client.h private/svn_client_mtcc.h private/svn_client_private.h
Modified: subversion/branches/shelve-checkpoint3/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/include/svn_client.h?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/subversion/include/svn_client.h (original)
+++ subversion/branches/shelve-checkpoint3/subversion/include/svn_client.h Wed Jul 26 12:44:33 2017
@@ -6716,6 +6716,90 @@ svn_client_cat(svn_stream_t *out,
+/** Checkpointing commands
+ *
+ * @defgroup svn_client_checkpoint_funcs Client Checkpointing Functions
+ * @{
+ */
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_checkpoint_init(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_checkpoint_uninit(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_checkpoint_squash(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_checkpoint_get_current(int *checkpoint_number_p,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
+ * Set *checkpoint_number to the new checkpoint revision number,
+ * or to -1 if no change was saved.
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_checkpoint_save(int *checkpoint_number,
+ const char *local_abspath,
+ /*const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,*/
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_checkpoint_revert(int checkpoint_number,
+ const char *local_abspath,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_checkpoint_list(apr_array_header_t **checkpoints,
+ const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** @} */
+
+
+
/** Shelving commands
*
* @defgroup svn_client_shelve_funcs Client Shelving Functions
Added: subversion/branches/shelve-checkpoint3/subversion/libsvn_client/checkpoint3.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/libsvn_client/checkpoint3.c?rev=1803040&view=auto
==============================================================================
--- subversion/branches/shelve-checkpoint3/subversion/libsvn_client/checkpoint3.c (added)
+++ subversion/branches/shelve-checkpoint3/subversion/libsvn_client/checkpoint3.c Wed Jul 26 12:44:33 2017
@@ -0,0 +1,709 @@
+/*
+ * checkpoint3.c: implementation of 'checkpoint' by commits in a local repo
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#include <string.h>
+#include <apr_strings.h>
+#include <apr_hash.h>
+#include "svn_hash.h"
+#include "svn_wc.h"
+#include "svn_ra.h"
+#include "svn_client.h"
+#include "svn_string.h"
+#include "svn_pools.h"
+#include "svn_error.h"
+#include "svn_error_codes.h"
+#include "svn_dirent_uri.h"
+#include "svn_path.h"
+#include "svn_sorts.h"
+#include "svn_props.h"
+#include "svn_repos.h"
+
+#include "client.h"
+#include "private/svn_wc_private.h"
+#include "private/svn_ra_private.h"
+#include "private/svn_sorts_private.h"
+
+#include "svn_private_config.h"
+
+
+/* -------------------- checkpoint repo -------------------- */
+
+/* Return the abspatch to the checkpoints repo.
+ *
+ * It need not necessarily exist.
+ */
+static char *
+checkpoints_repo_dir(const char *wc_root_abspath,
+ apr_pool_t *scratch_pool)
+{
+ return svn_path_join_many(scratch_pool,
+ wc_root_abspath, ".svn", "checkpoints",
+ SVN_VA_NULL);
+}
+
+/* ### temp: we should not be accessing the repo via URL but directly */
+static char *
+checkpoints_repo_url(const char *wc_root_abspath,
+ apr_pool_t *scratch_pool)
+{
+ return apr_pstrcat(scratch_pool,
+ "file://", wc_root_abspath, "/.svn/checkpoints",
+ SVN_VA_NULL);
+}
+
+static char *
+original_repos_url(const char *wc_root_abspath,
+ apr_pool_t *scratch_pool)
+{
+ return apr_pstrcat(scratch_pool,
+ "file://", wc_root_abspath, "/../repo",
+ SVN_VA_NULL);
+}
+
+/* Create the repo if it is not already present.
+ *
+ * Open the repo and return it in *REPOS_P.
+ */
+static svn_error_t *
+checkpoints_repo_create(svn_repos_t **repos_p,
+ const char *wc_root_abspath,
+ const char *uuid,
+ apr_pool_t *scratch_pool)
+{
+ const char *repo_dir
+ = checkpoints_repo_dir(wc_root_abspath, scratch_pool);
+
+ SVN_ERR(svn_repos_create(repos_p, repo_dir,
+ NULL, NULL, NULL, NULL, scratch_pool));
+ SVN_ERR(svn_fs_set_uuid(svn_repos_fs(*repos_p), uuid, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* Open the checkpoints repo.
+ */
+static svn_error_t *
+checkpoints_repo_open(svn_repos_t **repos_p,
+ const char *wc_root_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *repo_dir
+ = checkpoints_repo_dir(wc_root_abspath, scratch_pool);
+
+ SVN_ERR(svn_repos_open3(repos_p, repo_dir,
+ NULL, result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+checkpoints_repo_destroy(const char *wc_root_abspath,
+ apr_pool_t *scratch_pool)
+{
+ printf(" (destroying the repo is not implemented yet)\n");
+ return SVN_NO_ERROR;
+}
+
+/* Prune revisions later than NEW_HEAD from the repo at REPO_DIR.
+ * ### Ultra hacky!
+ */
+static svn_error_t *
+checkpoints_repo_prune(const char *repo_dir,
+ svn_revnum_t new_head,
+ apr_pool_t *scratch_pool)
+{
+ char *current_file_path = svn_path_join(repo_dir, "db/current", scratch_pool);
+ char *rep_cache_db_path = svn_path_join(repo_dir, "db/rep-cache.db", scratch_pool);
+ int old_head, r;
+
+ SVN_ERR(svn_io_read_version_file(&old_head, current_file_path, scratch_pool));
+ SVN_ERR(svn_io_write_version_file(current_file_path, new_head, scratch_pool));
+
+ /* Remove later rev files (at least the revprop files need to be gone) */
+ for (r = old_head; r > new_head; r--)
+ {
+ char *rev_file_path
+ = apr_psprintf(scratch_pool, "%s/db/revs/0/%d", repo_dir, r);
+ char *revprop_file_path
+ = apr_psprintf(scratch_pool, "%s/db/revprops/0/%d", repo_dir, r);
+
+ printf("pruning checkpoint %d\n", r - 1);
+ SVN_ERR(svn_io_remove_file2(rev_file_path, FALSE /*ignore_enoent*/,
+ scratch_pool));
+ SVN_ERR(svn_io_remove_file2(revprop_file_path, FALSE /*ignore_enoent*/,
+ scratch_pool));
+ }
+ /* Remove later revs from the rep cache */
+ /* ### For now, remove the whole rep cache */
+ SVN_ERR(svn_io_remove_file2(rep_cache_db_path, TRUE /*ignore_enoent*/,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* -------------------- transfers -------------------- */
+
+/* Update the WC to r(checkpoint_number + 1).
+ */
+static svn_error_t *
+checkpoint_update(int checkpoint_number,
+ const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *paths = apr_array_make(scratch_pool, 1, sizeof(char *));
+ svn_opt_revision_t revision = {svn_opt_revision_number};
+
+ APR_ARRAY_PUSH(paths, const char *) = wc_root_abspath;
+ revision.value.number = checkpoint_number + 1;
+
+ SVN_ERR(svn_client_update4(NULL /*result_revs*/,
+ paths, &revision,
+ svn_depth_infinity,
+ FALSE /*depth_is_sticky*/,
+ TRUE /*ignore_externals*/,
+ TRUE /*allow_unver_obstructions*/,
+ TRUE /*adds_as_modification*/,
+ FALSE /*make_parents*/,
+ ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Copy the WC base into the repo.
+ *
+ * ### Uses 'import' from disk into a commit editor.
+ * ### Lots of problems with that: loses props, adds unversioned files, etc.
+ * ### Instead, must export content and props directly from WC base.
+ */
+static svn_error_t *
+copy_base(const char *wc_root_abspath,
+ svn_repos_t *repos,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const svn_delta_editor_t *editor;
+ void *edit_baton;
+ const char *repos_url = checkpoints_repo_url(wc_root_abspath, scratch_pool);
+ /* List of in-repo path components from repo root to WC root. */
+ apr_array_header_t *new_entries = apr_array_make(scratch_pool, 4,
+ sizeof(const char *));
+ svn_boolean_t updated_repository;
+
+ SVN_ERR(svn_repos_get_commit_editor5(&editor, &edit_baton,
+ repos,
+ NULL /*txn*/,
+ "" /*repos_url_decoded*/,
+ "" /*base_path*/,
+ apr_hash_make(scratch_pool) /*revprop_table*/,
+ NULL, NULL, /*commit cb*/
+ NULL, NULL, /*authz cb*/
+ scratch_pool));
+
+ SVN_ERR(svn_client__import_internal(
+ &updated_repository,
+ wc_root_abspath,
+ repos_url, /* used just for a notification */
+ new_entries, editor, edit_baton,
+ svn_depth_infinity, 0 /*base_rev*/,
+ apr_hash_make(scratch_pool) /*excludes*/,
+ NULL /*autoprops*/,
+ NULL /*local_ignores_arr*/, NULL /*global_ignores*/,
+ TRUE /*no_ignore*/,
+ TRUE /*no_autoprops*/,
+ TRUE /*ignore_unknown_node_types*/,
+ NULL, NULL, /*filter cb*/
+ ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* Switch the WC base to point to the new repo.
+ */
+static svn_error_t *
+switch_base(const char *wc_root_abspath,
+ svn_repos_t *repos,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *orig_repos_root_url;
+ const char *repos_url = checkpoints_repo_url(wc_root_abspath, scratch_pool);
+
+ SVN_ERR(svn_client_get_repos_root(&orig_repos_root_url, NULL /* uuid */,
+ wc_root_abspath,
+ ctx, scratch_pool, scratch_pool));
+ SVN_ERR(svn_client_relocate2(wc_root_abspath,
+ orig_repos_root_url, repos_url,
+ TRUE /*ignore_externals*/,
+ ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* Switch the WC base to point to the original repo.
+ */
+static svn_error_t *
+switch_to_original_base(const char *wc_root_abspath,
+ svn_repos_t *repos,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *orig_repos_url = original_repos_url(wc_root_abspath, scratch_pool);
+ const char *repos_url = checkpoints_repo_url(wc_root_abspath, scratch_pool);
+
+ SVN_ERR(svn_client_relocate2(wc_root_abspath,
+ repos_url, orig_repos_url,
+ TRUE /*ignore_externals*/,
+ ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/*
+ * Assumes no uncommitted mods.
+ */
+static svn_error_t *
+squash_to_working_state(const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *repos_pool = svn_pool_create(scratch_pool);
+ svn_repos_t *repos;
+ svn_opt_revision_t peg_revision1 = {svn_opt_revision_head};
+ apr_array_header_t *ranges_to_merge
+ = apr_array_make(scratch_pool, 1, sizeof(void *));
+ svn_opt_revision_range_t range = { {svn_opt_revision_number, {1}},
+ {svn_opt_revision_head} };
+
+ SVN_ERR(checkpoints_repo_open(&repos, wc_root_abspath,
+ repos_pool, scratch_pool));
+
+ /* update to r1 */
+ printf(" (squash: updating to r1)\n");
+ SVN_ERR(checkpoint_update(0 /*checkpoint_number*/, wc_root_abspath,
+ ctx, scratch_pool));
+
+ /* merge all committed changes into WC, with no mergeinfo */
+ printf(" (squash: merging checkpointed changes into WC)\n");
+ APR_ARRAY_PUSH(ranges_to_merge, void *) = ⦥
+ SVN_ERR(svn_client_merge_peg5("" /*sourcepath1*/,
+ ranges_to_merge,
+ &peg_revision1,
+ "" /*targetpath*/,
+ svn_depth_infinity,
+ TRUE /*ignore_mergeinfo*/,
+ FALSE /*diff_ignore_ancestry*/,
+ FALSE /*force_delete*/,
+ FALSE /*record_only*/,
+ FALSE /*dry_run*/,
+ FALSE /*allow_mixed_rev*/,
+ NULL /*options*/,
+ ctx, scratch_pool));
+
+ /* Close the repo */
+ svn_pool_destroy(repos_pool);
+
+ return SVN_NO_ERROR;
+}
+
+/* Start a series of checkpoints.
+ *
+ * Create a local repo.
+ * Copy the WC base into it.
+ * Switch the WC to point at it.
+ *
+ * Assumptions (for initial prototype):
+ * WC is clean
+ * WC is single-rev
+ * WC base is at r1!
+ * WC root URL is repos root URL
+ */
+static svn_error_t *
+checkpoints_init(const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *uuid;
+ apr_pool_t *repos_pool = svn_pool_create(scratch_pool);
+ svn_repos_t *repos;
+
+ SVN_ERR(svn_client_uuid_from_path2(&uuid, wc_root_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ printf("creating repo\n");
+ SVN_ERR(checkpoints_repo_create(&repos, wc_root_abspath, uuid, repos_pool));
+
+ printf("copying base\n");
+ SVN_ERR(copy_base(wc_root_abspath, repos, ctx, scratch_pool));
+
+ printf("switching base\n");
+ SVN_ERR(switch_base(wc_root_abspath, repos, ctx, scratch_pool));
+
+ /* Close the repo */
+ svn_pool_destroy(repos_pool);
+ return SVN_NO_ERROR;
+}
+
+/* End a series of checkpoints.
+ *
+ * Switch the WC base to point at the original repo and base revision(s).
+ * Make the WC working state be the checkpoint final state.
+ * Destroy the local repo.
+ *
+ * Assumptions (for initial prototype):
+ */
+static svn_error_t *
+checkpoints_uninit(const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *repos_pool = svn_pool_create(scratch_pool);
+ svn_repos_t *repos;
+
+ SVN_ERR(checkpoints_repo_open(&repos, wc_root_abspath,
+ repos_pool, scratch_pool));
+
+ printf("switching back to original base\n");
+ SVN_ERR(switch_to_original_base(wc_root_abspath, repos, ctx, scratch_pool));
+
+ /* Close the repo */
+ svn_pool_destroy(repos_pool);
+
+ printf("destroying the checkpoints repo\n");
+ SVN_ERR(checkpoints_repo_destroy(wc_root_abspath, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Set *CURRENT to the current checkpoint number.
+ */
+static svn_error_t *
+read_current(int *current,
+ const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *repos_pool = svn_pool_create(scratch_pool);
+ svn_repos_t *repos;
+ svn_revnum_t youngest;
+
+ SVN_ERR(checkpoints_repo_open(&repos, wc_root_abspath,
+ repos_pool, scratch_pool));
+ SVN_ERR(svn_fs_youngest_rev(&youngest, svn_repos_fs(repos), scratch_pool));
+ *current = (youngest - 1);
+
+ /* Close the repo */
+ svn_pool_destroy(repos_pool);
+ return SVN_NO_ERROR;
+}
+
+/* -------------------- checkpoint save -------------------- */
+
+typedef struct commit_baton_t {
+ svn_revnum_t revision;
+} commit_baton_t;
+
+static svn_error_t *
+commit_callback(const svn_commit_info_t *commit_info,
+ void *baton,
+ apr_pool_t *scratch_pool)
+{
+ commit_baton_t *cb = baton;
+
+ cb->revision = commit_info->revision;
+ return SVN_NO_ERROR;
+}
+
+/* Write a checkpoint of the whole WC.
+ */
+static svn_error_t *
+checkpoint_save(int *checkpoint_number,
+ /*const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,*/
+ const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *paths = apr_array_make(scratch_pool, 1, sizeof(char *));
+ commit_baton_t cb = { 0 };
+
+ APR_ARRAY_PUSH(paths, const char *) = wc_root_abspath;
+
+ /* ### TODO: if not at latest checkpoint, first prune later checkpoints */
+
+ ctx->log_msg_func3 = NULL;
+ ctx->log_msg_func2 = NULL;
+ ctx->log_msg_func = NULL;
+ SVN_ERR(svn_client_commit6(
+ paths,
+ svn_depth_infinity /*depth*/,
+ TRUE /*keep_locks*/,
+ TRUE /*keep_changelists*/,
+ TRUE /*commit_as_operations*/,
+ FALSE, /* include_file_externals */
+ FALSE, /* include_dir_externals */
+ NULL /*changelists*/,
+ NULL /*revprop_table*/,
+ commit_callback, &cb,
+ ctx, scratch_pool));
+
+ if (checkpoint_number)
+ *checkpoint_number = (cb.revision - 1);
+ return SVN_NO_ERROR;
+}
+
+/* -------------------- checkpoint ... -------------------- */
+
+/* */
+static svn_error_t *
+checkpoint_revert(int checkpoint_number,
+ const char *wc_root_abspath,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *paths = apr_array_make(scratch_pool, 1, sizeof(char *));
+
+ APR_ARRAY_PUSH(paths, const char *) = wc_root_abspath;
+
+ /* Revert the WC local mods */
+ SVN_ERR(svn_client_revert3(paths,
+ svn_depth_infinity,
+ NULL /*changelists*/,
+ FALSE /*clear_changelists*/,
+ FALSE /*metadata_only*/,
+ ctx, scratch_pool));
+
+ SVN_ERR(checkpoint_update(checkpoint_number, wc_root_abspath,
+ ctx, scratch_pool));
+
+ /* Prune later revisions from the repo */
+ SVN_ERR(checkpoints_repo_prune(
+ checkpoints_repo_dir(wc_root_abspath, scratch_pool),
+ checkpoint_number + 1, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* -------------------- checkpoint ... -------------------- */
+
+svn_error_t *
+svn_client_checkpoint_init(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *wc_root_abspath;
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath, local_abspath,
+ ctx, scratch_pool, scratch_pool));
+ SVN_ERR(checkpoints_init(wc_root_abspath, ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_checkpoint_squash(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *wc_root_abspath;
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath, local_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ printf("checkpointing any outstanding changes\n");
+ SVN_ERR(checkpoint_save(NULL /*checkpoint_number*/,
+ wc_root_abspath, ctx, scratch_pool));
+
+ printf("squashing checkpoints to a working state\n");
+ SVN_ERR(squash_to_working_state(wc_root_abspath,
+ ctx, scratch_pool));
+
+ /* Prune later revisions from the repo */
+ SVN_ERR(checkpoints_repo_prune(
+ checkpoints_repo_dir(wc_root_abspath, scratch_pool),
+ 1 /*new_head revision*/, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_checkpoint_uninit(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *wc_root_abspath;
+
+ SVN_ERR(svn_client_checkpoint_squash(local_abspath, ctx, scratch_pool));
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath, local_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ SVN_ERR(checkpoints_uninit(wc_root_abspath, ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_checkpoint_get_current(int *checkpoint_number_p,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *wc_root_abspath;
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath, local_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ SVN_ERR(read_current(checkpoint_number_p, wc_root_abspath, ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_checkpoint_save(int *checkpoint_number,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *wc_root_abspath;
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath, local_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ SVN_ERR(checkpoint_save(checkpoint_number,
+ wc_root_abspath, ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_checkpoint_revert(int checkpoint_number,
+ const char *local_abspath,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *wc_root_abspath;
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath, local_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ /* ### TODO: Save the current state (of whole WC) */
+
+ /* Restore the requested checkpoint */
+ SVN_ERR(checkpoint_revert(checkpoint_number, wc_root_abspath,
+ dry_run,
+ ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* -------------------- checkpoint list -------------------- */
+
+#if 0
+typedef struct path_change_baton_t
+{
+ apr_array_header_t *changes;
+ apr_pool_t *result_pool;
+} path_change_baton_t;
+
+/* */
+static svn_error_t *
+path_change_func(void *baton,
+ svn_repos_path_change_t *change,
+ apr_pool_t *scratch_pool)
+{
+ path_change_baton_t *b = baton;
+
+ APR_ARRAY_PUSH(b->changes, void *) = svn_repos_path_change_dup(change, b->result_pool);
+ return SVN_NO_ERROR;
+}
+#endif
+
+typedef struct log_entry_baton_t
+{
+ /*path_change_baton_t *pb;*/
+ apr_array_header_t *entries;
+ apr_pool_t *result_pool;
+} log_entry_baton_t;
+
+/* */
+static svn_error_t *
+log_entry_func(void *baton,
+ svn_repos_log_entry_t *repos_log_entry,
+ apr_pool_t *scratch_pool)
+{
+ log_entry_baton_t *b = baton;
+ svn_log_entry_t *std_log_entry = svn_log_entry_create(b->result_pool);
+
+ std_log_entry->revision = repos_log_entry->revision;
+ std_log_entry->revprops = svn_prop_hash_dup(repos_log_entry->revprops,
+ b->result_pool);
+ /*std_log_entry->changed_paths2 = b->pb->changes;*/
+ /*b->pb->changes = apr_hash_make(b->pb->result_pool);*/
+ APR_ARRAY_PUSH(b->entries, void *) = std_log_entry;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_checkpoint_list(apr_array_header_t **checkpoints,
+ const char *wc_root_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ /*path_change_baton_t pb;*/
+ log_entry_baton_t lb;
+ apr_pool_t *repos_pool = svn_pool_create(scratch_pool);
+ svn_repos_t *repos;
+
+ SVN_ERR(checkpoints_repo_open(&repos, wc_root_abspath,
+ repos_pool, scratch_pool));
+
+ /*pb.changes = apr_array_make(scratch_pool, 0, sizeof(void *));*/
+ /*pb.result_pool = result_pool;*/
+ /*lb.pb = &pb;*/
+ lb.entries = apr_array_make(scratch_pool, 0, sizeof(void *));
+ lb.result_pool = result_pool;
+
+ SVN_ERR(svn_repos_get_logs5(repos, NULL /*paths*/,
+ SVN_INVALID_REVNUM /*start*/, 1 /*end*/,
+ 0 /*limit*/,
+ TRUE /*strict_node_history*/,
+ FALSE /*include_merged_revisions*/,
+ NULL /*revprops*/,
+ NULL, NULL, /*authz_read*/
+ NULL, NULL, /*path_change_func, &pb,*/
+ log_entry_func, &lb,
+ scratch_pool));
+
+ *checkpoints = lb.entries;
+
+ /* Close the repo */
+ svn_pool_destroy(repos_pool);
+ return SVN_NO_ERROR;
+}
+
Propchange: subversion/branches/shelve-checkpoint3/subversion/libsvn_client/checkpoint3.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: subversion/branches/shelve-checkpoint3/subversion/libsvn_client/checkpoint3.c
------------------------------------------------------------------------------
svn:mime-type = text/x-csrc
Modified: subversion/branches/shelve-checkpoint3/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/libsvn_client/client.h?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/subversion/libsvn_client/client.h (original)
+++ subversion/branches/shelve-checkpoint3/subversion/libsvn_client/client.h Wed Jul 26 12:44:33 2017
@@ -1267,6 +1267,28 @@ svn_client__merge_locked(svn_client__con
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* */
+svn_error_t *
+svn_client__import_internal(svn_boolean_t *updated_repository,
+ const char *local_abspath,
+ const char *url,
+ const apr_array_header_t *new_entries,
+ const svn_delta_editor_t *editor,
+ void *edit_baton,
+ svn_depth_t depth,
+ svn_revnum_t base_rev,
+ apr_hash_t *excludes,
+ apr_hash_t *autoprops,
+ apr_array_header_t *local_ignores,
+ apr_array_header_t *global_ignores,
+ svn_boolean_t no_ignore,
+ svn_boolean_t no_autoprops,
+ svn_boolean_t ignore_unknown_node_types,
+ svn_client_import_filter_func_t filter_callback,
+ void *filter_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/shelve-checkpoint3/subversion/libsvn_client/import.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/libsvn_client/import.c?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/subversion/libsvn_client/import.c (original)
+++ subversion/branches/shelve-checkpoint3/subversion/libsvn_client/import.c Wed Jul 26 12:44:33 2017
@@ -631,8 +631,8 @@ import_dir(const svn_delta_editor_t *edi
* called, it returns a directory baton for that directory, which is
* not necessarily the root.)
*/
-static svn_error_t *
-import(svn_boolean_t *updated_repository,
+svn_error_t *
+svn_client__import_internal(svn_boolean_t *updated_repository,
const char *local_abspath,
const char *url,
const apr_array_header_t *new_entries,
@@ -989,7 +989,7 @@ svn_client_import5(const char *path,
}
/* If an error occurred during the commit, properly abort the edit. */
- err = svn_error_trace(import(&updated_repository,
+ err = svn_error_trace(svn_client__import_internal(&updated_repository,
local_abspath, url, new_entries, editor,
edit_baton, depth, base_rev, excludes,
autoprops, local_ignores_arr, global_ignores,
Added: subversion/branches/shelve-checkpoint3/subversion/svn/checkpoint3-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/svn/checkpoint3-cmd.c?rev=1803040&view=auto
==============================================================================
--- subversion/branches/shelve-checkpoint3/subversion/svn/checkpoint3-cmd.c (added)
+++ subversion/branches/shelve-checkpoint3/subversion/svn/checkpoint3-cmd.c Wed Jul 26 12:44:33 2017
@@ -0,0 +1,307 @@
+/*
+ * checkpoint-cmd.c -- Checkpoint commands.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#include "svn_client.h"
+#include "svn_error_codes.h"
+#include "svn_error.h"
+#include "svn_path.h"
+#include "svn_utf.h"
+#include "svn_hash.h"
+
+#include "cl.h"
+
+#include "svn_private_config.h"
+#include "private/svn_sorts_private.h"
+
+
+/* */
+static svn_error_t *
+checkpoint_init(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(svn_client_checkpoint_init(local_abspath, ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+checkpoint_list(const char *local_abspath,
+ svn_boolean_t diffstat,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *checkpoints;
+ /*int current_checkpoint_number;*/
+ svn_boolean_t first = TRUE;
+ int i;
+
+ SVN_ERR(svn_client_checkpoint_list(&checkpoints,
+ local_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ /*SVN_ERR(svn_client_checkpoint_get_current(¤t_checkpoint_number,
+ local_abspath, ctx, scratch_pool));
+ current_checkpoint_name = apr_psprintf(scratch_pool, "%d.patch",
+ current_checkpoint_number);*/
+
+ for (i = 0; i < checkpoints->nelts; i++)
+ {
+ svn_log_entry_t *log_entry = APR_ARRAY_IDX(checkpoints, i, void *);
+ int number = (log_entry->revision - 1);
+ const char *name = apr_psprintf(scratch_pool, "%d", number);
+ char marker = (first ? '*' : ' ');
+ svn_string_t *date = svn_hash_gets(log_entry->revprops, "svn:date");
+
+ printf("%c %s %.16s\n",
+ marker, name, date ? date->data : "");
+
+ if (diffstat)
+ {
+ printf("\n");
+ }
+ first = FALSE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+checkpoint_save(/*const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,*/
+ svn_boolean_t quiet,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ int checkpoint_number;
+
+ SVN_ERR(svn_client_checkpoint_save(&checkpoint_number,
+ /*paths, depth, changelists,*/
+ local_abspath, ctx, scratch_pool));
+ if (! quiet)
+ {
+ if (checkpoint_number >= 0)
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "saved checkpoint %d\n",
+ checkpoint_number));
+ else
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "no changes\n"));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+checkpoint_squash(/*const char *arg,
+ svn_boolean_t dry_run,
+ svn_boolean_t quiet,*/
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(svn_client_checkpoint_squash(local_abspath, ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+checkpoint_revert(const char *arg,
+ svn_boolean_t dry_run,
+ svn_boolean_t quiet,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ int old_checkpoint_number;
+ int new_checkpoint_number;
+
+ SVN_ERR(svn_client_checkpoint_get_current(&old_checkpoint_number,
+ local_abspath, ctx, scratch_pool));
+ if (arg)
+ {
+ SVN_ERR(svn_cstring_atoi(&new_checkpoint_number, arg));
+ }
+ else
+ {
+ new_checkpoint_number = old_checkpoint_number;
+ }
+
+ SVN_ERR(svn_client_checkpoint_revert(new_checkpoint_number,
+ local_abspath,
+ dry_run, ctx, scratch_pool));
+#if 0
+ int i;
+ /* Delete any newer checkpoints */
+ for (i = old_checkpoint_number; i > new_checkpoint_number; i--)
+ {
+ SVN_ERR(svn_client_checkpoint_delete(i, local_abspath,
+ dry_run, ctx, scratch_pool));
+ if (! quiet)
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "deleted checkpoint %d\n",
+ i));
+ }
+#endif
+
+ if (!quiet)
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "reverted to checkpoint %d\n",
+ new_checkpoint_number));
+
+ return SVN_NO_ERROR;
+}
+
+/* First argument should be the subsubcommand. */
+static svn_error_t *
+get_subsubcommand(const char **subsubcommand,
+ apr_getopt_t *os,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *args;
+
+ SVN_ERR(svn_opt_parse_num_args(&args, os, 1, scratch_pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(subsubcommand,
+ APR_ARRAY_IDX(args, 0, const char *),
+ result_pool));
+ return SVN_NO_ERROR;
+}
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__checkpoint(apr_getopt_t *os,
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+ svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
+ const char *subsubcommand;
+ apr_array_header_t *targets;
+ const char *local_abspath;
+
+ SVN_ERR(get_subsubcommand(&subsubcommand, os, pool, pool));
+
+ /* Parse the remaining arguments as paths. */
+ SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+ opt_state->targets,
+ ctx, FALSE, pool));
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));
+
+ if (opt_state->quiet)
+ ctx->notify_func2 = NULL;
+
+ if (strcmp(subsubcommand, "init") == 0)
+ {
+ if (targets->nelts)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments"));
+
+ SVN_ERR(checkpoint_init(local_abspath, ctx, pool));
+ }
+ else if (strcmp(subsubcommand, "list") == 0
+ || strcmp(subsubcommand, "log") == 0)
+ {
+ if (targets->nelts)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments"));
+
+ SVN_ERR(checkpoint_list(local_abspath,
+ ! opt_state->quiet /*diffstat*/,
+ ctx, pool));
+ }
+ else if (strcmp(subsubcommand, "save") == 0)
+ {
+ if (targets->nelts)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments"));
+
+ /* ### TODO: Semantics for checkpointing selected paths.
+ svn_depth_t depth = opt_state->depth;
+
+ if (! targets->nelts)
+ return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL, NULL);
+
+ SVN_ERR(svn_cl__check_targets_are_local_paths(targets));
+
+ if (depth == svn_depth_unknown)
+ depth = svn_depth_infinity;
+
+ SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
+ */
+
+ SVN_ERR(checkpoint_save(/*targets, depth, opt_state->changelists,*/
+ opt_state->quiet, local_abspath, ctx, pool));
+ }
+ else if (strcmp(subsubcommand, "squash") == 0)
+ {
+ if (targets->nelts)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments"));
+
+ SVN_ERR(checkpoint_squash(/*NULL, opt_state->dry_run, opt_state->quiet,*/
+ local_abspath, ctx, pool));
+ }
+ else if (strcmp(subsubcommand, "revert") == 0)
+ {
+ if (targets->nelts)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments"));
+
+ SVN_ERR(checkpoint_revert(NULL, opt_state->dry_run, opt_state->quiet,
+ local_abspath, ctx, pool));
+ }
+ else if (strcmp(subsubcommand, "rollback") == 0)
+ {
+ const char *arg;
+
+ if (targets->nelts != 1)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, NULL);
+
+ /* Which checkpoint number? */
+ arg = APR_ARRAY_IDX(targets, 0, char *);
+
+ SVN_ERR(checkpoint_revert(arg, opt_state->dry_run, opt_state->quiet,
+ local_abspath, ctx, pool));
+ }
+ else if (strcmp(subsubcommand, "finish") == 0
+ || strcmp(subsubcommand, "uninit") == 0)
+ {
+ if (targets->nelts)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments"));
+
+ SVN_ERR(svn_client_checkpoint_uninit(local_abspath, ctx, pool));
+ }
+ else
+ {
+ return svn_error_createf(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
+ _("checkpoint: Unknown checkpoint command '%s'; "
+ "try 'svn help checkpoint'"),
+ subsubcommand);
+ }
+
+ return SVN_NO_ERROR;
+}
Propchange: subversion/branches/shelve-checkpoint3/subversion/svn/checkpoint3-cmd.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: subversion/branches/shelve-checkpoint3/subversion/svn/checkpoint3-cmd.c
------------------------------------------------------------------------------
svn:mime-type = text/x-csrc
Modified: subversion/branches/shelve-checkpoint3/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/svn/cl.h?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/subversion/svn/cl.h (original)
+++ subversion/branches/shelve-checkpoint3/subversion/svn/cl.h Wed Jul 26 12:44:33 2017
@@ -272,6 +272,7 @@ svn_opt_subcommand_t
svn_cl__cat,
svn_cl__changelist,
svn_cl__checkout,
+ svn_cl__checkpoint,
svn_cl__cleanup,
svn_cl__commit,
svn_cl__copy,
Modified: subversion/branches/shelve-checkpoint3/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/svn/svn.c?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/subversion/svn/svn.c (original)
+++ subversion/branches/shelve-checkpoint3/subversion/svn/svn.c Wed Jul 26 12:44:33 2017
@@ -611,6 +611,30 @@ const svn_opt_subcommand_desc2_t svn_cl_
" reporting the action taken.\n"),
{'r', 'q', 'N', opt_depth, opt_force, opt_ignore_externals} },
+ { "checkpoint", svn_cl__checkpoint, {0}, N_
+ ("Checkpoint the local changes.\n"
+ "usage: 0. checkpoint init\n"
+ " 1. checkpoint save\n"
+ " 2. checkpoint revert\n"
+ " 3. checkpoint rollback NUMBER\n"
+ " 4. checkpoint list|log\n"
+ " 5. checkpoint squash\n"
+ " 6. checkpoint finish|uninit\n"
+ "\n"
+ " 0. Initialize checkpointing.\n"
+ " ### WC must be a checkout of r1 of repo root\n"
+ " ### required before using other checkpointing commands\n"
+ " 1. Save the working state as a new checkpoint.\n"
+ " 2. Revert the working state to the current checkpoint.\n"
+ " 3. Roll back the working state to checkpoint NUMBER.\n"
+ " 4. List all checkpoints.\n"
+ " 5. Squash all checkpoints to just a base and working state.\n"
+ " 6. Return to a plain WC based on the original repository.\n"
+ " ### doesn't yet delete the checkpoint repo\n"),
+ {'q',
+ /*'-N', opt_depth, opt_targets, opt_changelist,*/
+ /*SVN_CL__LOG_MSG_OPTIONS*/} },
+
{ "cleanup", svn_cl__cleanup, {0}, N_
("Recursively clean up the working copy, removing write locks, resuming\n"
"unfinished operations, etc.\n"
Modified: subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion?rev=1803040&r1=1803039&r2=1803040&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion (original)
+++ subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion Wed Jul 26 12:44:33 2017
@@ -249,6 +249,7 @@ _svn()
cmds="$cmds plist propset pset relocate resolve resolved revert status"
cmds="$cmds switch unlock update upgrade"
cmds="$cmds shelve shelves unshelve"
+ cmds="$cmds checkpoint"
# help options have a strange command status...
local helpOpts='--help -h'
@@ -1029,6 +1030,9 @@ _svn()
shelves)
cmdOpts="$qOpts"
;;
+ checkpoint)
+ cmdOpts="$qOpts"
+ ;;
*)
;;
esac