You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/12/02 21:55:18 UTC
svn commit: r1041580 [10/35] - in
/subversion/branches/gpg-agent-password-store: ./ build/ build/ac-macros/
build/generator/ build/generator/templates/ build/win32/
contrib/hook-scripts/ contrib/server-side/ notes/http-and-webdav/
notes/wc-ng/ subversi...
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/conflicts.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/conflicts.c Thu Dec 2 20:55:08 2010
@@ -50,152 +50,6 @@
#include "svn_private_config.h"
-struct svn_wc_conflict_t
-{
- /* ### kind + property name are the primary keys of a conflict */
- /* The kind of conflict recorded */
- svn_wc_conflict_kind_t kind;
-
- /* When describing a property conflict the property name
- or "" when no property name is available. (Upgrade from old WC or
- raised via compatibility apis). */
- const char *property_name;
-
- /* ### TODO: Add more fields */
-};
-
-/* */
-static svn_error_t *
-conflict_alloc(svn_wc_conflict_t **conflict, apr_pool_t *result_pool)
-{
- svn_wc_conflict_t *c = apr_pcalloc(result_pool, sizeof(*c));
-
- *conflict = c;
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc_conflict_dup(svn_wc_conflict_t **duplicate,
- const svn_wc_conflict_t *base,
- apr_pool_t *result_pool)
-{
- svn_wc_conflict_t *c;
-
- SVN_ERR(conflict_alloc(&c, result_pool));
-
- c->kind = base->kind;
- c->property_name = base->property_name
- ? apr_pstrdup(result_pool, base->property_name)
- : NULL;
-
- *duplicate = c;
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc_create_property_conflict(svn_wc_conflict_t **conflict,
- const char *property_name,
- const svn_wc_conflict_version_t *older_version,
- const svn_wc_conflict_version_t *left_version,
- const svn_wc_conflict_version_t *right_version,
- const svn_string_t *older_value,
- const svn_string_t *left_value,
- const svn_string_t *right_value,
- const char *marker_abspath,
- svn_wc_operation_t operation,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
-}
-
-svn_error_t *
-svn_wc_create_text_conflict(svn_wc_conflict_t **conflict,
- const svn_wc_conflict_version_t *older_version,
- const svn_wc_conflict_version_t *left_version,
- const svn_wc_conflict_version_t *right_version,
- const char *older_abspath,
- const char *left_abspath,
- const char *right_abspath,
- svn_wc_operation_t operation,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
-}
-
-svn_error_t *
-svn_wc_create_tree_conflict(svn_wc_conflict_t **conflict,
- const svn_wc_conflict_version_t *older_version,
- const svn_wc_conflict_version_t *left_version,
- const svn_wc_conflict_version_t *right_version,
- svn_wc_conflict_action_t action,
- svn_wc_conflict_reason_t reason,
- svn_wc_operation_t operation,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
-}
-
-svn_error_t *
-svn_wc_get_conflict_info(svn_wc_conflict_kind_t *kind,
- const char **property_name,
- svn_wc_conflict_action_t *action,
- svn_wc_conflict_reason_t *reason,
- svn_wc_operation_t *operation,
- svn_boolean_t *conflict_resolved,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- svn_wc_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
-}
-
-
-svn_error_t *
-svn_wc_get_conflict_marker_files(const char **older_abspath,
- const char **left_abspath,
- const char **right_abspath,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- svn_wc_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
-}
-
-svn_error_t *
-svn_wc_get_conflict_sources(const svn_wc_conflict_version_t **older_version,
- const svn_wc_conflict_version_t **left_version,
- const svn_wc_conflict_version_t **right_version,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- svn_wc_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
-}
-
-svn_error_t *
-svn_wc_get_property_conflict_data(const svn_string_t **older_value,
- const svn_string_t **left_value,
- const svn_string_t **right_value,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- svn_wc_conflict_t *conflict,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
-}
-
-
svn_skel_t *
svn_wc__conflict_skel_new(apr_pool_t *result_pool)
{
@@ -312,6 +166,8 @@ attempt_deletion(const char *parent_dir,
### leave, for example, one of the conflict artifact files deleted but
### the entry still referring to it and trying to use it for the next
### attempt at resolving.
+
+ ### Does this still apply in the world of WC-NG? -hkw
*/
static svn_error_t *
resolve_conflict_on_node(svn_wc__db_t *db,
@@ -334,11 +190,7 @@ resolve_conflict_on_node(svn_wc__db_t *d
*did_resolve = FALSE;
- SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL,
- db, local_abspath, pool, pool));
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, pool));
SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
pool, pool));
@@ -366,6 +218,7 @@ resolve_conflict_on_node(svn_wc__db_t *d
if (resolve_text)
{
+ svn_stream_t *tmp_stream = NULL;
const char *auto_resolve_src;
/* Handle automatic conflict resolution before the temporary files are
@@ -390,7 +243,6 @@ resolve_conflict_on_node(svn_wc__db_t *d
if (conflict_old && conflict_working && conflict_new)
{
const char *temp_dir;
- svn_stream_t *tmp_stream;
svn_diff_t *diff;
svn_diff_conflict_display_style_t style =
conflict_choice == svn_wc_conflict_choose_theirs_conflict
@@ -402,7 +254,8 @@ resolve_conflict_on_node(svn_wc__db_t *d
pool, pool));
SVN_ERR(svn_stream_open_unique(&tmp_stream,
&auto_resolve_src,
- temp_dir, svn_io_file_del_none,
+ temp_dir,
+ svn_io_file_del_on_close,
pool, pool));
/* ### If any of these paths isn't absolute, treat it
@@ -436,7 +289,6 @@ resolve_conflict_on_node(svn_wc__db_t *d
NULL, NULL, NULL, NULL,
style,
pool));
- SVN_ERR(svn_stream_close(tmp_stream));
}
else
auto_resolve_src = NULL;
@@ -451,6 +303,9 @@ resolve_conflict_on_node(svn_wc__db_t *d
SVN_ERR(svn_io_copy_file(
svn_dirent_join(conflict_dir_abspath, auto_resolve_src, pool),
local_abspath, TRUE, pool));
+
+ if (tmp_stream)
+ SVN_ERR(svn_stream_close(tmp_stream));
}
/* Records whether we found any of the conflict files. */
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/copy.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/copy.c Thu Dec 2 20:55:08 2010
@@ -197,17 +197,13 @@ copy_pristine_text_if_necessary(svn_wc__
otherwise copy both the versioned metadata and the filesystem node (even
if it is the wrong kind, and recursively if it is a dir).
- A replacement for both copy_file_administratively and
- copy_added_file_administratively.
-
- ### Not yet fully working. Relies on in-db-props.
-
This also works for versioned symlinks that are stored in the db as
svn_wc__db_kind_file with svn:special set. */
static svn_error_t *
copy_versioned_file(svn_wc__db_t *db,
const char *src_abspath,
const char *dst_abspath,
+ const char *dst_op_root_abspath,
svn_boolean_t metadata_only,
svn_cancel_func_t cancel_func,
void *cancel_baton,
@@ -218,8 +214,6 @@ copy_versioned_file(svn_wc__db_t *db,
svn_skel_t *work_items = NULL;
const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
const char *tmpdir_abspath;
- const char *tmp_dst_abspath;
- svn_node_kind_t kind;
SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dst_abspath,
scratch_pool, scratch_pool));
@@ -234,14 +228,29 @@ copy_versioned_file(svn_wc__db_t *db,
copy recursively if it's a dir. */
if (!metadata_only)
{
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, src_abspath,
+ const char *tmp_dst_abspath;
+ svn_node_kind_t disk_kind;
+
+ SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, src_abspath,
tmpdir_abspath,
TRUE, /* recursive */
cancel_func, cancel_baton, scratch_pool));
+
if (tmp_dst_abspath)
{
svn_skel_t *work_item;
+ /* Remove 'read-only' from the destination file; it's a local add. */
+ {
+ const svn_string_t *needs_lock;
+ SVN_ERR(svn_wc__internal_propget(&needs_lock, db, src_abspath,
+ SVN_PROP_NEEDS_LOCK,
+ scratch_pool, scratch_pool));
+ if (needs_lock)
+ SVN_ERR(svn_io_set_file_read_write(tmp_dst_abspath,
+ FALSE, scratch_pool));
+ }
+
SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
tmp_dst_abspath, dst_abspath,
scratch_pool, scratch_pool));
@@ -251,7 +260,7 @@ copy_versioned_file(svn_wc__db_t *db,
/* Copy the (single) node's metadata, and move the new filesystem node
into place. */
- SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
+ SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath, dst_op_root_abspath,
work_items, scratch_pool));
SVN_ERR(svn_wc__wq_run(db, dir_abspath,
cancel_func, cancel_baton, scratch_pool));
@@ -275,6 +284,7 @@ static svn_error_t *
copy_versioned_dir(svn_wc__db_t *db,
const char *src_abspath,
const char *dst_abspath,
+ const char *dst_op_root_abspath,
svn_boolean_t metadata_only,
svn_cancel_func_t cancel_func,
void *cancel_baton,
@@ -285,21 +295,22 @@ copy_versioned_dir(svn_wc__db_t *db,
svn_skel_t *work_items = NULL;
const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
const char *tmpdir_abspath;
- const char *tmp_dst_abspath;
const apr_array_header_t *versioned_children;
- apr_hash_t *children;
- svn_node_kind_t kind;
+ apr_hash_t *disk_children;
+ svn_node_kind_t disk_kind;
apr_pool_t *iterpool;
int i;
/* Prepare a temp copy of the single filesystem node (usually a dir). */
if (!metadata_only)
{
+ const char *tmp_dst_abspath;
+
SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
dst_abspath,
scratch_pool, scratch_pool));
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, src_abspath,
+ SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, src_abspath,
tmpdir_abspath, FALSE, /* recursive */
cancel_func, cancel_baton, scratch_pool));
if (tmp_dst_abspath)
@@ -315,7 +326,7 @@ copy_versioned_dir(svn_wc__db_t *db,
/* Copy the (single) node's metadata, and move the new filesystem node
into place. */
- SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
+ SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath, dst_op_root_abspath,
work_items, scratch_pool));
SVN_ERR(svn_wc__wq_run(db, dir_abspath,
cancel_func, cancel_baton, scratch_pool));
@@ -329,12 +340,14 @@ copy_versioned_dir(svn_wc__db_t *db,
(*notify_func)(notify_baton, notify, scratch_pool);
}
- if (!metadata_only && kind == svn_node_dir)
+ if (!metadata_only && disk_kind == svn_node_dir)
/* All filesystem children, versioned and unversioned. We're only
interested in their names, so we can pass TRUE as the only_check_type
param. */
- SVN_ERR(svn_io_get_dirents3(&children, src_abspath, TRUE,
+ SVN_ERR(svn_io_get_dirents3(&disk_children, src_abspath, TRUE,
scratch_pool, scratch_pool));
+ else
+ disk_children = NULL;
/* Copy all the versioned children */
SVN_ERR(svn_wc__db_read_children(&versioned_children, db, src_abspath,
@@ -359,12 +372,14 @@ copy_versioned_dir(svn_wc__db_t *db,
if (child_kind == svn_wc__db_kind_file)
SVN_ERR(copy_versioned_file(db,
child_src_abspath, child_dst_abspath,
+ dst_op_root_abspath,
metadata_only,
cancel_func, cancel_baton, NULL, NULL,
iterpool));
else if (child_kind == svn_wc__db_kind_dir)
SVN_ERR(copy_versioned_dir(db,
child_src_abspath, child_dst_abspath,
+ dst_op_root_abspath,
metadata_only,
cancel_func, cancel_baton, NULL, NULL,
iterpool));
@@ -374,21 +389,22 @@ copy_versioned_dir(svn_wc__db_t *db,
svn_dirent_local_style(child_src_abspath,
scratch_pool));
- if (!metadata_only && kind == svn_node_dir)
+ if (disk_children)
/* Remove versioned child as it has been handled */
- apr_hash_set(children, child_name, APR_HASH_KEY_STRING, NULL);
+ apr_hash_set(disk_children, child_name, APR_HASH_KEY_STRING, NULL);
}
/* Copy all the remaining filesystem children, which are unversioned. */
- if (!metadata_only && kind == svn_node_dir)
+ if (disk_children)
{
apr_hash_index_t *hi;
- for (hi = apr_hash_first(scratch_pool, children); hi;
+ for (hi = apr_hash_first(scratch_pool, disk_children); hi;
hi = apr_hash_next(hi))
{
const char *name = svn__apr_hash_index_key(hi);
const char *unver_src_abspath, *unver_dst_abspath;
+ const char *tmp_dst_abspath;
if (svn_wc_is_adm_dir(name, iterpool))
continue;
@@ -400,8 +416,8 @@ copy_versioned_dir(svn_wc__db_t *db,
unver_src_abspath = svn_dirent_join(src_abspath, name, iterpool);
unver_dst_abspath = svn_dirent_join(dst_abspath, name, iterpool);
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, unver_src_abspath,
- tmpdir_abspath,
+ SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind,
+ unver_src_abspath, tmpdir_abspath,
TRUE, /* recursive */
cancel_func, cancel_baton, iterpool));
if (tmp_dst_abspath)
@@ -426,7 +442,6 @@ copy_versioned_dir(svn_wc__db_t *db,
}
-
/* Public Interface */
svn_error_t *
@@ -443,7 +458,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
svn_wc__db_t *db = wc_ctx->db;
svn_wc__db_kind_t src_db_kind;
const char *dstdir_abspath;
-
+
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -597,14 +612,16 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
if (src_db_kind == svn_wc__db_kind_file
|| src_db_kind == svn_wc__db_kind_symlink)
{
- SVN_ERR(copy_versioned_file(db, src_abspath, dst_abspath, metadata_only,
+ SVN_ERR(copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
+ metadata_only,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool));
}
else
{
- SVN_ERR(copy_versioned_dir(db, src_abspath, dst_abspath, metadata_only,
+ SVN_ERR(copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
+ metadata_only,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool));
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/deprecated.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/deprecated.c Thu Dec 2 20:55:08 2010
@@ -2729,7 +2729,6 @@ svn_wc_add_repos_file3(const char *dst_p
copyfrom_url,
copyfrom_rev,
cancel_func, cancel_baton,
- notify_func, notify_baton,
pool));
return svn_error_return(svn_wc_context_destroy(wc_ctx));
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.c Thu Dec 2 20:55:08 2010
@@ -74,6 +74,7 @@ typedef struct {
typedef struct {
apr_int64_t wc_id;
const char *local_relpath;
+ apr_int64_t op_depth;
const char *parent_relpath;
svn_wc__db_status_t presence;
svn_node_kind_t kind; /* ### should switch to svn_wc__db_kind_t */
@@ -471,6 +472,42 @@ get_base_info_for_deleted(svn_wc_entry_t
}
+/*
+ * Encode tree conflict descriptions into a single string.
+ *
+ * Set *CONFLICT_DATA to a string, allocated in POOL, that encodes the tree
+ * conflicts in CONFLICTS in a form suitable for storage in a single string
+ * field in a WC entry. CONFLICTS is a hash of zero or more pointers to
+ * svn_wc_conflict_description2_t objects, index by their basenames. All of the
+ * conflict victim paths must be siblings.
+ *
+ * Do all allocations in POOL.
+ *
+ * @see svn_wc__read_tree_conflicts()
+ */
+static svn_error_t *
+write_tree_conflicts(const char **conflict_data,
+ apr_hash_t *conflicts,
+ apr_pool_t *pool)
+{
+ svn_skel_t *skel = svn_skel__make_empty_list(pool);
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(pool, conflicts); hi; hi = apr_hash_next(hi))
+ {
+ svn_skel_t *c_skel;
+
+ SVN_ERR(svn_wc__serialize_conflict(&c_skel, svn__apr_hash_index_val(hi),
+ pool, pool));
+ svn_skel__prepend(c_skel, skel);
+ }
+
+ *conflict_data = svn_skel__unparse(skel, pool)->data;
+
+ return SVN_NO_ERROR;
+}
+
+
/* Read one entry from wc_db. It will be allocated in RESULT_POOL and
returned in *NEW_ENTRY.
@@ -487,7 +524,7 @@ get_base_info_for_deleted(svn_wc_entry_t
static svn_error_t *
read_one_entry(const svn_wc_entry_t **new_entry,
svn_wc__db_t *db,
- apr_uint64_t wc_id,
+ apr_int64_t wc_id,
const char *dir_abspath,
const char *name,
const svn_wc_entry_t *parent_entry,
@@ -586,9 +623,8 @@ read_one_entry(const svn_wc_entry_t **ne
if (tree_conflicts)
{
- SVN_ERR(svn_wc__write_tree_conflicts(&entry->tree_conflict_data,
- tree_conflicts,
- result_pool));
+ SVN_ERR(write_tree_conflicts(&entry->tree_conflict_data,
+ tree_conflicts, result_pool));
}
}
@@ -601,40 +637,24 @@ read_one_entry(const svn_wc_entry_t **ne
a subdirectory "over" a not-present directory. The read_info()
will return information out of the wc.db in the subdir. We
need to detect this situation and create a DELETED entry
- instead. */
+ instead.
+
+ ### Does this still happen? The regression tests passed when
+ the NODES query was erroneously accessing BASE_NODE. */
if (kind == svn_wc__db_kind_dir)
{
svn_sqlite__db_t *sdb;
svn_sqlite__stmt_t *stmt;
-#ifdef SVN_WC__NODES
- svn_sqlite__stmt_t *stmt_nodes;
- svn_boolean_t have_nodes_row;
-#endif
SVN_ERR(svn_wc__db_temp_borrow_sdb(
&sdb, db, dir_abspath,
svn_wc__db_openmode_readonly,
scratch_pool));
-#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_SELECT_NOT_PRESENT));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, entry->name));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
-#endif
-#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
- STMT_SELECT_NOT_PRESENT));
- SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", wc_id, entry->name));
- SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR_ASSERT(have_row == have_nodes_row);
- SVN_ERR(svn_sqlite__reset(stmt_nodes));
-#else
- stmt = stmt_nodes;
- have_row = have_nodes_row;
-#endif
-#endif
SVN_ERR(svn_sqlite__reset(stmt));
}
@@ -1084,7 +1104,7 @@ read_entries_new(apr_hash_t **result_ent
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
int i;
const svn_wc_entry_t *parent_entry;
- apr_uint64_t wc_id = 1; /* ### hacky. should remove. */
+ apr_int64_t wc_id = 1; /* ### hacky. should remove. */
entries = apr_hash_make(result_pool);
@@ -1139,7 +1159,7 @@ read_entry_pair(const svn_wc_entry_t **p
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- apr_uint64_t wc_id = 1; /* ### hacky. should remove. */
+ apr_int64_t wc_id = 1; /* ### hacky. should remove. */
SVN_ERR(read_one_entry(parent_entry, db, wc_id, dir_abspath,
"" /* name */,
@@ -1532,77 +1552,9 @@ insert_base_node(svn_sqlite__db_t *sdb,
{
svn_sqlite__stmt_t *stmt;
-#ifndef SVN_WC__NODES_ONLY
- /* ### NODE_DATA when switching to NODE_DATA, replace the
- query below with STMT_INSERT_BASE_NODE_DATA_FOR_ENTRY_1
- and adjust the parameters bound. Can't do that yet. */
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_INSERT_BASE_NODE_FOR_ENTRY));
- SVN_ERR(svn_sqlite__bind_int64(stmt, 1, base_node->wc_id));
- SVN_ERR(svn_sqlite__bind_text(stmt, 2, base_node->local_relpath));
-
- if (base_node->repos_id)
- {
- SVN_ERR(svn_sqlite__bind_int64(stmt, 3, base_node->repos_id));
- SVN_ERR(svn_sqlite__bind_text(stmt, 4, base_node->repos_relpath));
- }
-
- if (base_node->parent_relpath)
- SVN_ERR(svn_sqlite__bind_text(stmt, 5, base_node->parent_relpath));
-
- if (base_node->presence == svn_wc__db_status_not_present)
- SVN_ERR(svn_sqlite__bind_text(stmt, 6, "not-present"));
- else if (base_node->presence == svn_wc__db_status_normal)
- SVN_ERR(svn_sqlite__bind_text(stmt, 6, "normal"));
- else if (base_node->presence == svn_wc__db_status_absent)
- SVN_ERR(svn_sqlite__bind_text(stmt, 6, "absent"));
- else if (base_node->presence == svn_wc__db_status_incomplete)
- SVN_ERR(svn_sqlite__bind_text(stmt, 6, "incomplete"));
- else if (base_node->presence == svn_wc__db_status_excluded)
- SVN_ERR(svn_sqlite__bind_text(stmt, 6, "excluded"));
-
- SVN_ERR(svn_sqlite__bind_int64(stmt, 7, base_node->revision));
-
- /* ### kind might be "symlink" or "unknown" */
- if (base_node->kind == svn_node_none)
- SVN_ERR(svn_sqlite__bind_text(stmt, 5, "unknown"));
- else
- SVN_ERR(svn_sqlite__bind_text(stmt, 8,
- svn_node_kind_to_word(base_node->kind)));
-
- if (base_node->checksum)
- SVN_ERR(svn_sqlite__bind_checksum(stmt, 9, base_node->checksum,
- scratch_pool));
-
- if (base_node->translated_size != SVN_INVALID_FILESIZE)
- SVN_ERR(svn_sqlite__bind_int64(stmt, 10, base_node->translated_size));
-
- /* ### strictly speaking, changed_rev should be valid for present nodes. */
- if (SVN_IS_VALID_REVNUM(base_node->changed_rev))
- SVN_ERR(svn_sqlite__bind_int64(stmt, 11, base_node->changed_rev));
- if (base_node->changed_date)
- SVN_ERR(svn_sqlite__bind_int64(stmt, 12, base_node->changed_date));
- if (base_node->changed_author)
- SVN_ERR(svn_sqlite__bind_text(stmt, 13, base_node->changed_author));
-
- SVN_ERR(svn_sqlite__bind_text(stmt, 14, svn_depth_to_word(base_node->depth)));
-
- SVN_ERR(svn_sqlite__bind_int64(stmt, 15, base_node->last_mod_time));
-
- if (base_node->properties)
- SVN_ERR(svn_sqlite__bind_properties(stmt, 16, base_node->properties,
- scratch_pool));
-
- /* Execute and reset the insert clause. */
- SVN_ERR(svn_sqlite__insert(NULL, stmt));
-
-#endif
-#ifdef SVN_WC__NODES
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_INSERT_BASE_NODE_FOR_ENTRY_1));
-
SVN_ERR(svn_sqlite__bindf(stmt, "issisr",
base_node->wc_id,
base_node->local_relpath,
@@ -1655,8 +1607,6 @@ insert_base_node(svn_sqlite__db_t *sdb,
/* Execute and reset the insert clause. */
SVN_ERR(svn_sqlite__insert(NULL, stmt));
-
-#endif
return SVN_NO_ERROR;
}
@@ -1668,86 +1618,10 @@ insert_working_node(svn_sqlite__db_t *sd
{
svn_sqlite__stmt_t *stmt;
-#ifndef SVN_WC__NODES_ONLY
- /* ### NODE_DATA when switching to NODE_DATA, replace the
- query below with STMT_INSERT_WORKING_NODE_DATA_2
- and adjust the parameters bound. Can't do that yet. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_WORKING_NODE));
-
- SVN_ERR(svn_sqlite__bind_int64(stmt, 1, working_node->wc_id));
- SVN_ERR(svn_sqlite__bind_text(stmt, 2, working_node->local_relpath));
- SVN_ERR(svn_sqlite__bind_text(stmt, 3, working_node->parent_relpath));
-
- /* ### need rest of values */
- if (working_node->presence == svn_wc__db_status_normal)
- SVN_ERR(svn_sqlite__bind_text(stmt, 4, "normal"));
- else if (working_node->presence == svn_wc__db_status_not_present)
- SVN_ERR(svn_sqlite__bind_text(stmt, 4, "not-present"));
- else if (working_node->presence == svn_wc__db_status_base_deleted)
- SVN_ERR(svn_sqlite__bind_text(stmt, 4, "base-deleted"));
- else if (working_node->presence == svn_wc__db_status_incomplete)
- SVN_ERR(svn_sqlite__bind_text(stmt, 4, "incomplete"));
- else if (working_node->presence == svn_wc__db_status_excluded)
- SVN_ERR(svn_sqlite__bind_text(stmt, 4, "excluded"));
-
- if (working_node->kind == svn_node_none)
- SVN_ERR(svn_sqlite__bind_text(stmt, 5, "unknown"));
- else
- SVN_ERR(svn_sqlite__bind_text(stmt, 5,
- svn_node_kind_to_word(working_node->kind)));
-
- if (working_node->copyfrom_repos_path)
- {
- SVN_ERR(svn_sqlite__bind_int64(stmt, 6,
- working_node->copyfrom_repos_id));
- SVN_ERR(svn_sqlite__bind_text(stmt, 7,
- working_node->copyfrom_repos_path));
- SVN_ERR(svn_sqlite__bind_int64(stmt, 8, working_node->copyfrom_revnum));
- }
-
- if (working_node->moved_here)
- SVN_ERR(svn_sqlite__bind_int(stmt, 9, working_node->moved_here));
-
- if (working_node->moved_to)
- SVN_ERR(svn_sqlite__bind_text(stmt, 10, working_node->moved_to));
-
- if (working_node->checksum)
- SVN_ERR(svn_sqlite__bind_checksum(stmt, 11, working_node->checksum,
- scratch_pool));
-
- if (working_node->translated_size != SVN_INVALID_FILESIZE)
- SVN_ERR(svn_sqlite__bind_int64(stmt, 12, working_node->translated_size));
-
- if (SVN_IS_VALID_REVNUM(working_node->changed_rev))
- SVN_ERR(svn_sqlite__bind_int64(stmt, 13, working_node->changed_rev));
- if (working_node->changed_date)
- SVN_ERR(svn_sqlite__bind_int64(stmt, 14, working_node->changed_date));
- if (working_node->changed_author)
- SVN_ERR(svn_sqlite__bind_text(stmt, 15, working_node->changed_author));
-
- SVN_ERR(svn_sqlite__bind_text(stmt, 16,
- svn_depth_to_word(working_node->depth)));
-
- SVN_ERR(svn_sqlite__bind_int64(stmt, 17, working_node->last_mod_time));
-
- if (working_node->properties)
- SVN_ERR(svn_sqlite__bind_properties(stmt, 18, working_node->properties,
- scratch_pool));
-
- SVN_ERR(svn_sqlite__bind_int64(stmt, 19, working_node->keep_local));
-
- /* ### we should bind 'symlink_target' (20) as appropriate. */
-
- /* Execute and reset the insert clause. */
- SVN_ERR(svn_sqlite__insert(NULL, stmt));
-#endif
-
-#ifdef SVN_WC__NODES
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "isisnnnnsnrisnnni",
working_node->wc_id, working_node->local_relpath,
- (working_node->parent_relpath == NULL
- ? (apr_int64_t)1 : (apr_int64_t)2),
+ working_node->op_depth,
working_node->parent_relpath,
/* Setting depth for files? */
svn_depth_to_word(working_node->depth),
@@ -1786,7 +1660,7 @@ insert_working_node(svn_sqlite__db_t *sd
SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, working_node->checksum,
scratch_pool));
- if (working_node->properties)
+ if (working_node->properties) /* ### Never set, props done later */
SVN_ERR(svn_sqlite__bind_properties(stmt, 15, working_node->properties,
scratch_pool));
@@ -1794,7 +1668,6 @@ insert_working_node(svn_sqlite__db_t *sd
SVN_ERR(svn_sqlite__bind_int64(stmt, 16, working_node->translated_size));
SVN_ERR(svn_sqlite__insert(NULL, stmt));
-#endif
return SVN_NO_ERROR;
}
@@ -1839,23 +1712,29 @@ insert_actual_node(svn_sqlite__db_t *sdb
return svn_error_return(svn_sqlite__insert(NULL, stmt));
}
+struct write_baton {
+ db_base_node_t *base;
+ db_working_node_t *work;
+};
+
/* Write the information for ENTRY to WC_DB. The WC_ID, REPOS_ID and
REPOS_ROOT will all be used for writing ENTRY.
### transitioning from straight sql to using the wc_db APIs. For the
### time being, we'll need both parameters. */
static svn_error_t *
-write_entry(svn_wc__db_t *db,
+write_entry(struct write_baton **entry_node,
+ struct write_baton *parent_node,
+ svn_wc__db_t *db,
svn_sqlite__db_t *sdb,
apr_int64_t wc_id,
apr_int64_t repos_id,
- const char *repos_root,
const svn_wc_entry_t *entry,
const char *local_relpath,
const char *entry_abspath,
const svn_wc_entry_t *this_dir,
- svn_boolean_t always_create_actual,
svn_boolean_t create_locks,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
db_base_node_t *base_node = NULL;
@@ -1868,34 +1747,118 @@ write_entry(svn_wc__db_t *db,
else
parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
+ /* This is how it should work, it doesn't work like this yet because
+ we need proper op_depth to layer the working nodes.
+
+ Using "svn add", "svn rm", "svn cp" only files can be replaced
+ pre-wcng; directories can only be normal, deleted or added.
+ Files cannot be replaced within a deleted directory, so replaced
+ files can only exist in a normal directory, or a directory that
+ is added+copied. In a normal directory a replaced file needs a
+ base node and a working node, in an added+copied directory a
+ replaced file needs two working nodes at different op-depths.
+
+ With just the above operations the conversion for files and
+ directories is straightforward:
+
+ pre-wcng wcng
+ parent child parent child
+
+ normal normal base base
+ add+copied normal+copied work work
+ normal+copied normal+copied work work
+ normal delete base base+work
+ delete delete base+work base+work
+ add+copied delete work work
+ normal add base work
+ add add work work
+ add+copied add work work
+ normal add+copied base work
+ add add+copied work work
+ add+copied add+copied work work
+ normal replace base base+work
+ add+copied replace work work+work
+ normal replace+copied base base+work
+ add+copied replace+copied work work+work
+
+ However "svn merge" make this more complicated. The pre-wcng
+ "svn merge" is capable of replacing a directory, that is it can
+ mark the whole tree deleted, and then copy another tree on top.
+ The entries then represent the replacing tree overlayed on the
+ deleted tree.
+
+ original replace schedule in
+ tree tree combined tree
+
+ A A replace+copied
+ A/f delete+copied
+ A/g A/g replace+copied
+ A/h add+copied
+ A/B A/B replace+copied
+ A/B/f delete+copied
+ A/B/g A/B/g replace+copied
+ A/B/h add+copied
+ A/C delete+copied
+ A/C/f delete+copied
+ A/D add+copied
+ A/D/f add+copied
+
+ The original tree could be normal tree, or an add+copied tree.
+ Committing such a merge generally worked, but making further tree
+ modifications before commit sometimes failed.
+
+ The root of the replace is handled like the file replace:
+
+ pre-wcng wcng
+ parent child parent child
+
+ normal replace+copied base base+work
+ add+copied replace+copied work work+work
+
+ although obviously the node is a directory rather then a file.
+ There are then more conversion states where the parent is
+ replaced.
+
+ pre-wcng wcng
+ parent child parent child
+
+ replace+copied add [base|work]+work work
+ replace+copied add+copied [base|work]+work work
+ replace+copied delete+copied [base|work]+work [base|work]+work
+ delete+copied delete+copied [base|work]+work [base|work]+work
+ replace+copied replace+copied [base|work]+work [base|work]+work
+ */
+
switch (entry->schedule)
{
case svn_wc_schedule_normal:
if (entry->copied)
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
else
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ base_node = MAYBE_ALLOC(base_node, result_pool);
break;
case svn_wc_schedule_add:
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
break;
case svn_wc_schedule_delete:
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
/* If the entry is part of a REPLACED (not COPIED) subtree,
then it needs a BASE node. */
- if (! (entry->copied
- || (this_dir->copied
- && (this_dir->schedule == svn_wc_schedule_add ||
- this_dir->schedule == svn_wc_schedule_delete ||
- this_dir->schedule == svn_wc_schedule_replace))))
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ if (parent_node->base
+ && (! (entry->copied
+ || (this_dir->copied
+ && (this_dir->schedule == svn_wc_schedule_add ||
+ this_dir->schedule == svn_wc_schedule_delete ||
+ this_dir->schedule == svn_wc_schedule_replace)))))
+ base_node = MAYBE_ALLOC(base_node, result_pool);
break;
case svn_wc_schedule_replace:
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
+ if (parent_node->base)
+ base_node = MAYBE_ALLOC(base_node, result_pool);
break;
}
@@ -1903,21 +1866,21 @@ write_entry(svn_wc__db_t *db,
BASE node to indicate the not-present node. */
if (entry->deleted)
{
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ base_node = MAYBE_ALLOC(base_node, result_pool);
}
if (entry->copied)
{
/* Make sure we get a WORKING_NODE inserted. The copyfrom information
will occur here or on a parent, as appropriate. */
- working_node = MAYBE_ALLOC(working_node, scratch_pool);
+ working_node = MAYBE_ALLOC(working_node, result_pool);
if (entry->copyfrom_url)
{
const char *relative_url;
working_node->copyfrom_repos_id = repos_id;
- relative_url = svn_uri_is_child(repos_root, entry->copyfrom_url,
+ relative_url = svn_uri_is_child(this_dir->repos, entry->copyfrom_url,
NULL);
if (relative_url == NULL)
working_node->copyfrom_repos_path = "";
@@ -1925,60 +1888,31 @@ write_entry(svn_wc__db_t *db,
{
/* copyfrom_repos_path is NOT a URI. decode into repos path. */
working_node->copyfrom_repos_path =
- svn_path_uri_decode(relative_url, scratch_pool);
+ svn_path_uri_decode(relative_url, result_pool);
}
working_node->copyfrom_revnum = entry->copyfrom_rev;
+#ifdef SVN_WC__OP_DEPTH
+ working_node->op_depth
+ = svn_wc__db_op_depth_for_upgrade(local_relpath);
+#else
+ working_node->op_depth = 2; /* ### temporary op_depth */
+#endif
}
- else
+ else if (parent_node->work && parent_node->work->copyfrom_repos_path)
{
- const char *parent_abspath = svn_dirent_dirname(entry_abspath,
- scratch_pool);
- const char *op_root_abspath;
- const char *original_repos_relpath;
- svn_revnum_t original_revision;
- svn_error_t *err;
-
- /* The parent will *always* have info in the WORKING tree, since
- we've been designated as COPIED but do not have our own
- COPYFROM information. Therefore, our parent or a more distant
- ancestor has that information. Grab the data. */
- err = svn_wc__db_scan_addition(
- NULL,
- &op_root_abspath,
- NULL, NULL, NULL,
- &original_repos_relpath, NULL, NULL, &original_revision,
- db,
- parent_abspath,
- scratch_pool, scratch_pool);
-
- /* We could be reading the entries while in a transitional state
- during an add/copy operation. The scan_addition *does* throw
- errors sometimes. So clear anything that may come out of it,
- and perform the copyfrom construction only when it looks like
- we have a good/real set of return values. */
- svn_error_clear(err);
-
- /* We may have been copied from a mixed-rev working copy. We need
- to simulate additional copies around revision changes. The old
- code could separately store the revision, but NG needs to create
- copies at each change. */
- if (err == NULL
- && op_root_abspath != NULL
- && original_repos_relpath != NULL
- && SVN_IS_VALID_REVNUM(original_revision)
- /* above is valid result testing. below is the key test. */
- && original_revision != entry->revision)
- {
- const char *relpath_to_entry = svn_dirent_is_child(
- op_root_abspath, entry_abspath, NULL);
- const char *new_copyfrom_relpath = svn_relpath_join(
- original_repos_relpath, relpath_to_entry, scratch_pool);
-
- working_node->copyfrom_repos_id = repos_id;
- working_node->copyfrom_repos_path = new_copyfrom_relpath;
- working_node->copyfrom_revnum = entry->revision;
- }
+ working_node->copyfrom_repos_id = repos_id;
+ working_node->copyfrom_repos_path
+ = svn_relpath_join(parent_node->work->copyfrom_repos_path,
+ svn_relpath_basename(local_relpath, NULL),
+ result_pool);
+ working_node->copyfrom_revnum = parent_node->work->copyfrom_revnum;
+ working_node->op_depth = parent_node->work->op_depth;
}
+ else
+ return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
+ _("No copyfrom URL for '%s'"),
+ svn_dirent_local_style(local_relpath,
+ scratch_pool));
}
if (entry->keep_local)
@@ -2025,9 +1959,10 @@ write_entry(svn_wc__db_t *db,
if (entry->file_external_path != NULL)
{
- base_node = MAYBE_ALLOC(base_node, scratch_pool);
+ base_node = MAYBE_ALLOC(base_node, result_pool);
}
+
/* Insert the base node. */
if (base_node)
{
@@ -2083,16 +2018,16 @@ write_entry(svn_wc__db_t *db,
base_node->checksum = NULL;
else
SVN_ERR(svn_checksum_parse_hex(&base_node->checksum, svn_checksum_md5,
- entry->checksum, scratch_pool));
+ entry->checksum, result_pool));
- if (repos_root)
+ if (this_dir->repos)
{
base_node->repos_id = repos_id;
/* repos_relpath is NOT a URI. decode as appropriate. */
if (entry->url != NULL)
{
- const char *relative_url = svn_uri_is_child(repos_root,
+ const char *relative_url = svn_uri_is_child(this_dir->repos,
entry->url,
scratch_pool);
@@ -2100,11 +2035,11 @@ write_entry(svn_wc__db_t *db,
base_node->repos_relpath = "";
else
base_node->repos_relpath = svn_path_uri_decode(relative_url,
- scratch_pool);
+ result_pool);
}
else
{
- const char *base_path = svn_uri_is_child(repos_root,
+ const char *base_path = svn_uri_is_child(this_dir->repos,
this_dir->url,
scratch_pool);
if (base_path == NULL)
@@ -2113,7 +2048,7 @@ write_entry(svn_wc__db_t *db,
base_node->repos_relpath =
svn_dirent_join(svn_path_uri_decode(base_path, scratch_pool),
entry->name,
- scratch_pool);
+ result_pool);
}
}
@@ -2157,24 +2092,13 @@ write_entry(svn_wc__db_t *db,
&entry->file_external_rev,
scratch_pool));
-#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_UPDATE_FILE_EXTERNAL));
SVN_ERR(svn_sqlite__bindf(stmt, "iss",
- (apr_uint64_t)1 /* wc_id */,
+ (apr_int64_t)1 /* wc_id */,
entry->name,
str));
SVN_ERR(svn_sqlite__step_done(stmt));
-#endif
-#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPDATE_FILE_EXTERNAL_1));
- SVN_ERR(svn_sqlite__bindf(stmt, "iss",
- (apr_uint64_t)1 /* wc_id */,
- entry->name,
- str));
- SVN_ERR(svn_sqlite__step_done(stmt));
-#endif
}
}
@@ -2201,7 +2125,7 @@ write_entry(svn_wc__db_t *db,
else
SVN_ERR(svn_checksum_parse_hex(&working_node->checksum,
svn_checksum_md5,
- entry->checksum, scratch_pool));
+ entry->checksum, result_pool));
/* All subdirs start of incomplete, and stop being incomplete
when the entries file in the subdir is upgraded. */
@@ -2227,7 +2151,8 @@ write_entry(svn_wc__db_t *db,
/* If the entry is part of a COPIED (not REPLACED) subtree,
then the deletion is referring to the WORKING node, not
the BASE node. */
- if (entry->copied
+ if (!base_node
+ || entry->copied
|| (this_dir->copied
&& this_dir->schedule == svn_wc_schedule_add))
working_node->presence = svn_wc__db_status_not_present;
@@ -2262,11 +2187,24 @@ write_entry(svn_wc__db_t *db,
working_node->changed_date = entry->cmt_date;
working_node->changed_author = entry->cmt_author;
+ if (!entry->copied)
+ {
+ if (parent_node->work)
+ working_node->op_depth = parent_node->work->op_depth;
+ else
+#ifdef SVN_WC__OP_DEPTH
+ working_node->op_depth
+ = svn_wc__db_op_depth_for_upgrade(local_relpath);
+#else
+ working_node->op_depth = 2; /* ### temporary op_depth */
+#endif
+ }
+
SVN_ERR(insert_working_node(sdb, working_node, scratch_pool));
}
/* Insert the actual node. */
- if (actual_node || always_create_actual)
+ if (actual_node)
{
actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
@@ -2277,6 +2215,13 @@ write_entry(svn_wc__db_t *db,
SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
}
+ if (entry_node)
+ {
+ *entry_node = apr_palloc(result_pool, sizeof(*entry_node));
+ (*entry_node)->base = base_node;
+ (*entry_node)->work = working_node;
+ }
+
return SVN_NO_ERROR;
}
@@ -2288,6 +2233,9 @@ struct entries_write_baton
const char *dir_abspath;
const char *new_root_abspath;
apr_hash_t *entries;
+ struct write_baton *parent_node;
+ struct write_baton *dir_node;
+ apr_pool_t *result_pool;
};
/* Writes entries inside a sqlite transaction
@@ -2304,7 +2252,7 @@ entries_write_new_cb(void *baton,
const svn_wc_entry_t *this_dir;
apr_hash_index_t *hi;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- const char *repos_root, *old_root_abspath, *dir_relpath;
+ const char *old_root_abspath, *dir_relpath;
/* Get a copy of the "this dir" entry for comparison purposes. */
this_dir = apr_hash_get(ewb->entries, SVN_WC_ENTRY_THIS_DIR,
@@ -2316,8 +2264,6 @@ entries_write_new_cb(void *baton,
_("No default entry in directory '%s'"),
svn_dirent_local_style(dir_abspath,
iterpool));
- repos_root = this_dir->repos;
-
old_root_abspath = svn_dirent_get_longest_ancestor(dir_abspath,
new_root_abspath,
scratch_pool);
@@ -2327,12 +2273,11 @@ entries_write_new_cb(void *baton,
dir_relpath = svn_dirent_skip_ancestor(old_root_abspath, dir_abspath);
/* Write out "this dir" */
- SVN_ERR(write_entry(db, sdb, ewb->wc_id, ewb->repos_id, repos_root,
- this_dir,
- dir_relpath,
+ SVN_ERR(write_entry(&ewb->dir_node, ewb->parent_node, db, sdb,
+ ewb->wc_id, ewb->repos_id, this_dir, dir_relpath,
svn_dirent_join(new_root_abspath, dir_relpath,
scratch_pool),
- this_dir, FALSE, FALSE, iterpool));
+ this_dir, FALSE, ewb->result_pool, iterpool));
for (hi = apr_hash_first(scratch_pool, ewb->entries); hi;
hi = apr_hash_next(hi))
@@ -2351,14 +2296,12 @@ entries_write_new_cb(void *baton,
use this function for upgrading old working copies. */
child_abspath = svn_dirent_join(dir_abspath, name, iterpool);
child_relpath = svn_dirent_skip_ancestor(old_root_abspath, child_abspath);
- SVN_ERR(write_entry(db, sdb, ewb->wc_id, ewb->repos_id, repos_root,
- this_entry,
- child_relpath,
+ SVN_ERR(write_entry(NULL, ewb->dir_node, db, sdb,
+ ewb->wc_id, ewb->repos_id,
+ this_entry, child_relpath,
svn_dirent_join(new_root_abspath, child_relpath,
scratch_pool),
- this_dir,
- FALSE, TRUE,
- iterpool));
+ this_dir, TRUE, iterpool, iterpool));
}
svn_pool_destroy(iterpool);
@@ -2367,13 +2310,16 @@ entries_write_new_cb(void *baton,
svn_error_t *
-svn_wc__write_upgraded_entries(svn_wc__db_t *db,
+svn_wc__write_upgraded_entries(void **dir_baton,
+ void *parent_baton,
+ svn_wc__db_t *db,
svn_sqlite__db_t *sdb,
apr_int64_t repos_id,
apr_int64_t wc_id,
const char *dir_abspath,
const char *new_root_abspath,
apr_hash_t *entries,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
struct entries_write_baton ewb;
@@ -2384,12 +2330,17 @@ svn_wc__write_upgraded_entries(svn_wc__d
ewb.dir_abspath = dir_abspath;
ewb.new_root_abspath = new_root_abspath;
ewb.entries = entries;
+ ewb.parent_node = parent_baton;
+ ewb.result_pool = result_pool;
/* Run this operation in a transaction to speed up SQLite.
See http://www.sqlite.org/faq.html#q19 for more details */
- return svn_error_return(
- svn_sqlite__with_transaction(sdb, entries_write_new_cb, &ewb,
- scratch_pool));
+ SVN_ERR(svn_sqlite__with_transaction(sdb, entries_write_new_cb, &ewb,
+ scratch_pool));
+
+ *dir_baton = ewb.dir_node;
+
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.h?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.h (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/entries.h Thu Dec 2 20:55:08 2010
@@ -87,15 +87,21 @@ svn_wc__read_entries_old(apr_hash_t **en
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* For internal use by upgrade.c to write entries in the wc-ng format. */
+/* For internal use by upgrade.c to write entries in the wc-ng format.
+ Return in DIR_BATON the baton to be passed as PARENT_BATON when
+ upgrading child directories. Pass a NULL PARENT_BATON when upgrading
+ the root directory. */
svn_error_t *
-svn_wc__write_upgraded_entries(svn_wc__db_t *db,
+svn_wc__write_upgraded_entries(void **dir_baton,
+ void *parent_baton,
+ svn_wc__db_t *db,
svn_sqlite__db_t *sdb,
apr_int64_t repos_id,
apr_int64_t wc_id,
const char *dir_abspath,
const char *new_root_abspath,
apr_hash_t *entries,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
/* Parse a file external specification in the NULL terminated STR and
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/node.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/node.c Thu Dec 2 20:55:08 2010
@@ -1122,14 +1122,22 @@ svn_wc__node_get_lock_info(const char **
apr_pool_t *scratch_pool)
{
svn_wc__db_lock_t *lock;
+ svn_error_t *err;
- SVN_ERR(svn_wc__db_read_info(NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, &lock,
- wc_ctx->db, local_abspath,
- result_pool, scratch_pool));
+ err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &lock,
+ wc_ctx->db, local_abspath,
+ result_pool, scratch_pool);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_return(err);
+
+ svn_error_clear(err);
+ lock = NULL;
+ }
if (lock_token)
*lock_token = lock ? lock->token : NULL;
if (lock_owner)
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/props.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/props.c Thu Dec 2 20:55:08 2010
@@ -139,30 +139,9 @@ svn_wc__get_prejfile_abspath(const char
static svn_error_t *
immediate_install_props(svn_wc__db_t *db,
const char *local_abspath,
- svn_wc__db_kind_t kind,
apr_hash_t *working_props,
apr_pool_t *scratch_pool)
{
- apr_hash_t *base_props;
-
- /* ### no pristines should be okay. */
- SVN_ERR_W(svn_wc__db_read_pristine_props(&base_props, db, local_abspath,
- scratch_pool, scratch_pool),
- _("Failed to load pristine properties"));
-
- /* Check if the props are modified. If no changes, then wipe out
- the ACTUAL props. No pristines defined means that any ACTUAL
- props are okay, so go ahead and set them. */
- if (base_props != NULL)
- {
- apr_array_header_t *prop_diffs;
-
- SVN_ERR(svn_prop_diffs(&prop_diffs, working_props, base_props,
- scratch_pool));
- if (prop_diffs->nelts == 0)
- working_props = NULL;
- }
-
SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
working_props,
NULL /* conflict */,
@@ -350,7 +329,6 @@ svn_wc__perform_props_merge(svn_wc_notif
{
svn_wc__db_status_t status;
svn_boolean_t have_base;
- apr_array_header_t *prop_diffs;
SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -365,41 +343,18 @@ svn_wc__perform_props_merge(svn_wc_notif
SVN_ERR(svn_wc__db_temp_base_set_props(db, local_abspath,
new_base_props, pool));
- /* Check if the props are modified. */
- SVN_ERR(svn_prop_diffs(&prop_diffs, actual_props, new_base_props, pool));
-
- /* Save the actual properties file if it differs from base. */
- if (prop_diffs->nelts == 0)
- SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, NULL, NULL, NULL,
- pool));
- else
- SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
- NULL, NULL, pool));
+ SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
+ NULL, NULL, pool));
}
#else
if (base_merge)
return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
U_("base_merge=TRUE is no longer supported"));
- {
- apr_array_header_t *prop_diffs;
-
- SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
- pool));
-
- /* Save the actual properties file if it differs from base. */
- if (prop_diffs->nelts == 0)
- new_actual_props = NULL; /* Remove actual properties*/
-
- /* For the old school: write the properties into the "working"
- (aka ACTUAL) location. Note that PROPS may be NULL, indicating
- a removal of the props file. */
-
- SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
- NULL /* conflict */,
- NULL /* work_item */,
- pool));
- }
+ SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
+ NULL /* conflict */,
+ NULL /* work_item */,
+ pool));
#endif
SVN_ERR(svn_wc__wq_run(db, local_abspath,
@@ -1622,7 +1577,8 @@ svn_wc__merge_props(svn_wc_notify_state_
SVN_ERR(svn_wc__wq_tmp_build_set_property_conflict_marker(
&work_item,
db, local_abspath,
- svn_dirent_basename(reject_path, NULL),
+ svn_dirent_basename(reject_path,
+ NULL),
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
@@ -2185,7 +2141,7 @@ svn_wc__internal_propset(svn_wc__db_t *d
/* Drop it right onto the disk. We don't need loggy since we aren't
coordinating this change with anything else. */
- SVN_ERR(immediate_install_props(db, local_abspath, kind, prophash,
+ SVN_ERR(immediate_install_props(db, local_abspath, prophash,
scratch_pool));
if (notify_func)
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/relocate.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/relocate.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/relocate.c Thu Dec 2 20:55:08 2010
@@ -82,9 +82,9 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
{
svn_wc__db_kind_t kind;
const char *repos_relpath;
- const char *old_repos_root;
- const char *old_url;
- const char *new_repos_root;
+ const char *old_repos_root, *old_url;
+ const char *new_repos_root, *new_url;
+ int from_len, old_url_len;
const char *uuid;
svn_boolean_t is_wc_root;
@@ -129,16 +129,28 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
_("Cannot relocate a single file"));
old_url = svn_uri_join(old_repos_root, repos_relpath, scratch_pool);
- if (strcmp(old_url, from) != 0)
- return svn_error_create(SVN_ERR_WC_INVALID_RELOCATION, NULL,
- _("Given source URL invalid"));
+ old_url_len = strlen(old_url);
+ from_len = strlen(from);
+ if ((from_len > old_url_len) || (strncmp(old_url, from, strlen(from)) != 0))
+ return svn_error_createf(SVN_ERR_WC_INVALID_RELOCATION, NULL,
+ _("Invalid source URL prefix: '%s' (does not "
+ "overlap target's URL '%s')"),
+ from, old_url);
+
+ if (old_url_len == from_len)
+ new_url = to;
+ else
+ new_url = apr_pstrcat(scratch_pool, to, old_url + from_len, NULL);
+ if (! svn_path_is_url(new_url))
+ return svn_error_createf(SVN_ERR_WC_INVALID_RELOCATION, NULL,
+ _("Invalid destination URL: '%s'"), new_url);
- new_repos_root = uri_remove_components(to, repos_relpath, scratch_pool);
+ new_repos_root = uri_remove_components(new_url, repos_relpath, scratch_pool);
if (!new_repos_root)
return svn_error_createf(SVN_ERR_WC_INVALID_RELOCATION, NULL,
- _("Given destination URL invalid: '%s'"), to);
+ _("Invalid destination URL: '%s'"), new_url);
- SVN_ERR(validator(validator_baton, uuid, to, new_repos_root, scratch_pool));
+ SVN_ERR(validator(validator_baton, uuid, new_url, new_repos_root, scratch_pool));
return svn_error_return(svn_wc__db_global_relocate(wc_ctx->db, local_abspath,
new_repos_root,