summaryrefslogtreecommitdiff
path: root/subversion/libsvn_wc/entries.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_wc/entries.c')
-rw-r--r--subversion/libsvn_wc/entries.c422
1 files changed, 269 insertions, 153 deletions
diff --git a/subversion/libsvn_wc/entries.c b/subversion/libsvn_wc/entries.c
index c4517b0..24dae50 100644
--- a/subversion/libsvn_wc/entries.c
+++ b/subversion/libsvn_wc/entries.c
@@ -34,9 +34,11 @@
#include "svn_path.h"
#include "svn_ctype.h"
#include "svn_string.h"
+#include "svn_hash.h"
#include "wc.h"
#include "adm_files.h"
+#include "conflicts.h"
#include "entries.h"
#include "lock.h"
#include "tree_conflicts.h"
@@ -55,22 +57,23 @@
typedef struct db_node_t {
apr_int64_t wc_id;
const char *local_relpath;
- apr_int64_t op_depth;
+ int op_depth;
apr_int64_t repos_id;
const char *repos_relpath;
const char *parent_relpath;
svn_wc__db_status_t presence;
svn_revnum_t revision;
- svn_node_kind_t kind; /* ### should switch to svn_wc__db_kind_t */
+ svn_node_kind_t kind;
svn_checksum_t *checksum;
- svn_filesize_t translated_size;
+ svn_filesize_t recorded_size;
svn_revnum_t changed_rev;
apr_time_t changed_date;
const char *changed_author;
svn_depth_t depth;
- apr_time_t last_mod_time;
+ apr_time_t recorded_time;
apr_hash_t *properties;
svn_boolean_t file_external;
+ apr_array_header_t *inherited_props;
} db_node_t;
typedef struct db_actual_node_t {
@@ -148,7 +151,7 @@ check_file_external(svn_wc_entry_t *entry,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
- svn_wc__db_kind_t kind;
+ svn_node_kind_t kind;
const char *repos_relpath;
svn_revnum_t peg_revision;
svn_revnum_t revision;
@@ -169,7 +172,7 @@ check_file_external(svn_wc_entry_t *entry,
}
if (status == svn_wc__db_status_normal
- && kind == svn_wc__db_kind_file)
+ && kind == svn_node_file)
{
entry->file_external_path = repos_relpath;
if (SVN_IS_VALID_REVNUM(peg_revision))
@@ -204,9 +207,10 @@ check_file_external(svn_wc_entry_t *entry,
*/
static svn_error_t *
get_info_for_deleted(svn_wc_entry_t *entry,
- svn_wc__db_kind_t *kind,
+ svn_node_kind_t *kind,
const char **repos_relpath,
const svn_checksum_t **checksum,
+ svn_wc__db_lock_t **lock,
svn_wc__db_t *db,
const char *entry_abspath,
const svn_wc_entry_t *parent_entry,
@@ -229,22 +233,13 @@ get_info_for_deleted(svn_wc_entry_t *entry,
&entry->depth,
checksum,
NULL,
- NULL /* lock */,
- &entry->has_props,
+ lock,
+ &entry->has_props, NULL,
NULL,
db,
entry_abspath,
result_pool,
scratch_pool));
-
- if (*repos_relpath == NULL)
- SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath,
- &entry->repos,
- &entry->uuid,
- db,
- entry_abspath,
- result_pool,
- scratch_pool));
}
else
{
@@ -263,7 +258,7 @@ get_info_for_deleted(svn_wc_entry_t *entry,
&entry->depth,
checksum,
NULL,
- &entry->has_props,
+ &entry->has_props, NULL,
db,
entry_abspath,
result_pool,
@@ -272,7 +267,7 @@ get_info_for_deleted(svn_wc_entry_t *entry,
SVN_ERR(svn_wc__db_scan_deletion(NULL,
NULL,
- &work_del_abspath,
+ &work_del_abspath, NULL,
db, entry_abspath,
scratch_pool, scratch_pool));
@@ -304,7 +299,8 @@ get_info_for_deleted(svn_wc_entry_t *entry,
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_base_get_info(&status, NULL, &entry->revision,
NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, lock, NULL, NULL,
+ NULL,
db, entry_abspath,
result_pool, scratch_pool));
@@ -384,7 +380,7 @@ read_one_entry(const svn_wc_entry_t **new_entry,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_wc__db_kind_t kind;
+ svn_node_kind_t kind;
svn_wc__db_status_t status;
svn_wc__db_lock_t *lock;
const char *repos_relpath;
@@ -461,9 +457,10 @@ read_one_entry(const svn_wc_entry_t **new_entry,
child_abspath = svn_dirent_join(dir_abspath, child_name,
scratch_pool);
- SVN_ERR(svn_wc__db_read_conflicts(&child_conflicts,
- db, child_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__read_conflicts(&child_conflicts,
+ db, child_abspath,
+ FALSE /* create tempfiles */,
+ scratch_pool, scratch_pool));
for (j = 0; j < child_conflicts->nelts; j++)
{
@@ -475,8 +472,7 @@ read_one_entry(const svn_wc_entry_t **new_entry,
{
if (!tree_conflicts)
tree_conflicts = apr_hash_make(scratch_pool);
- apr_hash_set(tree_conflicts, child_name,
- APR_HASH_KEY_STRING, conflict);
+ svn_hash_sets(tree_conflicts, child_name, conflict);
}
}
}
@@ -525,7 +521,7 @@ read_one_entry(const svn_wc_entry_t **new_entry,
{
const char *work_del_abspath;
SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
- &work_del_abspath,
+ &work_del_abspath, NULL,
db, entry_abspath,
scratch_pool, scratch_pool));
@@ -572,7 +568,7 @@ read_one_entry(const svn_wc_entry_t **new_entry,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
- NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
db, entry_abspath,
scratch_pool,
scratch_pool));
@@ -637,7 +633,10 @@ read_one_entry(const svn_wc_entry_t **new_entry,
/* ### scan_addition may need to be updated to avoid returning
### status_copied in this case. */
}
- else if (work_status == svn_wc__db_status_copied)
+ /* For backwards-compatiblity purposes we treat moves just like
+ * regular copies. */
+ else if (work_status == svn_wc__db_status_copied ||
+ work_status == svn_wc__db_status_moved_here)
{
entry->copied = TRUE;
@@ -662,7 +661,8 @@ read_one_entry(const svn_wc_entry_t **new_entry,
svn_boolean_t is_copied_child;
svn_boolean_t is_mixed_rev = FALSE;
- SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied);
+ SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied ||
+ work_status == svn_wc__db_status_moved_here);
/* If this node inherits copyfrom information from an
ancestor node, then it must be a copied child. */
@@ -713,8 +713,7 @@ read_one_entry(const svn_wc_entry_t **new_entry,
&parent_repos_relpath,
&parent_root_url,
NULL, NULL,
- db,
- parent_abspath,
+ db, parent_abspath,
scratch_pool,
scratch_pool);
if (err)
@@ -826,6 +825,7 @@ read_one_entry(const svn_wc_entry_t **new_entry,
&kind,
&repos_relpath,
&checksum,
+ &lock,
db, entry_abspath,
parent_entry,
have_base, have_more_work,
@@ -836,11 +836,11 @@ read_one_entry(const svn_wc_entry_t **new_entry,
if (entry->depth == svn_depth_unknown)
entry->depth = svn_depth_infinity;
- if (kind == svn_wc__db_kind_dir)
+ if (kind == svn_node_dir)
entry->kind = svn_node_dir;
- else if (kind == svn_wc__db_kind_file)
+ else if (kind == svn_node_file)
entry->kind = svn_node_file;
- else if (kind == svn_wc__db_kind_symlink)
+ else if (kind == svn_node_symlink)
entry->kind = svn_node_file; /* ### no symlink kind */
else
entry->kind = svn_node_unknown;
@@ -878,37 +878,53 @@ read_one_entry(const svn_wc_entry_t **new_entry,
if (conflicted)
{
- const apr_array_header_t *conflicts;
- int j;
- SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, entry_abspath,
- scratch_pool, scratch_pool));
+ svn_skel_t *conflict;
+ svn_boolean_t text_conflicted;
+ svn_boolean_t prop_conflicted;
+ SVN_ERR(svn_wc__db_read_conflict(&conflict, db, entry_abspath,
+ scratch_pool, scratch_pool));
- for (j = 0; j < conflicts->nelts; j++)
+ SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, &text_conflicted,
+ &prop_conflicted, NULL,
+ db, dir_abspath, conflict,
+ scratch_pool, scratch_pool));
+
+ if (text_conflicted)
{
- const svn_wc_conflict_description2_t *cd;
- cd = APR_ARRAY_IDX(conflicts, j,
- const svn_wc_conflict_description2_t *);
+ const char *my_abspath;
+ const char *their_old_abspath;
+ const char *their_abspath;
+ SVN_ERR(svn_wc__conflict_read_text_conflict(&my_abspath,
+ &their_old_abspath,
+ &their_abspath,
+ db, dir_abspath,
+ conflict, scratch_pool,
+ scratch_pool));
- switch (cd->kind)
- {
- case svn_wc_conflict_kind_text:
- if (cd->base_abspath)
- entry->conflict_old = svn_dirent_basename(cd->base_abspath,
- result_pool);
- if (cd->their_abspath)
- entry->conflict_new = svn_dirent_basename(cd->their_abspath,
- result_pool);
- if (cd->my_abspath)
- entry->conflict_wrk = svn_dirent_basename(cd->my_abspath,
- result_pool);
- break;
- case svn_wc_conflict_kind_property:
- entry->prejfile = svn_dirent_basename(cd->their_abspath,
- result_pool);
- break;
- case svn_wc_conflict_kind_tree:
- break;
- }
+ if (my_abspath)
+ entry->conflict_wrk = svn_dirent_basename(my_abspath, result_pool);
+
+ if (their_old_abspath)
+ entry->conflict_old = svn_dirent_basename(their_old_abspath,
+ result_pool);
+
+ if (their_abspath)
+ entry->conflict_new = svn_dirent_basename(their_abspath,
+ result_pool);
+ }
+
+ if (prop_conflicted)
+ {
+ const char *prej_abspath;
+
+ SVN_ERR(svn_wc__conflict_read_prop_conflict(&prej_abspath, NULL,
+ NULL, NULL, NULL,
+ db, dir_abspath,
+ conflict, scratch_pool,
+ scratch_pool));
+
+ if (prej_abspath)
+ entry->prejfile = svn_dirent_basename(prej_abspath, result_pool);
}
}
@@ -922,7 +938,7 @@ read_one_entry(const svn_wc_entry_t **new_entry,
/* Let's check for a file external. ugh. */
if (status == svn_wc__db_status_normal
- && kind == svn_wc__db_kind_file)
+ && kind == svn_node_file)
SVN_ERR(check_file_external(entry, db, entry_abspath, dir_abspath,
result_pool, scratch_pool));
@@ -956,7 +972,7 @@ read_entries_new(apr_hash_t **result_entries,
"" /* name */,
NULL /* parent_entry */,
result_pool, iterpool));
- apr_hash_set(entries, "", APR_HASH_KEY_STRING, parent_entry);
+ svn_hash_sets(entries, "", parent_entry);
/* Use result_pool so that the child names (used by reference, rather
than copied) appear in result_pool. */
@@ -973,7 +989,7 @@ read_entries_new(apr_hash_t **result_entries,
SVN_ERR(read_one_entry(&entry,
db, wc_id, local_abspath, name, parent_entry,
result_pool, iterpool));
- apr_hash_set(entries, entry->name, APR_HASH_KEY_STRING, entry);
+ svn_hash_sets(entries, entry->name, entry);
}
svn_pool_destroy(iterpool);
@@ -1350,7 +1366,7 @@ prune_deleted(apr_hash_t **entries_pruned,
SVN_ERR(svn_wc__entry_is_hidden(&hidden, entry));
if (!hidden)
- apr_hash_set(*entries_pruned, key, APR_HASH_KEY_STRING, entry);
+ svn_hash_sets(*entries_pruned, key, entry);
}
return SVN_NO_ERROR;
@@ -1376,10 +1392,10 @@ entries_read_txn(void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool)
}
svn_error_t *
-svn_wc_entries_read(apr_hash_t **entries,
- svn_wc_adm_access_t *adm_access,
- svn_boolean_t show_hidden,
- apr_pool_t *pool)
+svn_wc__entries_read_internal(apr_hash_t **entries,
+ svn_wc_adm_access_t *adm_access,
+ svn_boolean_t show_hidden,
+ apr_pool_t *pool)
{
apr_hash_t *new_entries;
@@ -1388,7 +1404,7 @@ svn_wc_entries_read(apr_hash_t **entries,
{
svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
const char *local_abspath = svn_wc__adm_access_abspath(adm_access);
- apr_pool_t *result_pool = svn_wc_adm_access_pool(adm_access);
+ apr_pool_t *result_pool = svn_wc__adm_access_pool_internal(adm_access);
svn_sqlite__db_t *sdb;
struct entries_read_baton_t erb;
@@ -1412,12 +1428,21 @@ svn_wc_entries_read(apr_hash_t **entries,
*entries = new_entries;
else
SVN_ERR(prune_deleted(entries, new_entries,
- svn_wc_adm_access_pool(adm_access),
+ svn_wc__adm_access_pool_internal(adm_access),
pool));
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_wc_entries_read(apr_hash_t **entries,
+ svn_wc_adm_access_t *adm_access,
+ svn_boolean_t show_hidden,
+ apr_pool_t *pool)
+{
+ return svn_error_trace(svn_wc__entries_read_internal(entries, adm_access,
+ show_hidden, pool));
+}
/* No transaction required: called from write_entry which is itself
transaction-wrapped. */
@@ -1431,7 +1456,7 @@ insert_node(svn_sqlite__db_t *sdb,
SVN_ERR_ASSERT(node->op_depth > 0 || node->repos_relpath);
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isisnnnnsnrisnnni",
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsnrisnnni",
node->wc_id,
node->local_relpath,
node->op_depth,
@@ -1441,7 +1466,7 @@ insert_node(svn_sqlite__db_t *sdb,
node->changed_rev,
node->changed_date,
node->changed_author,
- node->last_mod_time));
+ node->recorded_time));
if (node->repos_relpath)
{
@@ -1449,7 +1474,7 @@ insert_node(svn_sqlite__db_t *sdb,
node->repos_id));
SVN_ERR(svn_sqlite__bind_text(stmt, 6,
node->repos_relpath));
- SVN_ERR(svn_sqlite__bind_int64(stmt, 7, node->revision));
+ SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, node->revision));
}
if (node->presence == svn_wc__db_status_normal)
@@ -1463,7 +1488,7 @@ insert_node(svn_sqlite__db_t *sdb,
else if (node->presence == svn_wc__db_status_excluded)
SVN_ERR(svn_sqlite__bind_text(stmt, 8, "excluded"));
else if (node->presence == svn_wc__db_status_server_excluded)
- SVN_ERR(svn_sqlite__bind_text(stmt, 8, "absent"));
+ SVN_ERR(svn_sqlite__bind_text(stmt, 8, "server-excluded"));
if (node->kind == svn_node_none)
SVN_ERR(svn_sqlite__bind_text(stmt, 10, "unknown"));
@@ -1491,12 +1516,16 @@ insert_node(svn_sqlite__db_t *sdb,
SVN_ERR(svn_sqlite__bind_properties(stmt, 15, node->properties,
scratch_pool));
- if (node->translated_size != SVN_INVALID_FILESIZE)
- SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->translated_size));
+ if (node->recorded_size != SVN_INVALID_FILESIZE)
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->recorded_size));
if (node->file_external)
SVN_ERR(svn_sqlite__bind_int(stmt, 20, 1));
+ if (node->inherited_props)
+ SVN_ERR(svn_sqlite__bind_iprops(stmt, 23, node->inherited_props,
+ scratch_pool));
+
SVN_ERR(svn_sqlite__insert(NULL, stmt));
return SVN_NO_ERROR;
@@ -1506,10 +1535,13 @@ insert_node(svn_sqlite__db_t *sdb,
/* */
static svn_error_t *
insert_actual_node(svn_sqlite__db_t *sdb,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
const db_actual_node_t *actual_node,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
+ svn_skel_t *conflict_data = NULL;
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL_NODE));
@@ -1521,24 +1553,57 @@ insert_actual_node(svn_sqlite__db_t *sdb,
SVN_ERR(svn_sqlite__bind_properties(stmt, 4, actual_node->properties,
scratch_pool));
- if (actual_node->conflict_old)
+ if (actual_node->changelist)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->changelist));
+
+ SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw(
+ &conflict_data,
+ db, wri_abspath,
+ actual_node->local_relpath,
+ actual_node->conflict_old,
+ actual_node->conflict_working,
+ actual_node->conflict_new,
+ actual_node->prop_reject,
+ actual_node->tree_conflict_data,
+ actual_node->tree_conflict_data
+ ? strlen(actual_node->tree_conflict_data)
+ : 0,
+ scratch_pool, scratch_pool));
+
+ if (conflict_data)
{
- SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->conflict_old));
- SVN_ERR(svn_sqlite__bind_text(stmt, 6, actual_node->conflict_new));
- SVN_ERR(svn_sqlite__bind_text(stmt, 7, actual_node->conflict_working));
+ svn_stringbuf_t *data = svn_skel__unparse(conflict_data, scratch_pool);
+
+ SVN_ERR(svn_sqlite__bind_blob(stmt, 6, data->data, data->len));
}
- if (actual_node->prop_reject)
- SVN_ERR(svn_sqlite__bind_text(stmt, 8, actual_node->prop_reject));
+ /* Execute and reset the insert clause. */
+ return svn_error_trace(svn_sqlite__insert(NULL, stmt));
+}
- if (actual_node->changelist)
- SVN_ERR(svn_sqlite__bind_text(stmt, 9, actual_node->changelist));
+static svn_boolean_t
+is_switched(db_node_t *parent,
+ db_node_t *child,
+ apr_pool_t *scratch_pool)
+{
+ if (parent && child)
+ {
+ if (parent->repos_id != child->repos_id)
+ return TRUE;
- if (actual_node->tree_conflict_data)
- SVN_ERR(svn_sqlite__bind_text(stmt, 10, actual_node->tree_conflict_data));
+ if (parent->repos_relpath && child->repos_relpath)
+ {
+ const char *unswitched
+ = svn_relpath_join(parent->repos_relpath,
+ svn_relpath_basename(child->local_relpath,
+ scratch_pool),
+ scratch_pool);
+ if (strcmp(unswitched, child->repos_relpath))
+ return TRUE;
+ }
+ }
- /* Execute and reset the insert clause. */
- return svn_error_trace(svn_sqlite__insert(NULL, stmt));
+ return FALSE;
}
struct write_baton {
@@ -1548,6 +1613,15 @@ struct write_baton {
apr_hash_t *tree_conflicts;
};
+#define WRITE_ENTRY_ASSERT(expr) \
+ if (!(expr)) \
+ return svn_error_createf(SVN_ERR_ASSERTION_FAIL, NULL, \
+ _("Unable to upgrade '%s' at line %d"), \
+ svn_dirent_local_style( \
+ svn_dirent_join(root_abspath, \
+ local_relpath, \
+ scratch_pool), \
+ scratch_pool), __LINE__)
/* Write the information for ENTRY to WC_DB. The WC_ID, REPOS_ID and
REPOS_ROOT will all be used for writing ENTRY.
@@ -1663,9 +1737,10 @@ write_entry(struct write_baton **entry_node,
replace+copied replace+copied [base|work]+work [base|work]+work
*/
- SVN_ERR_ASSERT(parent_node || entry->schedule == svn_wc_schedule_normal);
- SVN_ERR_ASSERT(!parent_node || parent_node->base
- || parent_node->below_work || parent_node->work);
+ WRITE_ENTRY_ASSERT(parent_node || entry->schedule == svn_wc_schedule_normal);
+
+ WRITE_ENTRY_ASSERT(!parent_node || parent_node->base
+ || parent_node->below_work || parent_node->work);
switch (entry->schedule)
{
@@ -1710,8 +1785,8 @@ write_entry(struct write_baton **entry_node,
BASE node to indicate the not-present node. */
if (entry->deleted)
{
- SVN_ERR_ASSERT(base_node || below_working_node);
- SVN_ERR_ASSERT(!entry->incomplete);
+ WRITE_ENTRY_ASSERT(base_node || below_working_node);
+ WRITE_ENTRY_ASSERT(!entry->incomplete);
if (base_node)
base_node->presence = svn_wc__db_status_not_present;
else
@@ -1719,8 +1794,8 @@ write_entry(struct write_baton **entry_node,
}
else if (entry->absent)
{
- SVN_ERR_ASSERT(base_node && !working_node && !below_working_node);
- SVN_ERR_ASSERT(!entry->incomplete);
+ WRITE_ENTRY_ASSERT(base_node && !working_node && !below_working_node);
+ WRITE_ENTRY_ASSERT(!entry->incomplete);
base_node->presence = svn_wc__db_status_server_excluded;
}
@@ -1728,16 +1803,10 @@ write_entry(struct write_baton **entry_node,
{
if (entry->copyfrom_url)
{
- const char *relpath;
-
working_node->repos_id = repos_id;
- relpath = svn_uri__is_child(this_dir->repos,
- entry->copyfrom_url,
- result_pool);
- if (relpath == NULL)
- working_node->repos_relpath = "";
- else
- working_node->repos_relpath = relpath;
+ working_node->repos_relpath = svn_uri_skip_ancestor(
+ this_dir->repos, entry->copyfrom_url,
+ result_pool);
working_node->revision = entry->copyfrom_rev;
working_node->op_depth
= svn_wc__db_op_depth_for_upgrade(local_relpath);
@@ -1752,6 +1821,17 @@ write_entry(struct write_baton **entry_node,
working_node->revision = parent_node->work->revision;
working_node->op_depth = parent_node->work->op_depth;
}
+ else if (parent_node->below_work
+ && parent_node->below_work->repos_relpath)
+ {
+ working_node->repos_id = repos_id;
+ working_node->repos_relpath
+ = svn_relpath_join(parent_node->below_work->repos_relpath,
+ svn_relpath_basename(local_relpath, NULL),
+ result_pool);
+ working_node->revision = parent_node->below_work->revision;
+ working_node->op_depth = parent_node->below_work->op_depth;
+ }
else
return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
_("No copyfrom URL for '%s'"),
@@ -1827,7 +1907,7 @@ write_entry(struct write_baton **entry_node,
scratch_pool),
scratch_pool, scratch_pool));
- SVN_ERR_ASSERT(conflict->kind == svn_wc_conflict_kind_tree);
+ WRITE_ENTRY_ASSERT(conflict->kind == svn_wc_conflict_kind_tree);
/* Fix dubious data stored by old clients, local adds don't have
a repository URL. */
@@ -1840,9 +1920,8 @@ write_entry(struct write_baton **entry_node,
/* Store in hash to be retrieved when writing the child
row. */
key = svn_dirent_skip_ancestor(root_abspath, conflict->local_abspath);
- apr_hash_set(tree_conflicts, apr_pstrdup(result_pool, key),
- APR_HASH_KEY_STRING,
- svn_skel__unparse(new_skel, result_pool)->data);
+ svn_hash_sets(tree_conflicts, apr_pstrdup(result_pool, key),
+ svn_skel__unparse(new_skel, result_pool)->data);
skel = skel->next;
}
}
@@ -1851,9 +1930,8 @@ write_entry(struct write_baton **entry_node,
if (parent_node && parent_node->tree_conflicts)
{
- const char *tree_conflict_data = apr_hash_get(parent_node->tree_conflicts,
- local_relpath,
- APR_HASH_KEY_STRING);
+ const char *tree_conflict_data =
+ svn_hash_gets(parent_node->tree_conflicts, local_relpath);
if (tree_conflict_data)
{
actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
@@ -1862,8 +1940,7 @@ write_entry(struct write_baton **entry_node,
/* Reset hash so that we don't write the row again when writing
actual-only nodes */
- apr_hash_set(parent_node->tree_conflicts, local_relpath,
- APR_HASH_KEY_STRING, NULL);
+ svn_hash_sets(parent_node->tree_conflicts, local_relpath, NULL);
}
if (entry->file_external_path != NULL)
@@ -1880,8 +1957,8 @@ write_entry(struct write_baton **entry_node,
base_node->op_depth = 0;
base_node->parent_relpath = parent_relpath;
base_node->revision = entry->revision;
- base_node->last_mod_time = entry->text_time;
- base_node->translated_size = entry->working_size;
+ base_node->recorded_time = entry->text_time;
+ base_node->recorded_size = entry->working_size;
if (entry->depth != svn_depth_exclude)
base_node->depth = entry->depth;
@@ -1893,14 +1970,15 @@ write_entry(struct write_baton **entry_node,
if (entry->deleted)
{
- SVN_ERR_ASSERT(base_node->presence == svn_wc__db_status_not_present);
+ WRITE_ENTRY_ASSERT(base_node->presence
+ == svn_wc__db_status_not_present);
/* ### should be svn_node_unknown, but let's store what we have. */
base_node->kind = entry->kind;
}
else if (entry->absent)
{
- SVN_ERR_ASSERT(base_node->presence
- == svn_wc__db_status_server_excluded);
+ WRITE_ENTRY_ASSERT(base_node->presence
+ == svn_wc__db_status_server_excluded);
/* ### should be svn_node_unknown, but let's store what we have. */
base_node->kind = entry->kind;
@@ -1933,8 +2011,8 @@ write_entry(struct write_baton **entry_node,
else if (entry->incomplete)
{
/* ### nobody should have set the presence. */
- SVN_ERR_ASSERT(base_node->presence
- == svn_wc__db_status_normal);
+ WRITE_ENTRY_ASSERT(base_node->presence
+ == svn_wc__db_status_normal);
base_node->presence = svn_wc__db_status_incomplete;
}
}
@@ -1995,17 +2073,16 @@ write_entry(struct write_baton **entry_node,
if (entry->url != NULL)
{
- const char *relpath = svn_uri__is_child(this_dir->repos,
- entry->url,
- result_pool);
- base_node->repos_relpath = relpath ? relpath : "";
+ base_node->repos_relpath = svn_uri_skip_ancestor(
+ this_dir->repos, entry->url,
+ result_pool);
}
else
{
- const char *relpath = svn_uri__is_child(this_dir->repos,
- this_dir->url,
- scratch_pool);
- if (relpath == NULL)
+ const char *relpath = svn_uri_skip_ancestor(this_dir->repos,
+ this_dir->url,
+ scratch_pool);
+ if (relpath == NULL || *relpath == '\0')
base_node->repos_relpath = entry->name;
else
base_node->repos_relpath =
@@ -2026,6 +2103,12 @@ write_entry(struct write_baton **entry_node,
if (entry->file_external_path)
base_node->file_external = TRUE;
+ /* Switched nodes get an empty iprops cache. */
+ if (parent_node
+ && is_switched(parent_node->base, base_node, scratch_pool))
+ base_node->inherited_props
+ = apr_array_make(scratch_pool, 0, sizeof(svn_prop_inherited_item_t*));
+
SVN_ERR(insert_node(sdb, base_node, scratch_pool));
/* We have to insert the lock after the base node, because the node
@@ -2057,13 +2140,18 @@ write_entry(struct write_baton **entry_node,
below_working_node->presence = svn_wc__db_status_normal;
below_working_node->kind = entry->kind;
below_working_node->repos_id = work->repos_id;
+ below_working_node->revision = work->revision;
+
+ /* This is just guessing. If the node below would have been switched
+ or if it was updated to a different version, the guess would
+ fail. But we don't have better information pre wc-ng :( */
if (work->repos_relpath)
below_working_node->repos_relpath
- = svn_relpath_join(work->repos_relpath, entry->name,
+ = svn_relpath_join(work->repos_relpath,
+ svn_relpath_basename(local_relpath, NULL),
result_pool);
else
below_working_node->repos_relpath = NULL;
- below_working_node->revision = parent_node->work->revision;
/* The revert_base checksum isn't available in the entry structure,
so the caller provides it. */
@@ -2079,13 +2167,37 @@ write_entry(struct write_baton **entry_node,
below_working_node->checksum =
text_base_info->revert_base.sha1_checksum;
}
- below_working_node->translated_size = 0;
+ below_working_node->recorded_size = 0;
below_working_node->changed_rev = SVN_INVALID_REVNUM;
below_working_node->changed_date = 0;
below_working_node->changed_author = NULL;
below_working_node->depth = svn_depth_infinity;
- below_working_node->last_mod_time = 0;
+ below_working_node->recorded_time = 0;
below_working_node->properties = NULL;
+
+ if (working_node
+ && entry->schedule == svn_wc_schedule_delete
+ && working_node->repos_relpath)
+ {
+ /* We are lucky, our guesses above are not necessary. The known
+ correct information is in working. But our op_depth design
+ expects more information here */
+ below_working_node->repos_relpath = working_node->repos_relpath;
+ below_working_node->repos_id = working_node->repos_id;
+ below_working_node->revision = working_node->revision;
+
+ /* Nice for 'svn status' */
+ below_working_node->changed_rev = entry->cmt_rev;
+ below_working_node->changed_date = entry->cmt_date;
+ below_working_node->changed_author = entry->cmt_author;
+
+ /* And now remove it from WORKING, because in wc-ng code
+ should read it from the lower layer */
+ working_node->repos_relpath = NULL;
+ working_node->repos_id = 0;
+ working_node->revision = SVN_INVALID_REVNUM;
+ }
+
SVN_ERR(insert_node(sdb, below_working_node, scratch_pool));
}
@@ -2096,8 +2208,8 @@ write_entry(struct write_baton **entry_node,
working_node->local_relpath = local_relpath;
working_node->parent_relpath = parent_relpath;
working_node->changed_rev = SVN_INVALID_REVNUM;
- working_node->last_mod_time = entry->text_time;
- working_node->translated_size = entry->working_size;
+ working_node->recorded_time = entry->text_time;
+ working_node->recorded_size = entry->working_size;
if (entry->depth != svn_depth_exclude)
working_node->depth = entry->depth;
@@ -2157,8 +2269,8 @@ write_entry(struct write_baton **entry_node,
if (entry->incomplete)
{
/* We shouldn't be overwriting another status. */
- SVN_ERR_ASSERT(working_node->presence
- == svn_wc__db_status_normal);
+ WRITE_ENTRY_ASSERT(working_node->presence
+ == svn_wc__db_status_normal);
working_node->presence = svn_wc__db_status_incomplete;
}
}
@@ -2201,7 +2313,8 @@ write_entry(struct write_baton **entry_node,
actual_node->local_relpath = local_relpath;
actual_node->parent_relpath = parent_relpath;
- SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
+ SVN_ERR(insert_actual_node(sdb, db, tmp_entry_abspath,
+ actual_node, scratch_pool));
}
if (entry_node)
@@ -2229,6 +2342,8 @@ write_entry(struct write_baton **entry_node,
static svn_error_t *
write_actual_only_entries(apr_hash_t *tree_conflicts,
svn_sqlite__db_t *sdb,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
apr_int64_t wc_id,
const char *parent_relpath,
apr_pool_t *scratch_pool)
@@ -2247,7 +2362,8 @@ write_actual_only_entries(apr_hash_t *tree_conflicts,
actual_node->parent_relpath = parent_relpath;
actual_node->tree_conflict_data = svn__apr_hash_index_val(hi);
- SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
+ SVN_ERR(insert_actual_node(sdb, db, wri_abspath, actual_node,
+ scratch_pool));
}
return SVN_NO_ERROR;
@@ -2275,8 +2391,7 @@ svn_wc__write_upgraded_entries(void **dir_baton,
struct write_baton *dir_node;
/* Get a copy of the "this dir" entry for comparison purposes. */
- this_dir = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR,
- APR_HASH_KEY_STRING);
+ this_dir = svn_hash_gets(entries, SVN_WC_ENTRY_THIS_DIR);
/* If there is no "this dir" entry, something is wrong. */
if (! this_dir)
@@ -2307,7 +2422,7 @@ svn_wc__write_upgraded_entries(void **dir_baton,
const svn_wc_entry_t *this_entry = svn__apr_hash_index_val(hi);
const char *child_abspath, *child_relpath;
svn_wc__text_base_info_t *text_base_info
- = apr_hash_get(text_bases_info, name, APR_HASH_KEY_STRING);
+ = svn_hash_gets(text_bases_info, name);
svn_pool_clear(iterpool);
@@ -2329,8 +2444,9 @@ svn_wc__write_upgraded_entries(void **dir_baton,
}
if (dir_node->tree_conflicts)
- SVN_ERR(write_actual_only_entries(dir_node->tree_conflicts, sdb,
- wc_id, dir_relpath, iterpool));
+ SVN_ERR(write_actual_only_entries(dir_node->tree_conflicts, sdb, db,
+ new_root_abspath, wc_id, dir_relpath,
+ iterpool));
*dir_baton = dir_node;
svn_pool_destroy(iterpool);
@@ -2425,14 +2541,14 @@ walker_helper(const char *dirpath,
svn_error_t *err;
svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
- err = svn_wc_entries_read(&entries, adm_access, show_hidden, pool);
+ err = svn_wc__entries_read_internal(&entries, adm_access, show_hidden,
+ pool);
if (err)
SVN_ERR(walk_callbacks->handle_error(dirpath, err, walk_baton, pool));
/* As promised, always return the '.' entry first. */
- dot_entry = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR,
- APR_HASH_KEY_STRING);
+ dot_entry = svn_hash_gets(entries, SVN_WC_ENTRY_THIS_DIR);
if (! dot_entry)
return walk_callbacks->handle_error
(dirpath, svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
@@ -2544,7 +2660,7 @@ svn_wc_walk_entries3(const char *path,
const char *local_abspath;
svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
svn_error_t *err;
- svn_wc__db_kind_t kind;
+ svn_node_kind_t kind;
svn_depth_t depth;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
@@ -2568,7 +2684,7 @@ svn_wc_walk_entries3(const char *path,
walk_baton, pool);
}
- if (kind == svn_wc__db_kind_file || depth == svn_depth_exclude)
+ if (kind == svn_node_file || depth == svn_depth_exclude)
{
const svn_wc_entry_t *entry;
@@ -2610,7 +2726,7 @@ svn_wc_walk_entries3(const char *path,
return SVN_NO_ERROR;
}
- if (kind == svn_wc__db_kind_dir)
+ if (kind == svn_node_dir)
return walker_helper(path, adm_access, walk_callbacks, walk_baton,
walk_depth, show_hidden, cancel_func, cancel_baton,
pool);