You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/12/12 17:43:45 UTC
svn commit: r1044847 [3/4] - in
/subversion/branches/diff-optimizations-bytes: ./ build/ build/ac-macros/
build/generator/templates/ notes/ notes/api-errata/ notes/api-errata/1.7/
subversion/include/ subversion/include/private/ subversion/libsvn_client...
Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql Sun Dec 12 16:43:42 2010
@@ -191,7 +191,8 @@ SELECT dav_cache FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
-- STMT_SELECT_DELETION_INFO
-SELECT nodes_base.presence, nodes_work.presence, nodes_work.moved_to
+SELECT nodes_base.presence, nodes_work.presence, nodes_work.moved_to,
+ nodes_work.op_depth
FROM nodes nodes_work
LEFT OUTER JOIN nodes nodes_base ON nodes_base.wc_id = nodes_work.wc_id
AND nodes_base.local_relpath = nodes_work.local_relpath
@@ -319,20 +320,15 @@ WHERE wc_id = ?1 AND local_relpath = ?2;
DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2;
--- STMT_DELETE_ACTUAL_NODE_WITHOUT_CHANGELIST
-DELETE FROM actual_node
-WHERE wc_id = ?1 AND local_relpath = ?2
- AND changelist IS NULL;
-
-- STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT
DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2
AND tree_conflict_data IS NULL;
--- STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE
+-- STMT_DELETE_CHILD_NODES_RECURSIVE
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3
- AND presence = 'not-present';
+ AND presence = ?4
-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST
UPDATE actual_node
@@ -386,10 +382,6 @@ WHERE wc_id = ?1 AND local_relpath = ?2
UPDATE nodes SET presence = ?3
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
--- STMT_UPDATE_NODE_BASE_PRESENCE_KIND
-UPDATE nodes SET presence = ?3, kind = ?4
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
-
-- STMT_UPDATE_NODE_WORKING_PRESENCE
UPDATE nodes SET presence = ?3
WHERE wc_id = ?1 AND local_relpath = ?2
@@ -525,6 +517,19 @@ SELECT wc_id, local_relpath, ?3 AS op_de
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
+-- STMT_INSERT_WORKING_NODE_FROM_NODE
+INSERT OR REPLACE INTO nodes (
+ wc_id, local_relpath, op_depth, parent_relpath, presence, kind, checksum,
+ changed_revision, changed_date, changed_author, depth, symlink_target,
+ translated_size, last_mod_time, properties)
+SELECT wc_id, local_relpath, ?3 AS op_depth, parent_relpath, ?4 AS presence,
+ kind, checksum, changed_revision, changed_date, changed_author, depth,
+ symlink_target, translated_size, last_mod_time, properties
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2
+ORDER BY op_depth DESC
+LIMIT 1;
+
-- STMT_INSERT_WORKING_NODE_FROM_BASE_COPY
INSERT INTO nodes (
wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
@@ -584,75 +589,6 @@ SELECT 1 FROM nodes WHERE wc_id = ?1 AND
AND op_depth = (SELECT MAX(op_depth) FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0);
-
--- STMT_COPY_NODES_ROW
-INSERT OR REPLACE INTO nodes (
- wc_id, local_relpath, op_depth, parent_relpath,
- repos_id, repos_path, revision, presence, /* moved_here, moved_to, */
- kind, properties, depth, checksum, symlink_target,
- changed_revision, changed_date, changed_author,
- translated_size, last_mod_time /* dav_cache, file_external */ )
-SELECT wc_id,
- ?4 /*dst_relpath*/,
- ?6 /*dst_op_depth*/,
- ?5 /*dst_parent_*/,
- repos_id, repos_path, revision, presence, /* moved_here, moved_to, */
- kind, properties, depth, checksum, symlink_target,
- changed_revision, changed_date, changed_author,
- translated_size, last_mod_time /* dav_cache, file_external */
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3;
-
--- STMT_COPY_NODES_AT_SAME_OP_DEPTH
-INSERT OR REPLACE INTO nodes (
- wc_id, local_relpath, op_depth, parent_relpath,
- repos_id, repos_path, revision, presence, /* moved_here, moved_to, */
- kind, properties, depth, checksum, symlink_target,
- changed_revision, changed_date, changed_author,
- translated_size, last_mod_time /* dav_cache, file_external */ )
-SELECT wc_id,
- ?4 /*dst_relpath*/ || SUBSTR(local_relpath, ?6 /*LEN(src_relpath)+1*/),
- ?5 /*dst_depth*/,
- ?4 /*dst_relpath*/ || SUBSTR(parent_relpath, ?6 /*LEN(src_relpath)+1*/),
- repos_id, repos_path, revision, presence, /* moved_here, moved_to, */
- kind, properties, depth, checksum, symlink_target,
- changed_revision, changed_date, changed_author,
- translated_size, last_mod_time /* dav_cache, file_external */
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3;
-
--- STMT_COPY_NODES_AT_GREATER_OP_DEPTH
-INSERT OR REPLACE INTO nodes (
- wc_id, local_relpath, op_depth, parent_relpath,
- repos_id, repos_path, revision, presence, /* moved_here, moved_to, */
- kind, properties, depth, checksum, symlink_target,
- changed_revision, changed_date, changed_author,
- translated_size, last_mod_time /* dav_cache, file_external */ )
-SELECT wc_id,
- ?4 /*dst_relpath*/ || SUBSTR(local_relpath, ?6 /*LEN(src_relpath)+1*/),
- op_depth + ?5 /*dst_depth*/ - ?3 /*src_depth*/,
- ?4 /*dst_relpath*/ || SUBSTR(parent_relpath, ?6 /*LEN(src_relpath)+1*/),
- repos_id, repos_path, revision, presence, /* moved_here, moved_to, */
- kind, properties, depth, checksum, symlink_target,
- changed_revision, changed_date, changed_author,
- translated_size, last_mod_time /* dav_cache, file_external */
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth > ?3;
-
--- STMT_COPY_ACTUAL_NODE_ROWS
-INSERT OR REPLACE INTO actual_node (
- wc_id, local_relpath, parent_relpath, properties,
- conflict_old, conflict_new, conflict_working,
- prop_reject, changelist, text_mod, tree_conflict_data )
-SELECT wc_id,
- ?4 /*dst_relpath*/ || SUBSTR(local_relpath, ?6 /*LEN(src_relpath)+1*/),
- ?5 /*dst_parent_*/ || SUBSTR(parent_relpath, ?7 /*LEN(src_parent_)+1*/),
- properties,
- conflict_old, conflict_new, conflict_working,
- prop_reject, changelist, text_mod, tree_conflict_data
-FROM actual_node
-WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#');
-
-- STMT_SELECT_ABSENT_NODES
SELECT local_relpath FROM nodes
WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
@@ -789,6 +725,13 @@ WHERE nodes_work.local_relpath = ?1
AND nodes_work.op_depth = (SELECT MAX(op_depth) FROM nodes
WHERE local_relpath = ?1 AND op_depth > 0);
+-- STMT_HAS_WORKING_NODES
+SELECT 1 FROM nodes WHERE op_depth > 0;
+
+-- STMT_UPDATE_CHECKSUM
+UPDATE nodes SET checksum = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3;
+
/* ------------------------------------------------------------------------- */
Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h Sun Dec 12 16:43:42 2010
@@ -124,12 +124,25 @@ extern "C" {
* The change from 19 to 20 introduces NODES and drops BASE_NODE and
* WORKING_NODE, op_depth is always 0 or 2.
*
+ * The change from 20 to 21 moved tree conflict storage from the
+ * parent to the conflicted node.
+ *
+ * The change from 21 to 22 moved tree conflict storage from
+ * conflict_data column to the tree_conflict_data column.
+ *
+ * The change from 22 to 23 introduced multi-layer op_depth processing for
+ * NODES.
+ *
* == 1.7.x shipped with format ???
*
* Please document any further format changes here.
*/
-#define SVN_WC__VERSION 22
+#define SVN_WC__VERSION 23
+
+#if SVN_WC__VERSION >= 23
+#define SVN_WC__OP_DEPTH
+#endif
/* Formats <= this have no concept of "revert text-base/props". */
#define SVN_WC__NO_REVERT_FILES 4
Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c Sun Dec 12 16:43:42 2010
@@ -299,7 +299,6 @@ scan_addition(svn_wc__db_status_t *statu
static svn_error_t *
scan_deletion(const char **base_del_relpath,
- svn_boolean_t *base_replaced,
const char **moved_to_relpath,
const char **work_del_relpath,
svn_wc__db_pdh_t *pdh,
@@ -2942,7 +2941,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
{
const char *base_del_relpath, *work_del_relpath;
- SVN_ERR(scan_deletion(&base_del_relpath, NULL, NULL, &work_del_relpath,
+ SVN_ERR(scan_deletion(&base_del_relpath, NULL, &work_del_relpath,
pdh, local_relpath, scratch_pool, scratch_pool));
if (work_del_relpath)
{
@@ -4436,31 +4435,42 @@ svn_wc__db_temp_op_set_dir_depth(svn_wc_
### Do we need to handle incomplete here? */
static svn_error_t *
-delete_not_present_children(svn_wc__db_pdh_t *pdh,
- const char *local_relpath,
- apr_pool_t *scratch_pool)
+remove_children(svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ svn_wc__db_status_t status,
+ apr_int64_t op_depth,
+ apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
-#ifdef SVN_WC__OP_DEPTH
- apr_int64_t op_depth = relpath_depth(local_relpath);
-#else
- apr_int64_t op_depth = 2; /* ### temporary op_depth */
-#endif
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isi", pdh->wcroot->wc_id,
+ STMT_DELETE_CHILD_NODES_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isit", pdh->wcroot->wc_id,
construct_like_arg(local_relpath,
scratch_pool),
- op_depth));
+ op_depth, presence_map, status));
SVN_ERR(svn_sqlite__step_done(stmt));
return SVN_NO_ERROR;
}
+static svn_error_t *
+db_working_actual_remove(svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool);
+
+static svn_error_t *
+info_below_working(svn_boolean_t *have_base,
+ svn_boolean_t *have_work,
+ svn_wc__db_status_t *status,
+ svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool);
+
/* Update the working node for LOCAL_ABSPATH setting presence=STATUS */
static svn_error_t *
-db_working_update_presence(svn_wc__db_status_t status,
+db_working_update_presence(apr_int64_t op_depth,
+ svn_wc__db_status_t status,
svn_wc__db_pdh_t *pdh,
const char *local_relpath,
apr_pool_t *scratch_pool)
@@ -4475,11 +4485,55 @@ db_working_update_presence(svn_wc__db_st
if (status == svn_wc__db_status_base_deleted)
{
- /* Switching to base-deleted is undoing an add/copy. If this
- was a copy then any children of the copy will now be
- not-present and should be removed. By this stage an add will
- have no children. */
- SVN_ERR(delete_not_present_children(pdh, local_relpath, scratch_pool));
+ /* Switching to base-deleted is undoing an add/copy. By this
+ stage an add will have no children. */
+#ifdef SVN_WC__OP_DEPTH
+ const apr_array_header_t *children;
+ apr_pool_t *iterpool;
+ int i;
+
+ /* Children of the copy will be marked deleted in the layer
+ above. */
+ SVN_ERR(remove_children(pdh, local_relpath,
+ svn_wc__db_status_base_deleted, op_depth + 1,
+ scratch_pool));
+
+ /* Children of the copy that overlay a lower level become
+ base_deleted, otherwise they get removed. */
+ SVN_ERR(gather_repo_children(&children, pdh, local_relpath, op_depth,
+ scratch_pool, scratch_pool));
+ iterpool = svn_pool_create(scratch_pool);
+ for (i = 0; i < children->nelts; ++i)
+ {
+ const char *name = APR_ARRAY_IDX(children, i, const char *);
+ const char *child_relpath;
+ svn_boolean_t below_base, below_work;
+ svn_wc__db_status_t below_status;
+
+ svn_pool_clear(iterpool);
+
+ child_relpath = svn_relpath_join(local_relpath, name, iterpool);
+ SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
+ pdh, child_relpath, iterpool));
+ if ((below_base || below_work)
+ && (below_status == svn_wc__db_status_normal
+ || below_status == svn_wc__db_status_added
+ || below_status == svn_wc__db_status_incomplete))
+ SVN_ERR(db_working_update_presence(op_depth,
+ svn_wc__db_status_base_deleted,
+ pdh, child_relpath, iterpool));
+ else
+ SVN_ERR(db_working_actual_remove(pdh, child_relpath, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+#else
+ /* If this was a copy then any children of the copy will now be
+ not-present and should be removed. */
+ SVN_ERR(remove_children(pdh, local_relpath,
+ svn_wc__db_status_not_present,
+ 2 /* ### temporary op_depth */,
+ scratch_pool));
+#endif
/* Reset the copyfrom in case this was a copy.
### What else should be reset? Properties? Or copy the node again? */
@@ -4535,7 +4589,19 @@ db_working_actual_remove(svn_wc__db_pdh_
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
- SVN_ERR(delete_not_present_children(pdh, local_relpath, scratch_pool));
+#ifndef SVN_WC__OP_DEPTH
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_not_present,
+ 2 /* ### temporary op_depth */, scratch_pool));
+#else
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_base_deleted,
+ op_depth + 1, scratch_pool));
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_normal,
+ op_depth, scratch_pool));
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_not_present,
+ op_depth, scratch_pool));
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_incomplete,
+ op_depth, scratch_pool));
+#endif
/* Postcondition: There are no NODES rows in this subtree, at same or
* greater op_depth. */
@@ -4586,8 +4652,13 @@ db_working_insert(svn_wc__db_status_t st
apr_int64_t op_depth = 2; /* ### temporary op_depth */
#endif
+#ifdef SVN_WC__OP_DEPTH
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_INSERT_WORKING_NODE_FROM_NODE));
+#else
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_INSERT_WORKING_NODE_FROM_BASE));
+#endif
SVN_ERR(svn_sqlite__bindf(stmt, "isit", pdh->wcroot->wc_id,
local_relpath, op_depth, presence_map, status));
SVN_ERR(svn_sqlite__insert(NULL, stmt));
@@ -4795,7 +4866,10 @@ temp_op_delete_txn(void *baton, svn_sqli
{
struct temp_op_delete_baton *b = baton;
svn_wc__db_status_t status, new_working_status;
- svn_boolean_t have_work, new_have_work;
+ svn_boolean_t have_work, add_work = FALSE, del_work = FALSE, mod_work = FALSE;
+#ifndef SVN_WC__OP_DEPTH
+ svn_boolean_t new_have_work;
+#endif
SVN_ERR(read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -4805,8 +4879,10 @@ temp_op_delete_txn(void *baton, svn_sqli
b->pdh, b->local_relpath,
scratch_pool, scratch_pool));
+#ifndef SVN_WC__OP_DEPTH
new_have_work = have_work;
new_working_status = status;
+#endif
if (!have_work)
{
@@ -4814,13 +4890,17 @@ temp_op_delete_txn(void *baton, svn_sqli
if (status == svn_wc__db_status_normal
|| status == svn_wc__db_status_incomplete)
{
+#ifdef SVN_WC__OP_DEPTH
+ add_work = TRUE;
+#else
new_have_work = TRUE;
new_working_status = svn_wc__db_status_base_deleted;
+#endif
}
}
else if (status == svn_wc__db_status_added)
{
- /* ADD/COPY-HERE/MOVE-HERE */
+ /* ADD/COPY-HERE/MOVE-HERE that could be a replace */
svn_boolean_t add_or_root_of_copy;
SVN_ERR(is_add_or_root_of_copy(&add_or_root_of_copy,
@@ -4833,24 +4913,51 @@ temp_op_delete_txn(void *baton, svn_sqli
SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
b->pdh, b->local_relpath, scratch_pool));
+#ifdef SVN_WC__OP_DEPTH
+ if ((below_base || below_work)
+ && below_status != svn_wc__db_status_not_present)
+ mod_work = TRUE;
+ else
+ del_work = TRUE;
+#else
if (below_base && below_status != svn_wc__db_status_not_present)
new_working_status = svn_wc__db_status_base_deleted;
else
new_have_work = FALSE;
+#endif
}
else
- new_working_status = svn_wc__db_status_not_present;
+ {
+#ifdef SVN_WC__OP_DEPTH
+ add_work = TRUE;
+#else
+ new_working_status = svn_wc__db_status_not_present;
+#endif
+ }
}
else if (status == svn_wc__db_status_incomplete)
{
svn_boolean_t add_or_root_of_copy;
SVN_ERR(is_add_or_root_of_copy(&add_or_root_of_copy,
b->pdh, b->local_relpath, scratch_pool));
+#ifdef SVN_WC__OP_DEPTH
+ if (add_or_root_of_copy)
+ del_work = TRUE;
+ else
+ add_work = TRUE;
+#else
if (add_or_root_of_copy)
new_have_work = FALSE;
+#endif
}
- if (!new_have_work && have_work)
+#ifndef SVN_WC__OP_DEPTH
+ del_work = !new_have_work && have_work;
+ add_work = new_have_work && !have_work;
+ mod_work = new_have_work && have_work && new_working_status != status;
+#endif
+
+ if (del_work)
{
SVN_ERR(db_working_actual_remove(b->pdh, b->local_relpath, scratch_pool));
@@ -4858,15 +4965,21 @@ temp_op_delete_txn(void *baton, svn_sqli
SVN_ERR(svn_wc__db_temp_forget_directory(b->db, b->local_abspath,
scratch_pool));
}
- else if (new_have_work && !have_work)
+ else if (add_work)
{
+#ifdef SVN_WC__OP_DEPTH
+ new_working_status = svn_wc__db_status_base_deleted;
+#endif
SVN_ERR(db_working_insert(new_working_status, b->pdh, b->local_relpath,
scratch_pool));
}
- else if (new_have_work && have_work
- && new_working_status != status)
+ else if (mod_work)
{
- SVN_ERR(db_working_update_presence(new_working_status, b->pdh,
+#ifdef SVN_WC__OP_DEPTH
+ new_working_status = svn_wc__db_status_base_deleted;
+#endif
+ SVN_ERR(db_working_update_presence(relpath_depth(b->local_relpath),
+ new_working_status, b->pdh,
b->local_relpath, scratch_pool));
}
else
@@ -5803,7 +5916,7 @@ svn_wc__db_global_relocate(svn_wc__db_t
if (status == svn_wc__db_status_deleted)
{
const char *work_del_relpath;
- SVN_ERR(scan_deletion(NULL, NULL, NULL, &work_del_relpath,
+ SVN_ERR(scan_deletion(NULL, NULL, &work_del_relpath,
pdh, local_dir_relpath,
scratch_pool, scratch_pool));
if (work_del_relpath)
@@ -6866,7 +6979,8 @@ svn_wc__db_scan_addition(svn_wc__db_stat
svn_wc__db_pdh_t *pdh;
const char *local_relpath;
const char *op_root_relpath;
- apr_int64_t repos_id, original_repos_id;
+ apr_int64_t repos_id = INVALID_REPOS_ID;
+ apr_int64_t original_repos_id = INVALID_REPOS_ID;
apr_int64_t *repos_id_p
= (repos_root_url || repos_uuid) ? &repos_id : NULL;
apr_int64_t *original_repos_id_p
@@ -6889,6 +7003,7 @@ svn_wc__db_scan_addition(svn_wc__db_stat
result_pool);
/* REPOS_ID must be valid if requested; ORIGINAL_REPOS_ID need not be. */
SVN_ERR_ASSERT(repos_id_p == NULL || repos_id != INVALID_REPOS_ID);
+
SVN_ERR(fetch_repos_info(repos_root_url, repos_uuid, pdh->wcroot->sdb,
repos_id, result_pool));
SVN_ERR(fetch_repos_info(original_root_url, original_uuid,
@@ -6903,7 +7018,6 @@ svn_wc__db_scan_addition(svn_wc__db_stat
* DB+LOCAL_ABSPATH, and outputting relpaths instead of abspaths. */
static svn_error_t *
scan_deletion(const char **base_del_relpath,
- svn_boolean_t *base_replaced,
const char **moved_to_relpath,
const char **work_del_relpath,
svn_wc__db_pdh_t *pdh,
@@ -6917,12 +7031,13 @@ scan_deletion(const char **base_del_relp
svn_boolean_t child_has_base = FALSE;
svn_boolean_t found_moved_to = FALSE;
svn_wc__db_wcroot_t *wcroot = pdh->wcroot;
+#ifdef SVN_WC__OP_DEPTH
+ apr_int64_t local_op_depth, op_depth;
+#endif
/* Initialize all the OUT parameters. */
if (base_del_relpath != NULL)
*base_del_relpath = NULL;
- if (base_replaced != NULL)
- *base_replaced = FALSE; /* becomes TRUE when we know for sure. */
if (moved_to_relpath != NULL)
*moved_to_relpath = NULL;
if (work_del_relpath != NULL)
@@ -6993,7 +7108,7 @@ scan_deletion(const char **base_del_relp
}
/* We need the presence of the WORKING node. Note that legal values
- are: normal, not-present, base-deleted. */
+ are: normal, not-present, base-deleted, incomplete. */
work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
/* The starting node should be deleted. */
@@ -7006,6 +7121,8 @@ scan_deletion(const char **base_del_relp
path_for_error_message(wcroot,
local_relpath,
scratch_pool));
+
+ /* ### incomplete not handled */
SVN_ERR_ASSERT(work_presence == svn_wc__db_status_normal
|| work_presence == svn_wc__db_status_not_present
|| work_presence == svn_wc__db_status_base_deleted);
@@ -7043,16 +7160,6 @@ scan_deletion(const char **base_del_relp
/* If a BASE node is marked as not-present, then we'll ignore
it within this function. That status is simply a bookkeeping
gimmick, not a real node that may have been deleted. */
-
- /* If we're looking at a present BASE node, *and* there is a
- WORKING node (present or deleted), then a replacement has
- occurred here or in an ancestor. */
- if (base_replaced != NULL
- && base_presence == svn_wc__db_status_normal
- && work_presence != svn_wc__db_status_base_deleted)
- {
- *base_replaced = TRUE;
- }
}
/* Only grab the nearest ancestor. */
@@ -7074,12 +7181,22 @@ scan_deletion(const char **base_del_relp
svn_sqlite__column_text(stmt, 2, NULL));
}
+#ifdef SVN_WC__OP_DEPTH
+ op_depth = svn_sqlite__column_int64(stmt, 3);
+ if (current_relpath == local_relpath)
+ local_op_depth = op_depth;
+
+ if (work_del_relpath && !work_del_relpath[0]
+ && ((op_depth < local_op_depth && op_depth > 0)
+ || child_presence == svn_wc__db_status_not_present))
+#else
if (work_del_relpath != NULL
&& work_presence == svn_wc__db_status_normal
&& child_presence == svn_wc__db_status_not_present)
- {
/* Parent is normal, but child was deleted. Therefore, the child
is the root of a WORKING subtree deletion. */
+#endif
+ {
*work_del_relpath = apr_pstrdup(result_pool, child_relpath);
}
@@ -7105,7 +7222,6 @@ scan_deletion(const char **base_del_relp
svn_error_t *
svn_wc__db_scan_deletion(const char **base_del_abspath,
- svn_boolean_t *base_replaced,
const char **moved_to_abspath,
const char **work_del_abspath,
svn_wc__db_t *db,
@@ -7124,7 +7240,7 @@ svn_wc__db_scan_deletion(const char **ba
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- SVN_ERR(scan_deletion(&base_del_relpath, base_replaced, &moved_to_relpath,
+ SVN_ERR(scan_deletion(&base_del_relpath, &moved_to_relpath,
&work_del_relpath,
pdh, local_relpath, result_pool, scratch_pool));
Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.h?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.h Sun Dec 12 16:43:42 2010
@@ -1943,8 +1943,7 @@ svn_wc__db_scan_addition(svn_wc__db_stat
the deleted node.
In this example, BASE_DEL_ABSPATH will bet set to B/W. That is the root of
- the BASE tree (implicitly) deleted by the replacement. BASE_REPLACED will
- be set to TRUE since B/W replaces the BASE node at B/W. WORK_DEL_ABSPATH
+ the BASE tree (implicitly) deleted by the replacement. WORK_DEL_ABSPATH
will be set to the subtree deleted within the replacement; in this case,
B/W/D. No move-away took place, so MOVED_TO_ABSPATH is set to NULL.
@@ -1954,14 +1953,12 @@ svn_wc__db_scan_addition(svn_wc__db_stat
post-move, but that is not known or reported by this function.
If BASE does not have a B/W, then the WORKING B/W is not a replacement,
- but a simple add/copy/move-here. BASE_DEL_ABSPATH will be set to NULL,
- and BASE_REPLACED will be set to FALSE.
+ but a simple add/copy/move-here. BASE_DEL_ABSPATH will be set to NULL.
If B/W/D does not exist in the WORKING tree (we're only talking about a
deletion of nodes of the BASE tree), then deleting B/W/D would have marked
the subtree for deletion. BASE_DEL_ABSPATH will refer to B/W/D,
- BASE_REPLACED will be FALSE, MOVED_TO_ABSPATH will be NULL, and
- WORK_DEL_ABSPATH will be NULL.
+ MOVED_TO_ABSPATH will be NULL, and WORK_DEL_ABSPATH will be NULL.
If the BASE node B/W/D was moved instead of deleted, then MOVED_TO_ABSPATH
would indicate the target location (and other OUT values as above).
@@ -2009,11 +2006,6 @@ svn_wc__db_scan_addition(svn_wc__db_stat
BASE_DEL_ABSPATH will specify the nearest ancestor of the explicit or
implicit deletion (if any) that applies to the BASE tree.
- BASE_REPLACED will specify whether the node at BASE_DEL_ABSPATH has
- been replaced (shadowed) by nodes in the WORKING tree. If no BASE
- deletion has occurred (BASE_DEL_ABSPATH is NULL, meaning the deletion
- is confined to the WORKING TREE), then BASE_REPLACED will be FALSE.
-
MOVED_TO_ABSPATH will specify the nearest ancestor that has moved-away,
if any. If no ancestors have been moved-away, then this is set to NULL.
@@ -2033,7 +2025,6 @@ svn_wc__db_scan_addition(svn_wc__db_stat
*/
svn_error_t *
svn_wc__db_scan_deletion(const char **base_del_abspath,
- svn_boolean_t *base_replaced,
const char **moved_to_abspath,
const char **work_del_abspath,
svn_wc__db_t *db,
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/blame-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/blame-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/blame-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/blame-cmd.c Sun Dec 12 16:43:42 2010
@@ -203,11 +203,11 @@ blame_receiver(void *baton,
we may need to adjust this. */
if (merged_revision < revision)
{
- svn_stream_printf(out, pool, "G ");
+ SVN_ERR(svn_stream_printf(out, pool, "G "));
use_merged = TRUE;
}
else
- svn_stream_printf(out, pool, " ");
+ SVN_ERR(svn_stream_printf(out, pool, " "));
}
if (use_merged)
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/cl.h?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/cl.h (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/cl.h Sun Dec 12 16:43:42 2010
@@ -817,6 +817,11 @@ svn_cl__opt_parse_path(svn_opt_revision_
const char *path,
apr_pool_t *pool);
+/* Return an error if TARGETS contains a mixture of URLs and paths; otherwise
+ * return SVN_NO_ERROR. */
+svn_error_t *
+svn_cl__assert_homogeneous_target_type(const apr_array_header_t *targets);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/copy-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/copy-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/copy-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/copy-cmd.c Sun Dec 12 16:43:42 2010
@@ -78,8 +78,10 @@ svn_cl__copy(apr_getopt_t *os,
SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
- /* Figure out which type of trace editor to use.
- If the src_paths are not homogeneous, setup_copy will return an error. */
+ /* Figure out which type of notification to use.
+ (There is no need to check that the src paths are homogeneous;
+ svn_client_copy6() through its subroutine try_copy() will return an
+ error if they are not.) */
src_path = APR_ARRAY_IDX(targets, 0, const char *);
srcs_are_urls = svn_path_is_url(src_path);
dst_path = APR_ARRAY_IDX(targets, targets->nelts - 1, const char *);
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/delete-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/delete-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/delete-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/delete-cmd.c Sun Dec 12 16:43:42 2010
@@ -48,7 +48,6 @@ svn_cl__delete(apr_getopt_t *os,
apr_array_header_t *targets;
svn_error_t *err;
svn_boolean_t is_url;
- int i;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -57,17 +56,8 @@ svn_cl__delete(apr_getopt_t *os,
if (! targets->nelts)
return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
- /* Check that all targets are of the same type. */
+ SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
is_url = svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *));
- for (i = 1; i < targets->nelts; i++)
- {
- const char *target = APR_ARRAY_IDX(targets, i, const char *);
- if (is_url != svn_path_is_url(target))
- return svn_error_return(
- svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Cannot mix repository and working copy "
- "targets")));
- }
if (! is_url)
{
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/diff-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/diff-cmd.c Sun Dec 12 16:43:42 2010
@@ -260,7 +260,7 @@ svn_cl__diff(apr_getopt_t *os,
}
else
{
- svn_boolean_t working_copy_present = FALSE, url_present = FALSE;
+ svn_boolean_t working_copy_present;
/* The 'svn diff [-r N[:M]] [TARGET[@REV]...]' case matches. */
@@ -272,25 +272,14 @@ svn_cl__diff(apr_getopt_t *os,
old_target = "";
new_target = "";
- /* Check to see if at least one of our paths is a working copy
- path. */
- for (i = 0; i < targets->nelts; ++i)
- {
- const char *path = APR_ARRAY_IDX(targets, i, const char *);
- if (! svn_path_is_url(path))
- working_copy_present = TRUE;
- else
- url_present = TRUE;
- }
+ SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
- if (url_present && working_copy_present)
- return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Cannot mix repository and working copy "
- "targets"));
+ working_copy_present = ! svn_path_is_url(APR_ARRAY_IDX(targets, 0,
+ const char *));
if (opt_state->start_revision.kind == svn_opt_revision_unspecified
&& working_copy_present)
- opt_state->start_revision.kind = svn_opt_revision_base;
+ opt_state->start_revision.kind = svn_opt_revision_base;
if (opt_state->end_revision.kind == svn_opt_revision_unspecified)
opt_state->end_revision.kind = working_copy_present
? svn_opt_revision_working : svn_opt_revision_head;
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/info-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/info-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/info-cmd.c Sun Dec 12 16:43:42 2010
@@ -462,25 +462,19 @@ print_info(void *baton,
svn_cl__node_description(info->tree_conflict->src_right_version,
info->repos_root_URL, pool);
- svn_cmdline_printf(pool,
- "%s: %s\n",
- _("Tree conflict"),
- desc);
+ SVN_ERR(svn_cmdline_printf(pool, "%s: %s\n", _("Tree conflict"), desc));
if (src_left_version)
- svn_cmdline_printf(pool,
- " %s: %s\n",
- _("Source left"), /* (1) */
- src_left_version);
+ SVN_ERR(svn_cmdline_printf(pool, " %s: %s\n",
+ _("Source left"), /* (1) */
+ src_left_version));
/* (1): Sneaking in a space in "Source left" so that it is the
* same length as "Source right" while it still starts in the same
* column. That's just a tiny tweak in the English `svn'. */
if (src_right_version)
- svn_cmdline_printf(pool,
- " %s: %s\n",
- _("Source right"),
- src_right_version);
+ SVN_ERR(svn_cmdline_printf(pool, " %s: %s\n", _("Source right"),
+ src_right_version));
}
/* Print extra newline separator. */
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/lock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/lock-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/lock-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/lock-cmd.c Sun Dec 12 16:43:42 2010
@@ -89,8 +89,6 @@ svn_cl__lock(apr_getopt_t *os,
svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
apr_array_header_t *targets;
const char *comment;
- svn_boolean_t wc_present = FALSE, url_present = FALSE;
- int i;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -100,21 +98,7 @@ svn_cl__lock(apr_getopt_t *os,
if (! targets->nelts)
return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
- /* Check to see if at least one of our paths is a working copy
- * path or a repository url. */
- for (i = 0; i < targets->nelts; ++i)
- {
- const char *target = APR_ARRAY_IDX(targets, i, const char *);
- if (! svn_path_is_url(target))
- wc_present = TRUE;
- else
- url_present = TRUE;
- }
-
- if (url_present && wc_present)
- return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Cannot mix repository and working copy "
- "targets"));
+ SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
/* Get comment. */
SVN_ERR(get_comment(&comment, ctx, opt_state, pool));
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/mergeinfo-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/mergeinfo-cmd.c Sun Dec 12 16:43:42 2010
@@ -48,9 +48,9 @@ print_log_rev(void *baton,
apr_pool_t *pool)
{
if (log_entry->non_inheritable)
- svn_cmdline_printf(pool, "r%ld*\n", log_entry->revision);
+ SVN_ERR(svn_cmdline_printf(pool, "r%ld*\n", log_entry->revision));
else
- svn_cmdline_printf(pool, "r%ld\n", log_entry->revision);
+ SVN_ERR(svn_cmdline_printf(pool, "r%ld\n", log_entry->revision));
return SVN_NO_ERROR;
}
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/mkdir-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/mkdir-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/mkdir-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/mkdir-cmd.c Sun Dec 12 16:43:42 2010
@@ -56,6 +56,8 @@ svn_cl__mkdir(apr_getopt_t *os,
if (! targets->nelts)
return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+ SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
+
if (! svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *)))
{
ctx->log_msg_func3 = NULL;
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/propget-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/propget-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/propget-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/propget-cmd.c Sun Dec 12 16:43:42 2010
@@ -155,7 +155,7 @@ print_properties(svn_stream_t *out,
apr_hash_t *hash = apr_hash_make(iterpool);
apr_hash_set(hash, pname_utf8, APR_HASH_KEY_STRING, propval);
- svn_cl__print_prop_hash(out, hash, FALSE, iterpool);
+ SVN_ERR(svn_cl__print_prop_hash(out, hash, FALSE, iterpool));
}
else
{
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/status.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/status.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/status.c Sun Dec 12 16:43:42 2010
@@ -167,8 +167,10 @@ print_status(const char *path,
old_tree_conflict = svn_wc__cd2_to_cd(tree_conflict, pool);
tree_status_code = 'C';
- svn_cl__get_human_readable_tree_conflict_description(
- &desc, old_tree_conflict, pool);
+ SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
+ &desc,
+ old_tree_conflict,
+ pool));
tree_desc_line = apr_psprintf(pool, "\n > %s", desc);
(*tree_conflicts)++;
}
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/unlock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/unlock-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/unlock-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/unlock-cmd.c Sun Dec 12 16:43:42 2010
@@ -49,8 +49,6 @@ svn_cl__unlock(apr_getopt_t *os,
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;
apr_array_header_t *targets;
- svn_boolean_t wc_present = FALSE, url_present = FALSE;
- int i;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -62,22 +60,7 @@ svn_cl__unlock(apr_getopt_t *os,
SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
- /* Check to see if at least one of our paths is a working copy
- * path or a repository url. */
- for (i = 0; i < targets->nelts; ++i)
- {
- const char *target = APR_ARRAY_IDX(targets, i, const char *);
-
- if (! svn_path_is_url(target))
- wc_present = TRUE;
- else
- url_present = TRUE;
- }
-
- if (url_present && wc_present)
- return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Cannot mix repository and working copy "
- "targets"));
+ SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
return svn_error_return(
svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/update-cmd.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/update-cmd.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/update-cmd.c Sun Dec 12 16:43:42 2010
@@ -110,6 +110,7 @@ svn_cl__update(apr_getopt_t *os,
svn_boolean_t depth_is_sticky;
struct svn_cl__check_externals_failed_notify_baton nwb;
apr_array_header_t *result_revs;
+ int i;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -120,29 +121,15 @@ svn_cl__update(apr_getopt_t *os,
SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
- /* If any targets are URLs, notify that we're skipping them and remove
- them from TARGETS. Although svn_client_update4() would skip them
- anyway, we don't want to pass invalid targets to it, and especially
- not to print_update_summary(). */
- {
- apr_array_header_t *new_targets
- = apr_array_make(scratch_pool, targets->nelts, sizeof(const char *));
- int i;
-
- for (i = 0; i < targets->nelts; i++)
- {
- const char *target = APR_ARRAY_IDX(targets, i, const char *);
-
- if (svn_path_is_url(target))
- ctx->notify_func2(ctx->notify_baton2,
- svn_wc_create_notify_url(
- target, svn_wc_notify_skip, scratch_pool),
- scratch_pool);
- else
- APR_ARRAY_PUSH(new_targets, const char *) = target;
- }
- targets = new_targets;
- }
+ /* If any targets are URLs, display error message and exit. */
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+ if (svn_path_is_url(target))
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("'%s' is not a local path"), target);
+ }
/* If using changelists, convert targets into a set of paths that
match the specified changelist(s). */
Modified: subversion/branches/diff-optimizations-bytes/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svn/util.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svn/util.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svn/util.c Sun Dec 12 16:43:42 2010
@@ -61,6 +61,7 @@
#include "private/svn_token.h"
#include "private/svn_opt_private.h"
+#include "private/svn_client_private.h"
@@ -1345,3 +1346,16 @@ svn_cl__opt_parse_path(svn_opt_revision_
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_cl__assert_homogeneous_target_type(const apr_array_header_t *targets)
+{
+ svn_error_t *err;
+
+ err = svn_client__assert_homogeneous_target_type(targets);
+ if (err && err->apr_err == SVN_ERR_ILLEGAL_TARGET)
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
+ _("Cannot mix repository and working copy "
+ "targets"));
+ return err;
+}
Modified: subversion/branches/diff-optimizations-bytes/subversion/svnadmin/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svnadmin/main.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svnadmin/main.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svnadmin/main.c Sun Dec 12 16:43:42 2010
@@ -1594,7 +1594,7 @@ main(int argc, const char *argv[])
if (argc <= 1)
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1621,7 +1621,7 @@ main(int argc, const char *argv[])
break;
else if (apr_err)
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1734,7 +1734,7 @@ main(int argc, const char *argv[])
break;
default:
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1768,7 +1768,7 @@ main(int argc, const char *argv[])
{
svn_error_clear(svn_cmdline_fprintf(stderr, pool,
_("subcommand argument required\n")));
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1786,7 +1786,7 @@ main(int argc, const char *argv[])
svn_error_clear(svn_cmdline_fprintf(stderr, pool,
_("Unknown command: '%s'\n"),
first_arg_utf8));
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1837,7 +1837,7 @@ main(int argc, const char *argv[])
pool);
svn_opt_format_option(&optstr, badopt, FALSE, pool);
if (subcommand->name[0] == '-')
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
else
svn_error_clear(svn_cmdline_fprintf(stderr, pool
, _("Subcommand '%s' doesn't accept option '%s'\n"
Modified: subversion/branches/diff-optimizations-bytes/subversion/svndumpfilter/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svndumpfilter/main.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svndumpfilter/main.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svndumpfilter/main.c Sun Dec 12 16:43:42 2010
@@ -1294,7 +1294,7 @@ main(int argc, const char *argv[])
if (argc <= 1)
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1320,7 +1320,7 @@ main(int argc, const char *argv[])
break;
else if (apr_err)
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1359,7 +1359,7 @@ main(int argc, const char *argv[])
break;
default:
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1394,7 +1394,7 @@ main(int argc, const char *argv[])
svn_error_clear(svn_cmdline_fprintf
(stderr, pool,
_("Subcommand argument required\n")));
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1414,7 +1414,7 @@ main(int argc, const char *argv[])
svn_error_clear(svn_cmdline_fprintf(stderr, pool,
_("Unknown command: '%s'\n"),
first_arg_utf8));
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1496,7 +1496,7 @@ main(int argc, const char *argv[])
pool);
svn_opt_format_option(&optstr, badopt, FALSE, pool);
if (subcommand->name[0] == '-')
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
else
svn_error_clear(svn_cmdline_fprintf
(stderr, pool,
Modified: subversion/branches/diff-optimizations-bytes/subversion/svnlook/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svnlook/main.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svnlook/main.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svnlook/main.c Sun Dec 12 16:43:42 2010
@@ -1841,6 +1841,24 @@ warning_func(void *baton,
}
+/* Return an error if the number of arguments (excluding the repository
+ * argument) is not NUM_ARGS. NUM_ARGS must be 0 or 1. The arguments
+ * are assumed to be found in OPT_STATE->arg1 and OPT_STATE->arg2. */
+static svn_error_t *
+check_number_of_args(struct svnlook_opt_state *opt_state,
+ int num_args)
+{
+ if ((num_args == 0 && opt_state->arg1 != NULL)
+ || (num_args == 1 && opt_state->arg2 != NULL))
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments given"));
+ if ((num_args == 1 && opt_state->arg1 == NULL))
+ return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
+ _("Missing repository path argument"));
+ return SVN_NO_ERROR;
+}
+
+
/* Factory function for the context baton. */
static svn_error_t *
get_ctxt_baton(svnlook_ctxt_t **baton_p,
@@ -1887,6 +1905,8 @@ subcommand_author(apr_getopt_t *os, void
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_author(c, pool));
return SVN_NO_ERROR;
@@ -1899,10 +1919,7 @@ subcommand_cat(apr_getopt_t *os, void *b
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
- if (opt_state->arg1 == NULL)
- return svn_error_createf
- (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("Missing repository path argument"));
+ SVN_ERR(check_number_of_args(opt_state, 1));
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_cat(c, opt_state->arg1, pool));
@@ -1916,6 +1933,8 @@ subcommand_changed(apr_getopt_t *os, voi
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_changed(c, pool));
return SVN_NO_ERROR;
@@ -1928,6 +1947,8 @@ subcommand_date(apr_getopt_t *os, void *
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_date(c, pool));
return SVN_NO_ERROR;
@@ -1940,6 +1961,8 @@ subcommand_diff(apr_getopt_t *os, void *
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_diff(c, pool));
return SVN_NO_ERROR;
@@ -1952,6 +1975,8 @@ subcommand_dirschanged(apr_getopt_t *os,
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_dirs_changed(c, pool));
return SVN_NO_ERROR;
@@ -1964,10 +1989,7 @@ subcommand_filesize(apr_getopt_t *os, vo
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
- if (opt_state->arg1 == NULL)
- return svn_error_createf
- (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("Missing repository path argument"));
+ SVN_ERR(check_number_of_args(opt_state, 1));
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_filesize(c, opt_state->arg1, pool));
@@ -2012,10 +2034,11 @@ subcommand_history(apr_getopt_t *os, voi
{
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
- const char *path = "/";
+ const char *path = (opt_state->arg1 ? opt_state->arg1 : "/");
- if (opt_state->arg1)
- path = opt_state->arg1;
+ if (opt_state->arg2 != NULL)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments given"));
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_history(c, path, pool));
@@ -2029,18 +2052,13 @@ subcommand_lock(apr_getopt_t *os, void *
{
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
- const char *path;
svn_lock_t *lock;
- if (opt_state->arg1)
- path = opt_state->arg1;
- else
- return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("Missing path argument"));
+ SVN_ERR(check_number_of_args(opt_state, 1));
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
- SVN_ERR(svn_fs_get_lock(&lock, c->fs, path, pool));
+ SVN_ERR(svn_fs_get_lock(&lock, c->fs, opt_state->arg1, pool));
if (lock)
{
@@ -2078,6 +2096,8 @@ subcommand_info(apr_getopt_t *os, void *
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_author(c, pool));
SVN_ERR(do_date(c, pool));
@@ -2092,6 +2112,8 @@ subcommand_log(apr_getopt_t *os, void *b
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_log(c, FALSE, pool));
return SVN_NO_ERROR;
@@ -2117,6 +2139,10 @@ subcommand_pget(apr_getopt_t *os, void *
(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
_("Missing propname or repository path argument"));
}
+ if ((opt_state->revprop && opt_state->arg2 != NULL)
+ || os->ind < os->argc)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments given"));
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_pget(c, opt_state->arg1,
@@ -2131,10 +2157,7 @@ subcommand_plist(apr_getopt_t *os, void
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
- if (!opt_state->revprop && opt_state->arg1 == NULL)
- return svn_error_create
- (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("Missing repository path argument"));
+ SVN_ERR(check_number_of_args(opt_state, opt_state->revprop ? 0 : 1));
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_plist(c, opt_state->revprop ? NULL : opt_state->arg1,
@@ -2149,6 +2172,10 @@ subcommand_tree(apr_getopt_t *os, void *
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ if (opt_state->arg2 != NULL)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Too many arguments given"));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(do_tree(c, opt_state->arg1 ? opt_state->arg1 : "",
opt_state->show_ids, opt_state->full_paths,
@@ -2163,6 +2190,8 @@ subcommand_youngest(apr_getopt_t *os, vo
struct svnlook_opt_state *opt_state = baton;
svnlook_ctxt_t *c;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(svn_cmdline_printf(pool, "%ld\n", c->rev_id));
return SVN_NO_ERROR;
@@ -2176,6 +2205,8 @@ subcommand_uuid(apr_getopt_t *os, void *
svnlook_ctxt_t *c;
const char *uuid;
+ SVN_ERR(check_number_of_args(opt_state, 0));
+
SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
SVN_ERR(svn_fs_get_uuid(c->fs, &uuid, pool));
SVN_ERR(svn_cmdline_printf(pool, "%s\n", uuid));
@@ -2230,7 +2261,7 @@ main(int argc, const char *argv[])
if (argc <= 1)
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -2255,7 +2286,7 @@ main(int argc, const char *argv[])
break;
else if (apr_err)
{
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -2355,7 +2386,7 @@ main(int argc, const char *argv[])
break;
default:
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
@@ -2397,7 +2428,7 @@ main(int argc, const char *argv[])
svn_error_clear
(svn_cmdline_fprintf(stderr, pool,
_("Subcommand argument required\n")));
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -2417,7 +2448,7 @@ main(int argc, const char *argv[])
(svn_cmdline_fprintf(stderr, pool,
_("Unknown command: '%s'\n"),
first_arg_utf8));
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -2449,7 +2480,7 @@ main(int argc, const char *argv[])
svn_error_clear
(svn_cmdline_fprintf(stderr, pool,
_("Repository argument required\n")));
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -2504,7 +2535,7 @@ main(int argc, const char *argv[])
pool);
svn_opt_format_option(&optstr, badopt, FALSE, pool);
if (subcommand->name[0] == '-')
- subcommand_help(NULL, NULL, pool);
+ SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
else
svn_error_clear
(svn_cmdline_fprintf
Modified: subversion/branches/diff-optimizations-bytes/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svnrdump/dump_editor.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svnrdump/dump_editor.c Sun Dec 12 16:43:42 2010
@@ -207,8 +207,8 @@ dump_props(struct dump_edit_baton *eb,
SVN_ERR(svn_stream_printf(eb->stream, pool, "\n\n"));
/* Cleanup so that data is never dumped twice. */
- svn_hash__clear(eb->props, eb->pool);
- svn_hash__clear(eb->deleted_props, eb->pool);
+ SVN_ERR(svn_hash__clear(eb->props, eb->pool));
+ SVN_ERR(svn_hash__clear(eb->deleted_props, eb->pool));
if (trigger_var)
*trigger_var = FALSE;
}
@@ -525,7 +525,7 @@ close_directory(void *dir_baton,
FALSE, NULL, SVN_INVALID_REVNUM, pool));
}
- svn_hash__clear(db->deleted_entries, pool);
+ SVN_ERR(svn_hash__clear(db->deleted_entries, pool));
return SVN_NO_ERROR;
}
@@ -725,7 +725,7 @@ apply_textdelta(void *file_baton, const
eb->dump_text = TRUE;
eb->base_checksum = apr_pstrdup(eb->pool, base_checksum);
- svn_stream_close(delta_filestream);
+ SVN_ERR(svn_stream_close(delta_filestream));
/* The actual writing takes place when this function has
finished. Set handler and handler_baton now so for
@@ -806,8 +806,8 @@ close_file(void *file_baton,
/* Cleanup */
eb->dump_props = FALSE;
- svn_hash__clear(eb->props, eb->pool);
- svn_hash__clear(eb->deleted_props, eb->pool);
+ SVN_ERR(svn_hash__clear(eb->props, eb->pool));
+ SVN_ERR(svn_hash__clear(eb->deleted_props, eb->pool));
}
/* Dump the text */
Modified: subversion/branches/diff-optimizations-bytes/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/svnrdump/svnrdump.c?rev=1044847&r1=1044846&r2=1044847&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/svnrdump/svnrdump.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/svnrdump/svnrdump.c Sun Dec 12 16:43:42 2010
@@ -74,33 +74,40 @@ static svn_opt_subcommand_t dump_cmd, lo
enum svn_svnrdump__longopt_t
{
opt_config_dir = SVN_OPT_FIRST_LONGOPT_ID,
+ opt_config_option,
opt_auth_username,
opt_auth_password,
- opt_non_interactive,
opt_auth_nocache,
+ opt_non_interactive,
+ opt_incremental,
opt_version,
- opt_config_option,
};
+#define SVN_SVNRDUMP__BASE_OPTIONS opt_config_dir, \
+ opt_config_option, \
+ opt_auth_username, \
+ opt_auth_password, \
+ opt_auth_nocache, \
+ opt_non_interactive
+
static const svn_opt_subcommand_desc2_t svnrdump__cmd_table[] =
- {
- { "dump", dump_cmd, { 0 },
- N_("usage: svnrdump dump URL [-r LOWER[:UPPER]]\n\n"
- "Dump revisions LOWER to UPPER of repository at remote URL "
- "to stdout in a 'dumpfile' portable format.\n"
- "If only LOWER is given, dump that one revision.\n"),
- { 0 } },
- { "load", load_cmd, { 0 },
- N_("usage: svnrdump load URL\n\n"
- "Load a 'dumpfile' given on stdin to a repository "
- "at remote URL.\n"),
- { 0 } },
- { "help", 0, { "?", "h" },
- N_("usage: svnrdump help [SUBCOMMAND...]\n\n"
- "Describe the usage of this program or its subcommands.\n"),
- { 0 } },
- { NULL, NULL, { 0 }, NULL, { 0 } }
- };
+{
+ { "dump", dump_cmd, { 0 },
+ N_("usage: svnrdump dump URL [-r LOWER[:UPPER]]\n\n"
+ "Dump revisions LOWER to UPPER of repository at remote URL to stdout\n"
+ "in a 'dumpfile' portable format. If only LOWER is given, dump that\n"
+ "one revision.\n"),
+ { 'r', 'q', opt_incremental, SVN_SVNRDUMP__BASE_OPTIONS } },
+ { "load", load_cmd, { 0 },
+ N_("usage: svnrdump load URL\n\n"
+ "Load a 'dumpfile' given on stdin to a repository at remote URL.\n"),
+ { 'q', SVN_SVNRDUMP__BASE_OPTIONS } },
+ { "help", 0, { "?", "h" },
+ N_("usage: svnrdump help [SUBCOMMAND...]\n\n"
+ "Describe the usage of this program or its subcommands.\n"),
+ { 0 } },
+ { NULL, NULL, { 0 }, NULL, { 0 } }
+};
static const apr_getopt_option_t svnrdump__options[] =
{
@@ -108,6 +115,8 @@ static const apr_getopt_option_t svnrdum
N_("specify revision number ARG (or X:Y range)")},
{"quiet", 'q', 0,
N_("no progress (only errors) to stderr")},
+ {"incremental", opt_incremental, 0,
+ N_("dump incrementally")},
{"config-dir", opt_config_dir, 1,
N_("read user configuration files from directory ARG")},
{"username", opt_auth_username, 1,
@@ -149,9 +158,10 @@ struct replay_baton {
typedef struct opt_baton_t {
svn_ra_session_t *session;
const char *url;
- svn_revnum_t start_revision;
- svn_revnum_t end_revision;
+ svn_opt_revision_t start_revision;
+ svn_opt_revision_t end_revision;
svn_boolean_t quiet;
+ svn_boolean_t incremental;
} opt_baton_t;
/* Print dumpstream-formatted information about REVISION.
@@ -170,7 +180,7 @@ replay_revstart(svn_revnum_t revision,
svn_stream_t *stdout_stream;
svn_stream_t *revprop_stream;
- svn_stream_for_stdout(&stdout_stream, pool);
+ SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
/* Revision-number: 19 */
SVN_ERR(svn_stream_printf(stdout_stream, pool,
@@ -220,7 +230,8 @@ replay_revend(svn_revnum_t revision,
/* No resources left to free. */
struct replay_baton *rb = replay_baton;
if (! rb->quiet)
- svn_cmdline_fprintf(stderr, pool, "* Dumped revision %lu.\n", revision);
+ SVN_ERR(svn_cmdline_fprintf(stderr, pool, "* Dumped revision %lu.\n",
+ revision));
return SVN_NO_ERROR;
}
@@ -271,6 +282,49 @@ open_connection(svn_ra_session_t **sessi
return SVN_NO_ERROR;
}
+/* Print a revision record header for REVISION to STDOUT_STREAM. Use
+ * SESSION to contact the repository for revision properties and
+ * such.
+ */
+static svn_error_t *
+dump_revision_header(svn_ra_session_t *session,
+ svn_stream_t *stdout_stream,
+ svn_revnum_t revision,
+ apr_pool_t *pool)
+{
+ apr_hash_t *prophash;
+ svn_stringbuf_t *propstring;
+ svn_stream_t *propstream;
+
+ SVN_ERR(svn_stream_printf(stdout_stream, pool,
+ SVN_REPOS_DUMPFILE_REVISION_NUMBER
+ ": %ld\n", revision));
+
+ prophash = apr_hash_make(pool);
+ propstring = svn_stringbuf_create("", pool);
+ SVN_ERR(svn_ra_rev_proplist(session, revision, &prophash, pool));
+
+ propstream = svn_stream_from_stringbuf(propstring, pool);
+ SVN_ERR(svn_hash_write2(prophash, propstream, "PROPS-END", pool));
+ SVN_ERR(svn_stream_close(propstream));
+
+ /* Property-content-length: 14; Content-length: 14 */
+ SVN_ERR(svn_stream_printf(stdout_stream, pool,
+ SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
+ ": %" APR_SIZE_T_FMT "\n",
+ propstring->len));
+ SVN_ERR(svn_stream_printf(stdout_stream, pool,
+ SVN_REPOS_DUMPFILE_CONTENT_LENGTH
+ ": %" APR_SIZE_T_FMT "\n\n",
+ propstring->len));
+ /* The properties */
+ SVN_ERR(svn_stream_write(stdout_stream, propstring->data,
+ &(propstring->len)));
+ SVN_ERR(svn_stream_printf(stdout_stream, pool, "\n"));
+
+ return SVN_NO_ERROR;
+}
+
/* Replay revisions START_REVISION thru END_REVISION (inclusive) of
* the repository located at URL, using callbacks which generate
* Subversion repository dumpstreams describing the changes made in
@@ -283,6 +337,7 @@ replay_revisions(svn_ra_session_t *sessi
svn_revnum_t start_revision,
svn_revnum_t end_revision,
svn_boolean_t quiet,
+ svn_boolean_t incremental,
apr_pool_t *pool)
{
const svn_delta_editor_t *dump_editor;
@@ -312,46 +367,62 @@ replay_revisions(svn_ra_session_t *sessi
/* Fake revision 0 if necessary */
if (start_revision == 0)
{
- apr_hash_t *prophash;
- svn_stringbuf_t *propstring;
- svn_stream_t *propstream;
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_REVISION_NUMBER
- ": %ld\n", start_revision));
-
- prophash = apr_hash_make(pool);
- propstring = svn_stringbuf_create("", pool);
-
- SVN_ERR(svn_ra_rev_proplist(session, start_revision,
- &prophash, pool));
-
- propstream = svn_stream_from_stringbuf(propstring, pool);
- SVN_ERR(svn_hash_write2(prophash, propstream, "PROPS-END", pool));
- SVN_ERR(svn_stream_close(propstream));
-
- /* Property-content-length: 14; Content-length: 14 */
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n",
- propstring->len));
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n",
- propstring->len));
- /* The properties */
- SVN_ERR(svn_stream_write(stdout_stream, propstring->data,
- &(propstring->len)));
- SVN_ERR(svn_stream_printf(stdout_stream, pool, "\n"));
+ SVN_ERR(dump_revision_header(session, stdout_stream,
+ start_revision, pool));
+
+ /* Revision 0 has no tree changes, so we're done. */
if (! quiet)
- svn_cmdline_fprintf(stderr, pool, "* Dumped revision %lu.\n",
- start_revision);
+ SVN_ERR(svn_cmdline_fprintf(stderr, pool, "* Dumped revision %lu.\n",
+ start_revision));
+ start_revision++;
+
+ /* If our first revision is 0, we can treat this as an
+ incremental dump. */
+ incremental = TRUE;
+ }
+
+ if (incremental)
+ {
+ SVN_ERR(svn_ra_replay_range(session, start_revision, end_revision,
+ 0, TRUE, replay_revstart, replay_revend,
+ replay_baton, pool));
+ }
+ else
+ {
+ const svn_ra_reporter3_t *reporter;
+ void *report_baton;
+ /* First, we need to dump the start_revision in full. We'll
+ start with a revision record header. */
+ SVN_ERR(dump_revision_header(session, stdout_stream,
+ start_revision, pool));
+
+ /* Then, we'll drive the dump editor with what would look like a
+ full checkout of the repository as it looked in
+ START_REVISION. We do this by manufacturing a basic 'report'
+ to the update reporter, telling it that we have nothing to
+ start with. The delta between nothing and everything-at-REV
+ is, effectively, a full dump of REV. */
+ SVN_ERR(svn_ra_do_update2(session, &reporter, &report_baton,
+ start_revision, "", svn_depth_infinity,
+ FALSE, dump_editor, dump_baton, pool));
+ SVN_ERR(reporter->set_path(report_baton, "", start_revision,
+ svn_depth_infinity, TRUE, NULL, pool));
+ SVN_ERR(reporter->finish_report(report_baton, pool));
+
+ /* All finished with START_REVISION! */
+ if (! quiet)
+ SVN_ERR(svn_cmdline_fprintf(stderr, pool, "* Dumped revision %lu.\n",
+ start_revision));
start_revision++;
+
+ /* Now go pick up additional revisions in the range, if any. */
+ if (start_revision <= end_revision)
+ SVN_ERR(svn_ra_replay_range(session, start_revision, end_revision,
+ 0, TRUE, replay_revstart, replay_revend,
+ replay_baton, pool));
}
- SVN_ERR(svn_ra_replay_range(session, start_revision, end_revision,
- 0, TRUE, replay_revstart, replay_revend,
- replay_baton, pool));
SVN_ERR(svn_stream_close(stdout_stream));
return SVN_NO_ERROR;
}
@@ -378,7 +449,7 @@ load_revisions(svn_ra_session_t *session
SVN_ERR(drive_dumpstream_loader(stdin_stream, parser, parse_baton,
session, check_cancel, NULL, pool));
- svn_stream_close(stdin_stream);
+ SVN_ERR(svn_stream_close(stdin_stream));
return SVN_NO_ERROR;
}
@@ -450,8 +521,9 @@ dump_cmd(apr_getopt_t *os,
{
opt_baton_t *opt_baton = baton;
return replay_revisions(opt_baton->session, opt_baton->url,
- opt_baton->start_revision, opt_baton->end_revision,
- opt_baton->quiet, pool);
+ opt_baton->start_revision.value.number,
+ opt_baton->end_revision.value.number,
+ opt_baton->quiet, opt_baton->incremental, pool);
}
/* Handle the "load" subcommand. Implements `svn_opt_subcommand_t'. */
@@ -482,13 +554,95 @@ help_cmd(apr_getopt_t *os,
NULL, pool);
}
+/* Examine the OPT_BATON's 'start_revision' and 'end_revision'
+ * members, making sure that they make sense (in general, and as
+ * applied to a repository whose current youngest revision is
+ * LATEST_REVISION).
+ */
+static svn_error_t *
+validate_and_resolve_revisions(opt_baton_t *opt_baton,
+ svn_revnum_t latest_revision,
+ apr_pool_t *pool)
+{
+ svn_revnum_t provided_start_rev = SVN_INVALID_REVNUM;
+
+ /* Ensure that the start revision is something we can handle. We
+ want a number >= 0. If unspecified, make it a number (r0) --
+ anything else is bogus. */
+ if (opt_baton->start_revision.kind == svn_opt_revision_number)
+ {
+ provided_start_rev = opt_baton->start_revision.value.number;
+ }
+ else if (opt_baton->start_revision.kind == svn_opt_revision_unspecified)
+ {
+ opt_baton->start_revision.kind = svn_opt_revision_number;
+ opt_baton->start_revision.value.number = 0;
+ }
+
+ if (opt_baton->start_revision.kind != svn_opt_revision_number)
+ {
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Unsupported revision specifier used; use "
+ "only integer values or 'HEAD'"));
+ }
+
+ if ((opt_baton->start_revision.value.number < 0) ||
+ (opt_baton->start_revision.value.number > latest_revision))
+ {
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Revision '%ld' does not exist"),
+ opt_baton->start_revision.value.number);
+ }
+
+ /* Ensure that the end revision is something we can handle. We want
+ a number <= the youngest, and > the start revision. If
+ unspecified, make it a number (start_revision + 1 if that was
+ specified, the youngest revision in the repository otherwise) --
+ anything else is bogus. */
+ if (opt_baton->end_revision.kind == svn_opt_revision_unspecified)
+ {
+ opt_baton->end_revision.kind = svn_opt_revision_number;
+ if (SVN_IS_VALID_REVNUM(provided_start_rev))
+ opt_baton->end_revision.value.number = provided_start_rev;
+ else
+ opt_baton->end_revision.value.number = latest_revision;
+ }
+
+ if (opt_baton->end_revision.kind != svn_opt_revision_number)
+ {
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Unsupported revision specifier used; use "
+ "only integer values or 'HEAD'"));
+ }
+
+ if ((opt_baton->end_revision.value.number < 0) ||
+ (opt_baton->end_revision.value.number > latest_revision))
+ {
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Revision '%ld' does not exist"),
+ opt_baton->end_revision.value.number);
+ }
+
+ /* Finally, make sure that the end revision is younger than the
+ start revision. We don't do "backwards" 'round here. */
+ if (opt_baton->end_revision.value.number <
+ opt_baton->start_revision.value.number)
+ {
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("LOWER revision cannot be greater than "
+ "UPPER revision; consider reversing your "
+ "revision range"));
+ }
+ return SVN_NO_ERROR;
+}
+
int
main(int argc, const char **argv)
{
+ svn_error_t *err = SVN_NO_ERROR;
const svn_opt_subcommand_desc2_t *subcommand = NULL;
opt_baton_t *opt_baton;
- char *revision_cut = NULL;
- svn_revnum_t latest_revision = svn_opt_revision_unspecified;
+ svn_revnum_t latest_revision = SVN_INVALID_REVNUM;
apr_pool_t *pool = NULL;
const char *config_dir = NULL;
const char *username = NULL;
@@ -498,14 +652,16 @@ main(int argc, const char **argv)
apr_array_header_t *config_options = NULL;
apr_getopt_t *os;
const char *first_arg;
+ apr_array_header_t *received_opts;
+ int i;
if (svn_cmdline_init ("svnrdump", stderr) != EXIT_SUCCESS)
return EXIT_FAILURE;
pool = svn_pool_create(NULL);
opt_baton = apr_pcalloc(pool, sizeof(*opt_baton));
- opt_baton->start_revision = svn_opt_revision_unspecified;
- opt_baton->end_revision = svn_opt_revision_unspecified;
+ opt_baton->start_revision.kind = svn_opt_revision_unspecified;
+ opt_baton->end_revision.kind = svn_opt_revision_unspecified;
opt_baton->url = NULL;
SVNRDUMP_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
@@ -535,6 +691,8 @@ main(int argc, const char **argv)
apr_signal(SIGXFSZ, SIG_IGN);
#endif
+ received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
+
while (1)
{
int opt;
@@ -550,23 +708,34 @@ main(int argc, const char **argv)
exit(EXIT_FAILURE);
}
+ /* Stash the option code in an array before parsing it. */
+ APR_ARRAY_PUSH(received_opts, int) = opt;
+
switch(opt)
{
case 'r':
{
- revision_cut = strchr(opt_arg, ':');
- if (revision_cut)
+ /* Make sure we've not seen -r already. */
+ if (opt_baton->start_revision.kind != svn_opt_revision_unspecified)
{
- opt_baton->start_revision =
- (svn_revnum_t)strtoul(opt_arg, &revision_cut, 10);
- opt_baton->end_revision =
- (svn_revnum_t)strtoul(revision_cut + 1, NULL, 10);
+ err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Multiple revision arguments "
+ "encountered; try '-r N:M' instead "
+ "of '-r N -r M'"));
+ return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
}
- else
+ /* Parse the -r argument. */
+ if (svn_opt_parse_revision(&(opt_baton->start_revision),
+ &(opt_baton->end_revision),
+ opt_arg, pool) != 0)
{
- opt_baton->start_revision =
- (svn_revnum_t)strtoul(opt_arg, NULL, 10);
- opt_baton->end_revision = opt_baton->start_revision;
+ const char *utf8_opt_arg;
+ err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
+ if (! err)
+ err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Syntax error in revision "
+ "argument '%s'"), utf8_opt_arg);
+ return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
}
}
break;
@@ -596,6 +765,9 @@ main(int argc, const char **argv)
case opt_non_interactive:
non_interactive = TRUE;
break;
+ case opt_incremental:
+ opt_baton->incremental = TRUE;
+ break;
case opt_config_option:
if (!config_options)
config_options =
@@ -625,8 +797,7 @@ main(int argc, const char **argv)
if (subcommand == NULL)
{
const char *first_arg_utf8;
- svn_error_t *err = svn_utf_cstring_to_utf8(&first_arg_utf8,
- first_arg, pool);
+ err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool);
if (err)
return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
svn_error_clear(svn_cmdline_fprintf(stderr, pool,
@@ -637,6 +808,39 @@ main(int argc, const char **argv)
exit(EXIT_FAILURE);
}
+ /* Check that the subcommand wasn't passed any inappropriate options. */
+ for (i = 0; i < received_opts->nelts; i++)
+ {
+ int opt_id = APR_ARRAY_IDX(received_opts, i, int);
+
+ /* All commands implicitly accept --help, so just skip over this
+ when we see it. Note that we don't want to include this option
+ in their "accepted options" list because it would be awfully
+ redundant to display it in every commands' help text. */
+ if (opt_id == 'h' || opt_id == '?')
+ continue;
+
+ if (! svn_opt_subcommand_takes_option3(subcommand, opt_id, NULL))
+ {
+ const char *optstr;
+ const apr_getopt_option_t *badopt =
+ svn_opt_get_option_from_code2(opt_id, svnrdump__options,
+ subcommand, pool);
+ svn_opt_format_option(&optstr, badopt, FALSE, pool);
+ if (subcommand->name[0] == '-')
+ SVN_INT_ERR(help_cmd(NULL, NULL, pool));
+ else
+ svn_error_clear
+ (svn_cmdline_fprintf
+ (stderr, pool,
+ _("Subcommand '%s' doesn't accept option '%s'\n"
+ "Type 'svnrdump help %s' for usage.\n"),
+ subcommand->name, optstr, subcommand->name));
+ svn_pool_destroy(pool);
+ return EXIT_FAILURE;
+ }
+ }
+
if (subcommand && strcmp(subcommand->name, "help") == 0)
{
SVNRDUMP_ERR(help_cmd(os, opt_baton, pool));
@@ -670,24 +874,10 @@ main(int argc, const char **argv)
unspecified. */
SVNRDUMP_ERR(svn_ra_get_latest_revnum(opt_baton->session,
&latest_revision, pool));
- if (opt_baton->start_revision == svn_opt_revision_unspecified)
- opt_baton->start_revision = 0;
- if (opt_baton->end_revision == svn_opt_revision_unspecified)
- opt_baton->end_revision = latest_revision;
- if (opt_baton->end_revision > latest_revision)
- {
- SVN_INT_ERR(svn_cmdline_fprintf(stderr, pool,
- _("Revision %ld does not exist.\n"),
- opt_baton->end_revision));
- exit(EXIT_FAILURE);
- }
- if (opt_baton->end_revision < opt_baton->start_revision)
- {
- SVN_INT_ERR(svn_cmdline_fprintf(stderr, pool,
- _("LOWER cannot be greater "
- "than UPPER.\n")));
- exit(EXIT_FAILURE);
- }
+
+ /* Make sure any provided revisions make sense. */
+ SVNRDUMP_ERR(validate_and_resolve_revisions(opt_baton,
+ latest_revision, pool));
/* Dispatch the subcommand */
SVNRDUMP_ERR((*subcommand->cmd_func)(os, opt_baton, pool));