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/04/14 08:51:03 UTC
svn commit: r933863 [3/5] - in /subversion/branches/svn-patch-improvements:
./ notes/commit-access-templates/ notes/wc-ng/
subversion/bindings/javahl/native/ subversion/bindings/swig/ruby/svn/
subversion/bindings/swig/ruby/test/ subversion/include/ sub...
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c?rev=933863&r1=933862&r2=933863&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c Wed Apr 14 06:51:00 2010
@@ -38,7 +38,6 @@
#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
-#include "svn_xml.h"
#include "svn_error.h"
#include "svn_props.h"
#include "svn_io.h"
@@ -57,7 +56,7 @@
#include "entries.h"
#include "props.h"
#include "translate.h"
-#include "lock.h"
+#include "lock.h" /* for svn_wc__write_check() */
#include "workqueue.h"
#include "svn_private_config.h"
@@ -89,7 +88,6 @@
install_props_file(): Used with loggy.
svn_wc__install_props(): Used with loggy.
svn_wc__loggy_revert_props_create(): Used with loggy.
- svn_wc__loggy_revert_props_restore(): Used with loggy.
*/
/* The real functionality here is part of libsvn_subr, in hashdump.c.
@@ -153,46 +151,6 @@ load_props(apr_hash_t **hash,
}
-/* */
-static svn_error_t *
-loggy_write_properties(svn_stringbuf_t **log_accum,
- apr_hash_t *properties,
- const char *dest_abspath,
- const char *adm_abspath,
- apr_pool_t *scratch_pool)
-{
- const char *prop_tmp_abspath;
- svn_stream_t *stream;
-
- /* Write the property hash into a temporary file. */
- SVN_ERR(svn_stream_open_unique(&stream, &prop_tmp_abspath,
- svn_dirent_dirname(dest_abspath,
- scratch_pool),
- svn_io_file_del_none,
- scratch_pool, scratch_pool));
- if (apr_hash_count(properties) != 0)
- SVN_ERR(svn_hash_write2(properties, stream, SVN_HASH_TERMINATOR,
- scratch_pool));
- SVN_ERR(svn_stream_close(stream));
-
- /* Write a log entry to move tmp file to the destination. */
- SVN_ERR(svn_wc__loggy_move(log_accum, adm_abspath,
- prop_tmp_abspath, dest_abspath,
- scratch_pool, scratch_pool));
-
- /* And make the destination read-only. */
- SVN_ERR(svn_wc__loggy_set_readonly(log_accum, adm_abspath,
- dest_abspath,
- scratch_pool, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-
-/*---------------------------------------------------------------------*/
-
-/*** Misc ***/
-
/* Opens reject temporary stream for FULL_PATH in the appropriate tmp space. */
static svn_error_t *
open_reject_tmp_stream(svn_stream_t **stream,
@@ -516,45 +474,66 @@ svn_wc__props_delete(svn_wc__db_t *db,
}
svn_error_t *
-svn_wc__loggy_revert_props_create(svn_stringbuf_t **log_accum,
- svn_wc__db_t *db,
+svn_wc__loggy_revert_props_create(svn_wc__db_t *db,
const char *local_abspath,
- const char *adm_abspath,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
svn_wc__db_kind_t kind;
+ const char *adm_abspath;
const char *revert_prop_abspath;
const char *base_prop_abspath;
svn_node_kind_t on_disk;
- SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, pool));
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, scratch_pool));
+
+ if (kind == svn_wc__db_kind_dir)
+ adm_abspath = local_abspath;
+ else
+ adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
/* TODO(#2843) The current caller ensures that PATH will not be an excluded
item. But do we really need show_hidden = TRUE here? */
SVN_ERR(svn_wc__prop_path(&revert_prop_abspath, local_abspath, kind,
- svn_wc__props_revert, pool));
+ svn_wc__props_revert, scratch_pool));
SVN_ERR(svn_wc__prop_path(&base_prop_abspath, local_abspath, kind,
- svn_wc__props_base, pool));
+ svn_wc__props_base, scratch_pool));
/* If prop base exist, move it to revert base. */
- SVN_ERR(svn_io_check_path(base_prop_abspath, &on_disk, pool));
+ SVN_ERR(svn_io_check_path(base_prop_abspath, &on_disk, scratch_pool));
if (on_disk == svn_node_file)
{
- SVN_ERR(svn_wc__loggy_move(log_accum, adm_abspath,
+ SVN_ERR(svn_wc__loggy_move(db, adm_abspath,
base_prop_abspath, revert_prop_abspath,
- pool, pool));
+ scratch_pool));
}
else if (on_disk == svn_node_none)
{
+ const char *prop_tmp_abspath;
+ svn_stream_t *stream;
+
/* If there wasn't any prop base we still need an empty revert
propfile, otherwise a revert won't know that a change to the
props needs to be made (it'll just see no file, and do nothing).
So (loggily) write out an empty revert propfile. */
- SVN_ERR(loggy_write_properties(log_accum, apr_hash_make(pool),
- revert_prop_abspath,
- adm_abspath, pool));
+ /* Create an empty file. */
+ SVN_ERR(svn_stream_open_unique(&stream, &prop_tmp_abspath,
+ svn_dirent_dirname(revert_prop_abspath,
+ scratch_pool),
+ svn_io_file_del_none,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_stream_close(stream));
+
+ /* Write a log entry to move tmp file to the destination. */
+ SVN_ERR(svn_wc__loggy_move(db, adm_abspath,
+ prop_tmp_abspath, revert_prop_abspath,
+ scratch_pool));
+
+ /* And make the destination read-only. */
+ SVN_ERR(svn_wc__loggy_set_readonly(db, adm_abspath,
+ revert_prop_abspath,
+ scratch_pool));
}
return SVN_NO_ERROR;
@@ -702,8 +681,6 @@ svn_wc_merge_props3(svn_wc_notify_state_
new_base_props, new_actual_props,
base_merge, FALSE, pool));
- /* ### add_loggy takes a DIR, but wq_run is a simple WRI_ABSPATH */
-
SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
cancel_func, cancel_baton,
pool));
@@ -1763,16 +1740,13 @@ svn_wc__merge_props(svn_wc_notify_state_
/* Mark entry as "conflicted" with a particular .prej file. */
{
- svn_stringbuf_t *log_accum = NULL;
svn_wc_entry_t entry;
entry.prejfile = svn_dirent_is_child(adm_abspath, reject_path, NULL);
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, adm_abspath,
+ SVN_ERR(svn_wc__loggy_entry_modify(db, adm_abspath,
local_abspath, &entry,
SVN_WC__ENTRY_MODIFY_PREJFILE,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__wq_add_loggy(db, adm_abspath, log_accum,
- scratch_pool));
+ scratch_pool));
}
} /* if (reject_tmp_fp) */
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c?rev=933863&r1=933862&r2=933863&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c Wed Apr 14 06:51:00 2010
@@ -138,6 +138,10 @@ compare_and_verify(svn_boolean_t *modifi
db, versioned_file_abspath,
scratch_pool, scratch_pool));
+#ifdef SVN_EXPERIMENTAL
+ /* ### node_checksum is originally MD-5 but will later be SHA-1... */
+#endif
+
if (node_checksum)
pristine_stream = svn_stream_checksummed2(pristine_stream,
&checksum, NULL,
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c?rev=933863&r1=933862&r2=933863&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c Wed Apr 14 06:51:00 2010
@@ -41,12 +41,15 @@ struct walk_baton
};
/* An svn_wc__node_found_func_t callback function for analyzing the wc
- * status of LOCAL_ABSPATH. Since it can be invoked for a lot of paths in
- * a wc but some data , i.e. if the wc is switched or has modifications, is
+ * status of LOCAL_ABSPATH. Update the status information in BATON->result.
+ * BATON is a 'struct walk_baton'.
+ *
+ * Implementation note: Since it can be invoked for a lot of paths in
+ * a wc but some data, i.e. if the wc is switched or has modifications, is
* expensive to calculate, we optimize by checking if those values are
- * already set before runnning the db operations. The found status
- * information is stored in BATON. Temporary allocations are made in
- * SCRATCH_POOL. */
+ * already set before runnning the db operations.
+ *
+ * Temporary allocations are made in SCRATCH_POOL. */
static svn_error_t *
analyze_status(const char *local_abspath,
void *baton,
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/status.c?rev=933863&r1=933862&r2=933863&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/status.c Wed Apr 14 06:51:00 2010
@@ -126,7 +126,7 @@ struct edit_baton
const apr_array_header_t *ignores;
/* Status item for the path represented by the anchor of the edit. */
- svn_wc_status2_t *anchor_status;
+ svn_wc_status3_t *anchor_status;
/* Was open_root() called for this edit drive? */
svn_boolean_t root_opened;
@@ -178,7 +178,7 @@ struct dir_baton
svn_boolean_t text_changed;
/* Working copy status structures for children of this directory.
- This hash maps const char * abspaths to svn_wc_status2_t *
+ This hash maps const char * abspaths to svn_wc_status3_t *
status items. */
apr_hash_t *statii;
@@ -188,7 +188,7 @@ struct dir_baton
/* The URI to this item in the repository. */
const char *url;
- /* out-of-date info corresponding to ood_* fields in svn_wc_status2_t. */
+ /* out-of-date info corresponding to ood_* fields in svn_wc_status3_t. */
svn_revnum_t ood_last_cmt_rev;
apr_time_t ood_last_cmt_date;
svn_node_kind_t ood_kind;
@@ -230,7 +230,7 @@ struct file_baton
/* The URI to this item in the repository. */
const char *url;
- /* out-of-date info corresponding to ood_* fields in svn_wc_status2_t. */
+ /* out-of-date info corresponding to ood_* fields in svn_wc_status3_t. */
svn_revnum_t ood_last_cmt_rev;
apr_time_t ood_last_cmt_date;
svn_node_kind_t ood_kind;
@@ -240,7 +240,7 @@ struct file_baton
/** Code **/
static svn_error_t *
-internal_status(svn_wc_status2_t **status,
+internal_status(svn_wc_status3_t **status,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
@@ -278,7 +278,7 @@ internal_status(svn_wc_status2_t **statu
non-NULL, REPOS_ROOT must contain the repository root URL of the entry.
*/
static svn_error_t *
-assemble_status(svn_wc_status2_t **status,
+assemble_status(svn_wc_status3_t **status,
svn_wc__db_t *db,
const char *local_abspath,
const svn_wc_entry_t *entry,
@@ -292,7 +292,7 @@ assemble_status(svn_wc_status2_t **statu
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_wc_status2_t *stat;
+ svn_wc_status3_t *stat;
svn_boolean_t locked_p = FALSE;
svn_boolean_t switched_p = FALSE;
const svn_wc_conflict_description2_t *tree_conflict;
@@ -636,7 +636,7 @@ send_status_structure(const struct walk_
void *status_baton,
apr_pool_t *pool)
{
- svn_wc_status2_t *statstruct;
+ svn_wc_status3_t *statstruct;
SVN_ERR(assemble_status(&statstruct, wb->db, local_abspath, entry,
parent_entry, path_kind, path_special, get_all,
@@ -644,7 +644,8 @@ send_status_structure(const struct walk_
pool, pool));
if (statstruct && status_func)
- return status_func(status_baton, local_abspath, statstruct, pool);
+ return svn_error_return((*status_func)(status_baton, local_abspath,
+ statstruct, pool));
return SVN_NO_ERROR;
}
@@ -762,7 +763,7 @@ send_unversioned_item(const struct walk_
apr_pool_t *pool)
{
svn_boolean_t ignore, is_external;
- svn_wc_status2_t *status;
+ svn_wc_status3_t *status;
ignore = svn_wc_match_ignore_list(svn_dirent_basename(local_abspath, NULL),
patterns, pool);
@@ -783,7 +784,8 @@ send_unversioned_item(const struct walk_
/* If we aren't ignoring it, or if it's an externals path, or it has a lock
in the repository, pass this entry to the status func. */
if (no_ignore || (! ignore) || is_external || status->repos_lock)
- return (status_func)(status_baton, local_abspath, status, pool);
+ return svn_error_return((*status_func)(status_baton, local_abspath, status,
+ pool));
return SVN_NO_ERROR;
}
@@ -916,7 +918,7 @@ handle_externals(const struct walk_statu
}
-/* Send svn_wc_status2_t * structures for the directory LOCAL_ABSPATH and
+/* Send svn_wc_status3_t * structures for the directory LOCAL_ABSPATH and
for all its entries through STATUS_FUNC/STATUS_BATON, or, if SELECTED
is non-NULL, only for that directory entry.
@@ -1182,14 +1184,14 @@ get_dir_status(const struct walk_status_
static svn_error_t *
hash_stash(void *baton,
const char *path,
- const svn_wc_status2_t *status,
+ const svn_wc_status3_t *status,
apr_pool_t *scratch_pool)
{
apr_hash_t *stat_hash = baton;
apr_pool_t *hash_pool = apr_hash_pool_get(stat_hash);
assert(! apr_hash_get(stat_hash, path, APR_HASH_KEY_STRING));
apr_hash_set(stat_hash, apr_pstrdup(hash_pool, path),
- APR_HASH_KEY_STRING, svn_wc_dup_status2(status, hash_pool));
+ APR_HASH_KEY_STRING, svn_wc_dup_status3(status, hash_pool));
return SVN_NO_ERROR;
}
@@ -1237,7 +1239,7 @@ tweak_statushash(void *baton,
svn_lock_t *repos_lock,
apr_pool_t *scratch_pool)
{
- svn_wc_status2_t *statstruct;
+ svn_wc_status3_t *statstruct;
apr_pool_t *pool;
apr_hash_t *statushash;
@@ -1361,7 +1363,7 @@ find_dir_url(const struct dir_baton *db,
{
const char *url;
struct dir_baton *pb = db->parent_baton;
- const svn_wc_status2_t *status = apr_hash_get(pb->statii,
+ const svn_wc_status3_t *status = apr_hash_get(pb->statii,
db->local_abspath,
APR_HASH_KEY_STRING);
/* Note that status->entry->url is NULL in the case of a missing
@@ -1392,7 +1394,7 @@ make_dir_baton(void **dir_baton,
struct edit_baton *eb = edit_baton;
struct dir_baton *d = apr_pcalloc(pool, sizeof(*d));
const char *local_abspath;
- const svn_wc_status2_t *status_in_parent;
+ const svn_wc_status3_t *status_in_parent;
SVN_ERR_ASSERT(path || (! pb));
@@ -1461,7 +1463,7 @@ make_dir_baton(void **dir_baton,
|| d->depth == svn_depth_immediates)
)
{
- const svn_wc_status2_t *this_dir_status;
+ const svn_wc_status3_t *this_dir_status;
const apr_array_header_t *ignores = eb->ignores;
SVN_ERR(get_dir_status(&eb->wb, local_abspath,
@@ -1516,7 +1518,7 @@ make_file_baton(struct dir_baton *parent
svn_boolean_t
-svn_wc__is_sendable_status(const svn_wc_status2_t *status,
+svn_wc__is_sendable_status(const svn_wc_status3_t *status,
svn_boolean_t no_ignore,
svn_boolean_t get_all)
{
@@ -1588,11 +1590,11 @@ struct status_baton
static svn_error_t *
mark_deleted(void *baton,
const char *local_abspath,
- const svn_wc_status2_t *status,
+ const svn_wc_status3_t *status,
apr_pool_t *scratch_pool)
{
struct status_baton *sb = baton;
- svn_wc_status2_t *new_status = svn_wc_dup_status2(status, scratch_pool);
+ svn_wc_status3_t *new_status = svn_wc_dup_status3(status, scratch_pool);
new_status->repos_text_status = svn_wc_status_deleted;
return sb->real_status_func(sb->real_status_baton, local_abspath,
new_status, scratch_pool);
@@ -1632,7 +1634,7 @@ handle_statii(struct edit_baton *eb,
for (hi = apr_hash_first(pool, statii); hi; hi = apr_hash_next(hi))
{
const char *path = svn__apr_hash_index_key(hi);
- svn_wc_status2_t *status = svn__apr_hash_index_val(hi);
+ svn_wc_status3_t *status = svn__apr_hash_index_val(hi);
/* Clear the subpool. */
svn_pool_clear(subpool);
@@ -1878,7 +1880,7 @@ close_directory(void *dir_baton,
if (pb && ! db->excluded)
{
svn_boolean_t was_deleted = FALSE;
- const svn_wc_status2_t *dir_status;
+ const svn_wc_status3_t *dir_status;
/* See if the directory was deleted or replaced. */
dir_status = apr_hash_get(pb->statii, db->local_abspath,
@@ -1903,7 +1905,7 @@ close_directory(void *dir_baton,
target, we should only report the target. */
if (*eb->target_basename)
{
- const svn_wc_status2_t *tgt_status;
+ const svn_wc_status3_t *tgt_status;
tgt_status = apr_hash_get(db->statii, eb->target_abspath,
APR_HASH_KEY_STRING);
@@ -2358,7 +2360,7 @@ svn_wc_get_default_ignores(apr_array_hea
/* */
static svn_error_t *
-internal_status(svn_wc_status2_t **status,
+internal_status(svn_wc_status3_t **status,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
@@ -2409,14 +2411,18 @@ internal_status(svn_wc_status2_t **statu
return svn_error_return(err);
}
- return assemble_status(status, db, local_abspath, entry,
- parent_entry, svn_node_unknown, FALSE, /* bogus */
- TRUE, FALSE, NULL, NULL, result_pool, scratch_pool);
+ return svn_error_return(assemble_status(status, db, local_abspath, entry,
+ parent_entry, svn_node_unknown,
+ FALSE /* path_special (bogus) */,
+ TRUE /* get_all */,
+ FALSE /* is_ignored */,
+ NULL, NULL,
+ result_pool, scratch_pool));
}
svn_error_t *
-svn_wc_status3(svn_wc_status2_t **status,
+svn_wc_status3(svn_wc_status3_t **status,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
@@ -2427,12 +2433,11 @@ svn_wc_status3(svn_wc_status2_t **status
scratch_pool));
}
-
-svn_wc_status2_t *
-svn_wc_dup_status2(const svn_wc_status2_t *orig_stat,
+svn_wc_status3_t *
+svn_wc_dup_status3(const svn_wc_status3_t *orig_stat,
apr_pool_t *pool)
{
- svn_wc_status2_t *new_stat = apr_palloc(pool, sizeof(*new_stat));
+ svn_wc_status3_t *new_stat = apr_palloc(pool, sizeof(*new_stat));
/* Shallow copy all members. */
*new_stat = *orig_stat;
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c?rev=933863&r1=933862&r2=933863&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c Wed Apr 14 06:51:00 2010
@@ -544,12 +544,13 @@ cleanup_dir_baton_child(void *dir_baton)
/* Return a new dir_baton to represent NAME (a subdirectory of
PARENT_BATON). If PATH is NULL, this is the root directory of the
- edit. */
+ edit. ADDING should be TRUE if we are adding this directory. */
static svn_error_t *
make_dir_baton(struct dir_baton **d_p,
const char *path,
struct edit_baton *eb,
struct dir_baton *pb,
+ svn_boolean_t adding,
apr_pool_t *scratch_pool)
{
apr_pool_t *dir_pool;
@@ -584,26 +585,38 @@ make_dir_baton(struct dir_baton **d_p,
/* Figure out the new_relpath for this directory. */
if (eb->switch_relpath)
{
- /* Switches are, shall we say, complex. If this directory is
- the root directory (it has no parent), then it either gets
- the SWITCH_URL for its own (if it is both anchor and target)
- or the parent of the SWITCH_URL (if it is anchor, but there's
- another target). */
- if (! pb)
+ /* Handle switches... */
+
+ if (pb == NULL)
{
- if (! *eb->target_basename) /* anchor is also target */
- d->new_relpath = apr_pstrdup(dir_pool, eb->switch_relpath);
+ if (*eb->target_basename == '\0')
+ {
+ /* No parent baton and target_basename=="" means that we are
+ the target of the switch. Thus, our NEW_RELPATH will be
+ the SWITCH_RELPATH. */
+ d->new_relpath = eb->switch_relpath;
+ }
else
- d->new_relpath = svn_relpath_dirname(eb->switch_relpath, dir_pool);
+ {
+ /* This node is NOT the target of the switch (one of our
+ children is the target); therefore, it must already exist.
+ Get its old REPOS_RELPATH, as it won't be changing. */
+ SVN_ERR(svn_wc__db_scan_base_repos(&d->new_relpath, NULL, NULL,
+ eb->db, d->local_abspath,
+ dir_pool, scratch_pool));
+ }
}
- /* Else this directory is *not* the root (has a parent). If it
- is the target (there is a target, and this directory has no
- grandparent), then it gets the SWITCH_URL for its own.
- Otherwise, it gets a child of its parent's URL. */
else
{
- if (*eb->target_basename && (! pb->parent_baton))
- d->new_relpath = apr_pstrdup(dir_pool, eb->switch_relpath);
+ /* This directory is *not* the root (has a parent). If there is
+ no grandparent, then we may have anchored at the parent,
+ and self is the target. If we match the target, then set
+ NEW_RELPATH to the SWITCH_RELPATH.
+
+ Otherwise, we simply extend NEW_RELPATH from the parent. */
+ if (pb->parent_baton == NULL
+ && strcmp(eb->target_basename, d->name) == 0)
+ d->new_relpath = eb->switch_relpath;
else
d->new_relpath = svn_relpath_join(pb->new_relpath, d->name,
dir_pool);
@@ -611,13 +624,22 @@ make_dir_baton(struct dir_baton **d_p,
}
else /* must be an update */
{
- /* updates are the odds ones. if we're updating a path already
- present on disk, we use its original URL. otherwise, we'll
- telescope based on its parent's URL. */
- d->new_relpath = node_get_relpath_ignore_errors(eb->db, d->local_abspath,
- dir_pool, scratch_pool);
- if ((! d->new_relpath) && pb)
- d->new_relpath = svn_relpath_join(pb->new_relpath, d->name, dir_pool);
+ /* If we are adding the node, then simply extend the parent's
+ relpath for our own. */
+ if (adding)
+ {
+ SVN_ERR_ASSERT(pb != NULL);
+ d->new_relpath = svn_relpath_join(pb->new_relpath, d->name,
+ dir_pool);
+ }
+ else
+ {
+ /* Get the original REPOS_RELPATH. An update will not be
+ changing its value. */
+ SVN_ERR(svn_wc__db_scan_base_repos(&d->new_relpath, NULL, NULL,
+ eb->db, d->local_abspath,
+ dir_pool, scratch_pool));
+ }
}
/* the bump information lives in the edit pool */
@@ -706,9 +728,10 @@ complete_directory(struct edit_baton *eb
/* If this is the root directory and there is a target, we can't
mark this directory complete. */
- if (is_root_dir && *eb->target_basename)
+ if (is_root_dir && *eb->target_basename != '\0')
{
- /* Before we can finish, we may need to clear the exclude flag for
+ /* ### obsolete comment?
+ Before we can finish, we may need to clear the exclude flag for
target. Also give a chance to the target that is explicitly pulled
in. */
svn_wc__db_kind_t kind;
@@ -717,28 +740,41 @@ complete_directory(struct edit_baton *eb
SVN_ERR_ASSERT(strcmp(local_abspath, eb->anchor_abspath) == 0);
- err = svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL,
- eb->db, eb->target_abspath, pool, pool);
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ /* Note: we are fetching information about the *target*, not self.
+ There is no guarantee that the target has a BASE node. Two examples:
+
+ 1. the node was present, but the update deleted it
+ 2. the node was not present in BASE, but locally-added, and the
+ update did not create a new BASE node "under" the local-add.
+
+ If there is no BASE node for the target, then we certainly don't
+ have to worry about removing it. */
+ err = svn_wc__db_base_get_info(&status, &kind, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ eb->db, eb->target_abspath,
+ pool, pool);
+ if (err)
{
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_return(err);
+
svn_error_clear(err);
return SVN_NO_ERROR;
}
- else if (err)
- return svn_error_return(err);
if (status == svn_wc__db_status_excluded)
{
- /* There is a small chance that the target is gone in the
+ /* ### obsolete comment?
+ There is a small chance that the target is gone in the
repository. If so, we should get rid of the entry now. */
if (kind == svn_wc__db_kind_dir &&
svn_wc__adm_missing(eb->db, eb->target_abspath, pool))
{
- /* Still passing NULL for THEIR_URL. A case where THEIR_URL
+ /* ### obsolete comment?
+ * Still passing NULL for THEIR_URL. A case where THEIR_URL
* is needed in this call is rare or even non-existant.
* ### TODO: Construct a proper THEIR_URL anyway. See also
* NULL handling code in do_entry_deletion(). */
@@ -750,77 +786,99 @@ complete_directory(struct edit_baton *eb
return SVN_NO_ERROR;
}
+ iterpool = svn_pool_create(pool);
+
/* Mark THIS_DIR complete. */
SVN_ERR(svn_wc__db_temp_op_set_base_incomplete(eb->db, local_abspath, FALSE,
- pool));
+ iterpool));
if (eb->depth_is_sticky)
{
svn_depth_t depth;
- /* ### We should specifically check BASE_NODE here and then only remove
+ /* ### obsolete comment?
+ ### We should specifically check BASE_NODE here and then only remove
the BASE_NODE if there is a WORKING_NODE. */
- SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, &depth, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL,
- eb->db, local_abspath, pool, pool));
-
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, &depth, NULL, NULL, NULL, NULL,
+ eb->db, local_abspath,
+ iterpool, iterpool));
if (depth != eb->requested_depth)
- {
- /* After a depth upgrade the entry must reflect the new depth.
- Upgrading to infinity changes the depth of *all* directories,
- upgrading to something else only changes the target. */
-
- if ((eb->requested_depth == svn_depth_infinity)
- || ((strcmp(local_abspath, eb->target_abspath) == 0)
- && eb->requested_depth > depth))
- {
- SVN_ERR(svn_wc__set_depth(eb->db, local_abspath,
- eb->requested_depth, pool));
- }
- }
+ {
+ /* After a depth upgrade the entry must reflect the new depth.
+ Upgrading to infinity changes the depth of *all* directories,
+ upgrading to something else only changes the target. */
+
+ if (eb->requested_depth == svn_depth_infinity
+ || (strcmp(local_abspath, eb->target_abspath) == 0
+ && eb->requested_depth > depth))
+ {
+ SVN_ERR(svn_wc__db_temp_op_set_dir_depth(eb->db,
+ local_abspath,
+ eb->requested_depth,
+ iterpool));
+ }
+ }
}
/* Remove any deleted or missing entries. */
- iterpool = svn_pool_create(pool);
- SVN_ERR(svn_wc__db_read_children(&children, eb->db, local_abspath, pool,
- iterpool));
+ SVN_ERR(svn_wc__db_base_get_children(&children, eb->db, local_abspath,
+ pool, iterpool));
for (i = 0; i < children->nelts; i++)
{
const char *name = APR_ARRAY_IDX(children, i, const char *);
const char *node_abspath;
- svn_wc__db_status_t status, base_status;
+ svn_wc__db_status_t status;
svn_wc__db_kind_t kind;
- svn_depth_t depth;
svn_revnum_t revnum;
- svn_boolean_t base_shadowed;
+ svn_error_t *err;
svn_pool_clear(iterpool);
node_abspath = svn_dirent_join(local_abspath, name, iterpool);
- SVN_ERR(svn_wc__db_read_info(&status, &kind, &revnum, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, &depth, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, &base_shadowed, NULL, NULL,
- eb->db, node_abspath, iterpool, iterpool));
-
- if (base_shadowed)
+ /* ### there is an edge case that we can run into right now: this
+ ### dir can have a "subdir" node in the BASE_NODE, but the
+ ### actual subdir does NOT have a record.
+ ###
+ ### in particular, copy_tests 21 and schedule_tests 10 can create
+ ### this situation. in short: the subdir is rm'd on the disk, and
+ ### a deletion of that directory is committed. a local-add then
+ ### reintroduces the directory and metadata (within WORKING).
+ ### before or after an update, the parent dir has the "subdir"
+ ### BASE_NODE and it is missing in the child. asking for the BASE
+ ### won't return status_obstructed since there is a true subdir
+ ### there now.
+ ###
+ ### at some point in the control flow, we should have removed
+ ### the "subdir" record. maybe there is a good place to remove
+ ### that record (or wait for single-dir). for now, we can correct
+ ### it when we detect it. */
+ err = svn_wc__db_base_get_info(&status, &kind, &revnum,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ eb->db, node_abspath,
+ iterpool, iterpool);
+ if (err)
{
- SVN_ERR(svn_wc__db_base_get_info(&base_status, &kind, &revnum, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- eb->db, node_abspath,
- iterpool, iterpool));
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_return(err);
+
+ svn_error_clear(err);
+
+ SVN_ERR(svn_wc__db_temp_remove_subdir_record(eb->db, node_abspath,
+ iterpool));
+ continue;
}
- else
- base_status = status;
- /* Any entry still marked as deleted (and not schedule add) can now
+ /* ### obsolete comment?
+ Any entry still marked as deleted (and not schedule add) can now
be removed -- if it wasn't undeleted by the update, then it
shouldn't stay in the updated working set. Schedule add items
should remain.
@@ -830,19 +888,15 @@ complete_directory(struct edit_baton *eb
number different from the target revision of the update means the
update never mentioned the item, so the entry should be
removed. */
- if (base_status == svn_wc__db_status_not_present ||
- (base_status == svn_wc__db_status_absent
- && (revnum != *(eb->target_revision))))
+ if (status == svn_wc__db_status_not_present
+ || (status == svn_wc__db_status_absent
+ && revnum != *eb->target_revision))
{
- if (status != svn_wc__db_status_added)
- SVN_ERR(svn_wc__entry_remove(eb->db, node_abspath, iterpool));
- else
- SVN_ERR(svn_wc__db_base_remove(eb->db, node_abspath, iterpool));
+ SVN_ERR(svn_wc__db_base_remove(eb->db, node_abspath, iterpool));
}
else if (kind == svn_wc__db_kind_dir
&& svn_wc__adm_missing(eb->db, node_abspath, iterpool)
- && base_status != svn_wc__db_status_absent
- && status != svn_wc__db_status_added)
+ && status != svn_wc__db_status_absent)
{
SVN_ERR(svn_wc__entry_remove(eb->db, node_abspath, iterpool));
@@ -1029,6 +1083,11 @@ make_file_baton(struct file_baton **f_p,
f->local_abspath,
file_pool, scratch_pool);
+ /* ### why the complicated logic above. isn't it always this way?
+ ### file externals are probably special/different? */
+ if (f->new_relpath == NULL)
+ f->new_relpath = svn_relpath_join(pb->new_relpath, f->name, file_pool);
+
f->pool = file_pool;
f->edit_baton = pb->edit_baton;
f->propchanges = apr_array_make(file_pool, 1, sizeof(svn_prop_t));
@@ -1318,7 +1377,7 @@ open_root(void *edit_baton,
edit run. */
eb->root_opened = TRUE;
- SVN_ERR(make_dir_baton(&db, NULL, eb, NULL, pool));
+ SVN_ERR(make_dir_baton(&db, NULL, eb, NULL, FALSE, pool));
*dir_baton = db;
SVN_ERR(svn_wc__db_read_kind(&kind, eb->db, db->local_abspath, TRUE, pool));
@@ -2161,7 +2220,6 @@ do_entry_deletion(struct edit_baton *eb,
if (strcmp(local_abspath, eb->target_abspath) == 0)
{
svn_wc_entry_t tmp_entry;
- svn_stringbuf_t *log_accum = NULL;
tmp_entry.revision = *(eb->target_revision);
/* ### Why not URL as well? This might be a switch. ... */
@@ -2173,14 +2231,13 @@ do_entry_deletion(struct edit_baton *eb,
tmp_entry.deleted = TRUE;
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum,
+ SVN_ERR(svn_wc__loggy_entry_modify(eb->db,
dir_abspath, local_abspath,
&tmp_entry,
SVN_WC__ENTRY_MODIFY_REVISION
| SVN_WC__ENTRY_MODIFY_KIND
| SVN_WC__ENTRY_MODIFY_DELETED,
- pool, pool));
- SVN_ERR(svn_wc__wq_add_loggy(eb->db, dir_abspath, log_accum, pool));
+ pool));
eb->target_deleted = TRUE;
}
@@ -2287,8 +2344,39 @@ add_directory(const char *path,
SVN_ERR_ASSERT((copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_revision))
|| (!copyfrom_path &&
!SVN_IS_VALID_REVNUM(copyfrom_revision)));
+ if (copyfrom_path != NULL)
+ {
+ /* ### todo: for now, this editor doesn't know how to deal with
+ copyfrom args. Someday it will interpet them as an update
+ optimization, and actually copy one part of the wc to another.
+ Then it will recursively "normalize" all the ancestry in the
+ copied tree. Someday!
+
+ Note from the future: if someday it does, we'll probably want
+ to tweak libsvn_ra_neon/fetch.c:validate_element() to accept
+ that an add-dir element can contain a delete-entry element
+ (because the dir might be added with history). Currently
+ that combination will not validate. See r30161, and see the
+ thread in which this message appears:
+
+ http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=136879
+ From: "David Glasser" <gl...@davidglasser.net>
+ To: "Karl Fogel" <kf...@red-bean.com>, dev@subversion.tigris.org
+ Cc: "Arfrever Frehtes Taifersar Arahesis" <ar...@gmail.com>,
+ glasser@tigris.org
+ Subject: Re: svn commit: r30161 - in trunk/subversion: \
+ libsvn_ra_neon tests/cmdline
+ Date: Fri, 4 Apr 2008 14:47:06 -0700
+ Message-ID: <1e...@mail.gmail.com>
+
+ */
+ return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+ _("Failed to add directory '%s': "
+ "copyfrom arguments not yet supported"),
+ svn_dirent_local_style(path, pool));
+ }
- SVN_ERR(make_dir_baton(&db, path, eb, pb, pool));
+ SVN_ERR(make_dir_baton(&db, path, eb, pb, TRUE, pool));
*child_baton = db;
if (pb->skip_descendants)
@@ -2529,40 +2617,6 @@ add_directory(const char *path,
}
}
- /* Either we got real copyfrom args... */
- if (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_revision))
- {
- /* ### todo: for now, this editor doesn't know how to deal with
- copyfrom args. Someday it will interpet them as an update
- optimization, and actually copy one part of the wc to another.
- Then it will recursively "normalize" all the ancestry in the
- copied tree. Someday!
-
- Note from the future: if someday it does, we'll probably want
- to tweak libsvn_ra_neon/fetch.c:validate_element() to accept
- that an add-dir element can contain a delete-entry element
- (because the dir might be added with history). Currently
- that combination will not validate. See r30161, and see the
- thread in which this message appears:
-
- http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=136879
- From: "David Glasser" <gl...@davidglasser.net>
- To: "Karl Fogel" <kf...@red-bean.com>, dev@subversion.tigris.org
- Cc: "Arfrever Frehtes Taifersar Arahesis" <ar...@gmail.com>,
- glasser@tigris.org
- Subject: Re: svn commit: r30161 - in trunk/subversion: \
- libsvn_ra_neon tests/cmdline
- Date: Fri, 4 Apr 2008 14:47:06 -0700
- Message-ID: <1e...@mail.gmail.com>
-
- */
- return svn_error_createf(
- SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Failed to add directory '%s': "
- "copyfrom arguments not yet supported"),
- svn_dirent_local_style(db->local_abspath, pool));
- }
- else /* ...or we got invalid copyfrom args. */
{
svn_wc_entry_t tmp_entry;
apr_uint64_t modify_flags = SVN_WC__ENTRY_MODIFY_KIND |
@@ -2673,7 +2727,7 @@ open_directory(const char *path,
svn_wc_conflict_description2_t *tree_conflict = NULL;
svn_wc__db_status_t status, base_status;
- SVN_ERR(make_dir_baton(&db, path, eb, pb, pool));
+ SVN_ERR(make_dir_baton(&db, path, eb, pb, FALSE, pool));
*child_baton = db;
/* We should have a write lock on every directory touched. */
@@ -2816,30 +2870,6 @@ externals_prop_changed(const apr_array_h
return NULL;
}
-/* This implements the svn_iter_apr_hash_cb_t callback interface.
- *
- * Add a property named KEY ('const char *') to a list of properties
- * to be deleted. BATON is the list: an 'apr_array_header_t *'
- * representing propchanges (the same type as found in struct dir_baton
- * and struct file_baton).
- *
- * Ignore KLEN, VAL, and POOL.
- */
-static svn_error_t *
-add_prop_deletion(void *baton, const void *key,
- apr_ssize_t klen, void *val,
- apr_pool_t *pool)
-{
- apr_array_header_t *propchanges = baton;
- const char *name = key;
- svn_prop_t *prop = apr_array_push(propchanges);
-
- /* Add the deletion of NAME to PROPCHANGES. */
- prop->name = name;
- prop->value = NULL;
-
- return SVN_NO_ERROR;
-}
/* Create in POOL a name->value hash from PROP_LIST, and return it. */
static apr_hash_t *
@@ -2898,6 +2928,7 @@ close_directory(void *dir_baton,
int i;
apr_hash_t *props_to_delete;
svn_wc__db_kind_t kind;
+ apr_hash_index_t *hi;
SVN_ERR(svn_wc__db_read_kind(&kind, eb->db,
db->local_abspath, TRUE, pool));
@@ -2913,8 +2944,9 @@ close_directory(void *dir_baton,
pool, pool));
}
- /* Calculate which base props weren't also in the incoming
- propchanges. */
+ /* In a copy of the BASE props, remove every property that we see an
+ incoming change for. The remaining unmentioned properties are those
+ which need to be deleted. */
props_to_delete = apr_hash_copy(pool, base_props);
for (i = 0; i < regular_props->nelts; i++)
{
@@ -2924,9 +2956,18 @@ close_directory(void *dir_baton,
APR_HASH_KEY_STRING, NULL);
}
- /* Add these props to the incoming propchanges. */
- SVN_ERR(svn_iter_apr_hash(NULL, props_to_delete, add_prop_deletion,
- regular_props, pool));
+ /* Add these props to the incoming propchanges (in regular_props). */
+ for (hi = apr_hash_first(pool, props_to_delete);
+ hi != NULL;
+ hi = apr_hash_next(hi))
+ {
+ const char *propname = svn__apr_hash_index_key(hi);
+ svn_prop_t *prop = apr_array_push(regular_props);
+
+ /* Record a deletion for PROPNAME. */
+ prop->name = propname;
+ prop->value = NULL;
+ }
}
/* If this directory has property changes stored up, now is the time
@@ -3007,19 +3048,66 @@ close_directory(void *dir_baton,
}
}
+ /* If this directory is merely an anchor for a targeted child, then we
+ should not be updating the node at all. */
+ if (db->parent_baton == NULL
+ && *eb->target_basename != '\0')
+ {
+ /* And we should not have received any changes! */
+ SVN_ERR_ASSERT(db->propchanges->nelts == 0);
+ /* ... which also implies LAST_CHANGE == NULL,
+ and NEW_BASE_PROPS == NULL. */
+ }
+ else
+ {
+ svn_depth_t depth;
+ svn_revnum_t changed_rev;
+ apr_time_t changed_date;
+ const char *changed_author;
+
+ /* ### we know a base node already exists. it was created in
+ ### open_directory or add_directory. let's just preserve the
+ ### existing depth value, and possibly changed_*. */
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ &changed_rev,
+ &changed_date,
+ &changed_author,
+ NULL, &depth, NULL, NULL, NULL, NULL,
+ eb->db, db->local_abspath,
+ pool, pool));
+
+ /* If we received any changed_* values, then use them. */
+ if (last_change)
+ {
+ changed_rev = last_change->cmt_rev;
+ changed_date = last_change->cmt_date;
+ changed_author = last_change->cmt_author;
+ }
+
+ /* ### the props thing below is probably wrong. example: maybe we
+ ### didn't get any updates, so the props should be unchanged. */
+
+ SVN_ERR(svn_wc__db_base_add_directory(
+ eb->db, db->local_abspath,
+ db->new_relpath,
+ eb->repos_root, eb->repos_uuid,
+ *eb->target_revision,
+ new_base_props ? new_base_props : apr_hash_make(pool),
+ changed_rev, changed_date, changed_author,
+ NULL /* children */,
+ depth,
+ NULL /* conflict */,
+ NULL /* work_items */,
+ pool));
+ }
+
/* Queue some items to install the properties. */
if (new_base_props || new_actual_props)
SVN_ERR(svn_wc__install_props(eb->db, db->local_abspath,
new_base_props, new_actual_props,
TRUE /* write_base_props */, TRUE, pool));
- if (last_change)
- SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, db->local_abspath,
- last_change->cmt_rev,
- last_change->cmt_date,
- last_change->cmt_author,
- pool));
-
/* Process all of the queued work items for this directory. */
SVN_ERR(svn_wc__wq_run(eb->db, db->local_abspath,
eb->cancel_func, eb->cancel_baton,
@@ -3119,6 +3207,7 @@ absent_file_or_dir(const char *path,
repos_relpath, repos_root_url,
repos_uuid, *(eb->target_revision),
db_kind, svn_wc__db_status_absent,
+ NULL, NULL,
pool));
return SVN_NO_ERROR;
@@ -4127,88 +4216,25 @@ change_file_prop(void *file_baton,
}
-
-/* Append to LOG_ACCUM, log commands to update the entry for LOCAL_ABSPATH
- with a NEW_REVISION and a NEW_RELPATH(if non-NULL), making sure
- the entry refers to a file and has no absent or deleted state.
- Use POOL for temporary allocations.
-
- ### REPOS_ROOT must be the current repository root while still using
- entries here */
-static svn_error_t *
-loggy_tweak_base_node(svn_stringbuf_t **log_accum,
- const char *local_abspath,
- svn_revnum_t new_revision,
- const char *repos_root,
- const char *new_relpath,
- apr_pool_t *pool)
-{
- /* Write log entry which will bump the revision number. Also, just
- in case we're overwriting an existing phantom 'deleted' or
- 'absent' entry, be sure to remove the hiddenness. */
- svn_wc_entry_t tmp_entry;
- apr_uint64_t modify_flags = SVN_WC__ENTRY_MODIFY_KIND
- | SVN_WC__ENTRY_MODIFY_REVISION
- | SVN_WC__ENTRY_MODIFY_DELETED
- | SVN_WC__ENTRY_MODIFY_ABSENT
- | SVN_WC__ENTRY_MODIFY_TEXT_TIME
- | SVN_WC__ENTRY_MODIFY_WORKING_SIZE;
-
-
- tmp_entry.revision = new_revision;
- tmp_entry.kind = svn_node_file;
- tmp_entry.deleted = FALSE;
- tmp_entry.absent = FALSE;
- /* Indicate the file was locally modified and we didn't get to
- calculate the true value, but we can't set it to UNKNOWN (-1),
- because that would indicate absense of this value.
- If it isn't locally modified,
- we'll overwrite with the actual value later. */
- tmp_entry.working_size = SVN_WC_ENTRY_WORKING_SIZE_UNKNOWN;
- /* The same is true for the TEXT_TIME field, except that that doesn't
- have an explicid 'changed' value, so we set the value to 'undefined'. */
- tmp_entry.text_time = 0;
-
- /* Possibly install a *non*-inherited URL in the entry. */
- if (new_relpath)
- {
- tmp_entry.url = svn_path_url_add_component2(repos_root, new_relpath,
- pool);
- modify_flags |= SVN_WC__ENTRY_MODIFY_URL;
- }
-
- return svn_error_return(
- svn_wc__loggy_entry_modify(log_accum,
- svn_dirent_dirname(local_abspath, pool),
- local_abspath, &tmp_entry, modify_flags,
- pool, pool));
-}
-
-
-/* Write loggy commands to install a text base file from the given temporary
+/* Queue operations to install a text base file from the given temporary
* path TEMP_TEXT_BASE_ABSPATH (which must be in the adm temp area) to the
* given final text-base path FINAL_TEXT_BASE_ABSPATH (which must be the
* standard text-base path or revert-base path for the file).
- *
- * Write log instructions to do this into *LOG_ACCUM. Store all loggy paths
- * as paths relative to ADM_ABSPATH.
- *
- * Allocate *LOG_ACCUM in RESULT_POOL if it is NULL.
*/
static svn_error_t *
-install_text_base(svn_stringbuf_t **log_accum,
+install_text_base(svn_wc__db_t *db,
const char *adm_abspath,
const char *temp_text_base_abspath,
const char *final_text_base_abspath,
- apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- SVN_ERR(svn_wc__loggy_move(log_accum, adm_abspath,
+ SVN_ERR(svn_wc__loggy_move(db, adm_abspath,
temp_text_base_abspath, final_text_base_abspath,
- result_pool, scratch_pool));
- SVN_ERR(svn_wc__loggy_set_readonly(log_accum, adm_abspath,
+ scratch_pool));
+ SVN_ERR(svn_wc__loggy_set_readonly(db, adm_abspath,
final_text_base_abspath,
- result_pool, scratch_pool));
+ scratch_pool));
+
return SVN_NO_ERROR;
}
@@ -4236,25 +4262,26 @@ install_text_base(svn_stringbuf_t **log_
* this file, and removed after a successful run of the generated log
* commands.
*
+ * NEW_TEXT_BASE_MD5_CHECKSUM and NEW_TEXT_BASE_SHA1_CHECKSUM are the
+ * checksums that were computed as we constructed the (new) text base.
+ * (That was performed during a txdelta apply, or during a copy of an
+ * add-with-history.)
+ *
* Set *CONTENT_STATE to the state of the contents after the
* installation. If an error is returned, the value of these three
* variables is undefined.
*
- * ACTUAL_CHECKSUM is the checksum that was computed as we constructed
- * the (new) text base. That was performed during a txdelta apply, or
- * during a copy of an add-with-history.
- *
* POOL is used for all bookkeeping work during the installation.
*/
static svn_error_t *
-merge_file(svn_stringbuf_t **log_accum,
- svn_boolean_t *install_pristine,
+merge_file(svn_boolean_t *install_pristine,
const char **install_from,
svn_wc_notify_state_t *content_state,
const svn_wc_entry_t *entry,
struct file_baton *fb,
const char *new_text_base_tmp_abspath,
- const svn_checksum_t *actual_checksum,
+ const svn_checksum_t *new_text_base_md5_checksum,
+ const svn_checksum_t *new_text_base_sha1_checksum,
apr_pool_t *pool)
{
struct edit_baton *eb = fb->edit_baton;
@@ -4263,8 +4290,6 @@ merge_file(svn_stringbuf_t **log_accum,
svn_boolean_t is_replaced = FALSE;
svn_boolean_t magic_props_changed;
enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
- svn_wc_entry_t tmp_entry;
- apr_uint64_t flags = 0;
/*
When this function is called on file F, we assume the following
@@ -4284,11 +4309,6 @@ merge_file(svn_stringbuf_t **log_accum,
modifications.
*/
-#if 0
- /* ### this will break update_tests 43. see comment in close_file() */
- SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
-#endif
-
*install_pristine = FALSE;
*install_from = NULL;
@@ -4362,15 +4382,6 @@ merge_file(svn_stringbuf_t **log_accum,
&& ! entry->file_external_path) /* ### EBUG */
is_replaced = TRUE;
- if (fb->add_existed)
- {
- /* Tweak schedule for the file's entry so it is no longer
- scheduled for addition. */
- tmp_entry.schedule = svn_wc_schedule_normal;
- flags |= (SVN_WC__ENTRY_MODIFY_SCHEDULE |
- SVN_WC__ENTRY_MODIFY_FORCE);
- }
-
/* For 'textual' merging, we implement this matrix.
Text file Binary File
@@ -4516,24 +4527,19 @@ merge_file(svn_stringbuf_t **log_accum,
### in the future, all the state changes should be
### made atomically. */
SVN_ERR(svn_wc__internal_merge(
- log_accum, &merge_outcome,
+ &merge_outcome,
eb->db,
merge_left, NULL,
new_text_base_tmp_abspath, NULL,
fb->local_abspath,
fb->copied_working_text,
oldrev_str, newrev_str, mine_str,
- FALSE, eb->diff3_cmd, NULL, fb->propchanges,
+ FALSE /* dry_run */,
+ eb->diff3_cmd, NULL, fb->propchanges,
eb->conflict_func, eb->conflict_baton,
eb->cancel_func, eb->cancel_baton,
pool));
- /* svn_wc__internal_merge() should have queued all of
- its work (including a bunch of stuff that we pre-loaded
- into the log accumulator). */
- SVN_ERR_ASSERT(*log_accum == NULL
- || svn_stringbuf_isempty(*log_accum));
-
/* If we created a temporary left merge file, get rid of it. */
if (delete_left)
{
@@ -4583,55 +4589,31 @@ merge_file(svn_stringbuf_t **log_accum,
SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP,
pool, pool));
- /* A log command that copies the tmp-text-base and REtranslates
- it back to the working file.
- Now, since this is done during the execution of the log file, this
- retranslation is actually done according to the new props. */
- SVN_ERR(svn_wc__loggy_copy(log_accum, pb->local_abspath,
- tmptext, fb->local_abspath, pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
-
- /* Done with the temporary file. Toss it. */
- /* ### stupid fucking function sometimes decides NOT to create a
- ### temp file. but how are we supposed to know? */
- if (strcmp(tmptext, fb->local_abspath) != 0)
- {
- const svn_skel_t *work_item;
-
- SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
- eb->db,
- tmptext,
- pool, pool));
- SVN_ERR(svn_wc__db_wq_add(eb->db, pb->local_abspath,
- work_item, pool));
- }
+ /* We always want to reinstall the working file if the magic
+ properties have changed, or there are any keywords present.
+ Note that TMPTEXT might actually refer to the working file
+ itself (the above function skips a detranslate when not
+ required). This is acceptable, as we will (re)translate
+ according to the new properties into a temporary file (from
+ the working file), and then rename the temp into place. Magic! */
+ *install_pristine = TRUE;
+ *install_from = tmptext;
}
}
/* Deal with installation of the new textbase, if appropriate. */
if (new_text_base_tmp_abspath)
{
- SVN_ERR(install_text_base(log_accum, pb->local_abspath,
- new_text_base_tmp_abspath, fb->text_base_abspath,
- pool, pool));
- tmp_entry.checksum = svn_checksum_to_cstring(actual_checksum, pool);
- flags |= SVN_WC__ENTRY_MODIFY_CHECKSUM;
- }
-
- /* If FB->PATH is locally deleted, but not as part of a replacement
- then keep it deleted. */
- if (fb->deleted && !is_replaced)
- {
- tmp_entry.schedule = svn_wc_schedule_delete;
- flags |= SVN_WC__ENTRY_MODIFY_SCHEDULE;
+ /* Move the temp text-base file to its final destination and install
+ * its checksum in the entry. FB->text_base_path is the appropriate
+ * path: the "revert-base" path if the node is replaced, else the
+ * usual text-base path. */
+ SVN_ERR(install_text_base(eb->db, pb->local_abspath,
+ new_text_base_tmp_abspath,
+ fb->text_base_abspath,
+ pool));
}
- /* Do the entry modifications we've accumulated. */
- SVN_ERR(svn_wc__loggy_entry_modify(log_accum, pb->local_abspath,
- fb->local_abspath, &tmp_entry, flags,
- pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
-
/* Log commands to handle text-timestamp and working-size,
if the file is - or will be - unmodified and schedule-normal */
if (!*install_pristine
@@ -4642,23 +4624,21 @@ merge_file(svn_stringbuf_t **log_accum,
obstruction. */
if (fb->last_changed_date && !fb->obstruction_found)
SVN_ERR(svn_wc__loggy_set_timestamp(
- log_accum, pb->local_abspath,
+ eb->db, pb->local_abspath,
fb->local_abspath, fb->last_changed_date,
- pool, pool));
+ pool));
if ((new_text_base_tmp_abspath || magic_props_changed)
&& !fb->deleted)
{
/* Adjust entries file to match working file */
SVN_ERR(svn_wc__loggy_set_entry_timestamp_from_wc(
- log_accum, pb->local_abspath,
- fb->local_abspath, pool, pool));
+ eb->db, pb->local_abspath,
+ fb->local_abspath, pool));
}
SVN_ERR(svn_wc__loggy_set_entry_working_size_from_wc(
- log_accum, pb->local_abspath,
- fb->local_abspath, pool, pool));
-
- SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
+ eb->db, pb->local_abspath,
+ fb->local_abspath, pool));
}
/* Set the returned content state. */
@@ -4686,78 +4666,11 @@ merge_file(svn_stringbuf_t **log_accum,
}
-static svn_error_t *
-construct_base_node(svn_wc__db_t *db,
- const char *local_abspath,
- svn_revnum_t target_revision,
- svn_boolean_t resched_normal,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *scratch_pool)
-{
- /* ### HACK: Before we can set properties, we need a node in
- the database. This code could be its own WQ item,
- handling more than just this tweak, but it will
- be removed soon anyway.
-
- ### HACK: The loggy stuff checked the preconditions for us,
- we just make the property code happy here.
-
- We can also clear entry.deleted here, as we are adding a new
- BASE_NODE anyway */
-
- const char *adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- svn_wc_entry_t tmp_entry;
- svn_stringbuf_t *log_accum = NULL;
- apr_uint64_t flags = (SVN_WC__ENTRY_MODIFY_KIND
- | SVN_WC__ENTRY_MODIFY_REVISION
- | SVN_WC__ENTRY_MODIFY_DELETED);
-
- if (resched_normal)
- {
- /* Make sure we have a record in BASE; not in WORKING,
- or we try to install properties in the wrong place */
- flags |= SVN_WC__ENTRY_MODIFY_SCHEDULE | SVN_WC__ENTRY_MODIFY_FORCE;
- tmp_entry.schedule = svn_wc_schedule_normal;
- }
-
- /* ### we can probably just use entry_modify2() rather than adding
- ### a work item, then running it. */
-
- /* Create a very minimalistic file node that will be overridden
- from the loggy operations we have in the file baton log accumulator */
-
- tmp_entry.kind = svn_node_file;
- tmp_entry.revision = target_revision;
- tmp_entry.deleted = FALSE;
-
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum,
- adm_abspath,
- local_abspath,
- &tmp_entry,
- flags,
- scratch_pool, scratch_pool));
-
- SVN_ERR(svn_wc__wq_add_loggy(db, adm_abspath,
- log_accum,
- scratch_pool));
-
- /* ### for now, we use the ADM_ABSPATH even tho a WRI_ABSPATH is all that
- ### is required. BUT: the path must exist, and the file may not.
- ### the directory certainly does tho... */
- SVN_ERR(svn_wc__wq_run(db, adm_abspath,
- cancel_func, cancel_baton,
- scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-
/* An svn_delta_editor_t function. */
/* Mostly a wrapper around merge_file. */
static svn_error_t *
close_file(void *file_baton,
- const char *expected_hex_digest,
+ const char *expected_md5_digest,
apr_pool_t *pool)
{
struct file_baton *fb = file_baton;
@@ -4765,13 +4678,12 @@ close_file(void *file_baton,
struct last_change_info *last_change = NULL;
svn_wc_notify_state_t content_state, prop_state;
svn_wc_notify_lock_state_t lock_state;
- svn_checksum_t *expected_checksum = NULL;
- svn_checksum_t *md5_actual_checksum;
- svn_checksum_t *sha1_actual_checksum;
- const char *new_base_abspath;
+ svn_checksum_t *expected_md5_checksum = NULL;
+ svn_checksum_t *new_text_base_md5_checksum;
+ svn_checksum_t *new_text_base_sha1_checksum;
+ const char *new_text_base_abspath;
apr_hash_t *new_base_props = NULL;
apr_hash_t *new_actual_props = NULL;
- svn_stringbuf_t *delayed_log_accum = svn_stringbuf_create("", pool);
apr_array_header_t *entry_props;
apr_array_header_t *wc_props;
apr_array_header_t *regular_props;
@@ -4786,9 +4698,9 @@ close_file(void *file_baton,
return SVN_NO_ERROR;
}
- if (expected_hex_digest)
- SVN_ERR(svn_checksum_parse_hex(&expected_checksum, svn_checksum_md5,
- expected_hex_digest, pool));
+ if (expected_md5_digest)
+ SVN_ERR(svn_checksum_parse_hex(&expected_md5_checksum, svn_checksum_md5,
+ expected_md5_digest, pool));
/* Was this an add-with-history, with no apply_textdelta? */
if (fb->added_with_history && ! fb->received_textdelta)
@@ -4802,30 +4714,31 @@ close_file(void *file_baton,
eb->db, fb->local_abspath,
fb->pool, pool));
- md5_actual_checksum = fb->copied_text_base_md5_checksum;
- sha1_actual_checksum = fb->copied_text_base_sha1_checksum;
- new_base_abspath = fb->copied_text_base_abspath;
- SVN_ERR_ASSERT(! new_base_abspath || svn_dirent_is_absolute(new_base_abspath));
+ new_text_base_md5_checksum = fb->copied_text_base_md5_checksum;
+ new_text_base_sha1_checksum = fb->copied_text_base_sha1_checksum;
+ new_text_base_abspath = fb->copied_text_base_abspath;
+ SVN_ERR_ASSERT(! new_text_base_abspath
+ || svn_dirent_is_absolute(new_text_base_abspath));
}
else
{
/* Pull the actual checksum from the file_baton, computed during
the application of a text delta. */
- md5_actual_checksum = fb->new_text_base_md5_checksum;
- sha1_actual_checksum = fb->new_text_base_sha1_checksum;
- new_base_abspath = fb->new_text_base_tmp_abspath;
+ new_text_base_md5_checksum = fb->new_text_base_md5_checksum;
+ new_text_base_sha1_checksum = fb->new_text_base_sha1_checksum;
+ new_text_base_abspath = fb->new_text_base_tmp_abspath;
}
/* window-handler assembles new pristine text in .svn/tmp/text-base/ */
- if (new_base_abspath && expected_checksum
- && !svn_checksum_match(expected_checksum, md5_actual_checksum))
+ if (new_text_base_abspath && expected_md5_checksum
+ && !svn_checksum_match(expected_md5_checksum, new_text_base_md5_checksum))
return svn_error_createf(SVN_ERR_CHECKSUM_MISMATCH, NULL,
_("Checksum mismatch for '%s':\n"
" expected: %s\n"
" actual: %s\n"),
svn_dirent_local_style(fb->local_abspath, pool),
- expected_hex_digest,
- svn_checksum_to_cstring_display(md5_actual_checksum, pool));
+ expected_md5_digest,
+ svn_checksum_to_cstring_display(new_text_base_md5_checksum, pool));
#ifdef SVN_EXPERIMENTAL
/* If we had a text change, drop the pristine into it's proper place. */
@@ -4838,8 +4751,8 @@ close_file(void *file_baton,
file operations are not side by side. */
if (fb->new_pristine_tmp_abspath)
SVN_ERR(svn_wc__db_pristine_install(eb->db, fb->new_pristine_tmp_abspath,
- sha1_actual_checksum,
- md5_actual_checksum, pool));
+ new_text_base_sha1_checksum,
+ new_text_base_md5_checksum, pool));
#endif
/* Get a copy of the entry *before* we begin mucking around with the
@@ -4851,17 +4764,6 @@ close_file(void *file_baton,
_("'%s' is not under version control"),
svn_dirent_local_style(fb->local_abspath, pool));
- /* add_file() was called, or there was an added node here. Ensure that
- we have a BASE node to work with. */
- if (fb->adding_file || fb->add_existed)
- {
- SVN_ERR(construct_base_node(eb->db, fb->local_abspath,
- *eb->target_revision,
- fb->add_existed /* resched_normal */,
- eb->cancel_func, eb->cancel_baton,
- pool));
- }
-
/* Gather the changes for each kind of property. */
SVN_ERR(svn_categorize_props(fb->propchanges, &entry_props, &wc_props,
®ular_props, pool));
@@ -4871,22 +4773,7 @@ close_file(void *file_baton,
eb->db, fb->local_abspath,
entry_props,
pool, pool));
-
- /* ### Hack: The following block should be an atomic operation (including
- ### the install loggy install portions of some functions called above */
SVN_ERR_ASSERT(last_change != NULL); /* files should always have.. */
- SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, fb->local_abspath,
- last_change->cmt_rev,
- last_change->cmt_date,
- last_change->cmt_author,
- pool));
-
- /* Set the new revision and URL in the entry and clean up some other
- fields. This clears DELETED from any prior versioned file with the
- same name (needed before attempting to install props). */
- SVN_ERR(loggy_tweak_base_node(&delayed_log_accum, fb->local_abspath,
- *eb->target_revision,
- eb->repos_root, fb->new_relpath, pool));
/* Install all kinds of properties. It is important to do this before
any file content merging, since that process might expand keywords, in
@@ -4932,17 +4819,6 @@ close_file(void *file_baton,
TRUE /* force_base_install */,
pool));
-#if 0
- /* ### this breaks update_tests 43. it does a *partial* edit of the
- ### state. if the user cancels a merge resolution (e.g EOF), then
- ### the working copy ends up horked. */
-
- /* Now that the installation of the props has been queued, flush out
- anything from the delayed accumulator. */
- SVN_WC__FLUSH_LOG_ACCUM(eb->db, fb->dir_baton->local_abspath,
- delayed_log_accum, pool);
-#endif
-
/* This writes a whole bunch of log commands to install wcprops. */
/* ### no it doesn't. this immediately modifies them. should probably
### occur later, when we know the (new) BASE node exists. */
@@ -4951,59 +4827,182 @@ close_file(void *file_baton,
pool));
/* Do the hard work. This will queue some additional work. */
- SVN_ERR(merge_file(&delayed_log_accum, &install_pristine, &install_from,
+ SVN_ERR(merge_file(&install_pristine, &install_from,
&content_state, entry,
- fb, new_base_abspath, md5_actual_checksum,
- pool));
+ fb, new_text_base_abspath, new_text_base_md5_checksum,
+ new_text_base_sha1_checksum, pool));
- /* Queue all operations. */
- SVN_WC__FLUSH_LOG_ACCUM(eb->db, fb->dir_baton->local_abspath,
- delayed_log_accum, pool);
+ /* Insert/replace the BASE node with all of the new metadata. */
+ {
+#ifdef SVN_EXPERIMENTAL
+ /* Set the 'checksum' column of the file's BASE_NODE row to
+ * NEW_TEXT_BASE_SHA1_CHECKSUM. The pristine text identified by that
+ * checksum is already in the pristine store. */
+ const svn_checksum_t *new_checksum = new_text_base_sha1_checksum;
+#else
+ const svn_checksum_t *new_checksum = new_text_base_md5_checksum;
+#endif
- /* Now that all the state has settled, should we update the readonly
- status of the working file? The LOCK_STATE will signal what we should
- do for this node. */
- if (new_base_abspath == NULL
- && lock_state == svn_wc_notify_lock_state_unlocked)
+ /* If we don't have a NEW checksum, then the base must not have changed.
+ Just carry over the old checksum. */
+ if (new_checksum == NULL)
+ {
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL,
+ &new_checksum, NULL, NULL, NULL,
+ eb->db, fb->local_abspath,
+ pool, pool));
+#ifdef SVN_EXPERIMENTAL
+ /* ### new_checksum is originally MD-5 but will later be SHA-1... */
+#endif
+
+ }
+
+ SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
+ fb->new_relpath,
+ eb->repos_root, eb->repos_uuid,
+ *eb->target_revision,
+ new_base_props,
+ last_change->cmt_rev,
+ last_change->cmt_date,
+ last_change->cmt_author,
+ new_checksum,
+ SVN_INVALID_FILESIZE,
+ NULL, NULL,
+ pool));
+
+ /* ### ugh. deal with preserving the file external value in the database.
+ ### there is no official API, so we do it this way. maybe we should
+ ### have a temp API into wc_db. */
+ if (entry && entry->file_external_path)
+ {
+ svn_wc_entry_t tmp_entry;
+
+ tmp_entry.file_external_path = entry->file_external_path;
+ tmp_entry.file_external_peg_rev = entry->file_external_peg_rev;
+ tmp_entry.file_external_rev = entry->file_external_rev;
+ SVN_ERR(svn_wc__entry_modify2(eb->db, fb->local_abspath,
+ svn_node_file, FALSE /* parent_stub */,
+ &tmp_entry,
+ SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL,
+ pool));
+ }
+ }
+
+ /* Deal with the WORKING tree, based on updates to the BASE tree. */
+
+ /* An ancestor was locally-deleted. This file is being added within
+ that tree. We need to schedule this file for deletion. */
+ if (fb->dir_baton->in_deleted_and_tree_conflicted_subtree && fb->adding_file)
{
- /* If a lock was removed and we didn't update the text contents, we
- might need to set the file read-only. */
- SVN_ERR(svn_wc__loggy_maybe_set_readonly(eb->db,
- fb->dir_baton->local_abspath,
- fb->local_abspath, pool));
+ /* ### temporary hack. we should simply write a WORKING_NODE. */
+
+ svn_wc_entry_t tmp_entry;
+
+ tmp_entry.schedule = svn_wc_schedule_delete;
+ SVN_ERR(svn_wc__entry_modify2(eb->db, fb->local_abspath,
+ svn_node_file, FALSE /* parent_stub */,
+ &tmp_entry, SVN_WC__ENTRY_MODIFY_SCHEDULE,
+ pool));
+ }
+
+ /* This file was locally-added. This file is now being added by the
+ update. We can toss the local-add, turning this into a local-edit. */
+ if (fb->add_existed && fb->adding_file)
+ {
+ /* ### temporary hack. we should simply delete the WORKING_NODE. */
+
+ svn_wc_entry_t tmp_entry;
+
+ /* ### we need to use FORCE to ensure transition to normal. otherwise,
+ ### it would remain in the added state. */
+ tmp_entry.schedule = svn_wc_schedule_normal;
+ SVN_ERR(svn_wc__entry_modify2(eb->db, fb->local_abspath,
+ svn_node_file, FALSE /* parent_stub */,
+ &tmp_entry,
+ SVN_WC__ENTRY_MODIFY_SCHEDULE
+ | SVN_WC__ENTRY_MODIFY_FORCE,
+ pool));
}
+ /* ### we may as well run whatever is in the queue right now. this
+ ### starts out with some crap node data via construct_base_node(),
+ ### so we can't really monkey things up too badly here. all tests
+ ### continue to pass, so this also gives us a better insight into
+ ### doing things more immediately, rather than queuing to run at
+ ### some future point in time. */
+ SVN_ERR(svn_wc__wq_run(eb->db, fb->dir_baton->local_abspath,
+ eb->cancel_func, eb->cancel_baton,
+ pool));
+
if (install_pristine)
{
+ svn_boolean_t record_fileinfo;
const svn_skel_t *work_item;
+ /* If we are installing from the pristine contents, then go ahead and
+ record the fileinfo. That will be the "proper" values. Installing
+ from some random file means the fileinfo does NOT correspond to
+ the pristine (in which case, the fileinfo will be cleared for
+ safety's sake). */
+ record_fileinfo = install_from == NULL;
+
SVN_ERR(svn_wc__wq_build_file_install(&work_item,
eb->db,
fb->local_abspath,
install_from,
eb->use_commit_times,
- TRUE /* record_fileinfo */,
+ record_fileinfo,
pool, pool));
SVN_ERR(svn_wc__db_wq_add(eb->db, fb->dir_baton->local_abspath,
work_item, pool));
}
- /* Clean up any temporary files. */
-#if 0
- /* ### can't really use this now. INSTALL_FROM might refer to the
- ### revert-base for file externals. (sigh) once that is fixed,
- ### then this will be handy for other cases. */
- if (install_from != NULL)
+ /* Now that all the state has settled, should we update the readonly
+ status of the working file? The LOCK_STATE will signal what we should
+ do for this node. */
+ if (new_text_base_abspath == NULL
+ && lock_state == svn_wc_notify_lock_state_unlocked)
{
const svn_skel_t *work_item;
- SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
- install_from,
- pool, pool));
+ /* If a lock was removed and we didn't update the text contents, we
+ might need to set the file read-only.
+
+ Note: this will also update the executable flag, but ... meh. */
+ SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, eb->db,
+ fb->local_abspath,
+ pool, pool));
SVN_ERR(svn_wc__db_wq_add(eb->db, fb->dir_baton->local_abspath,
work_item, pool));
}
-#endif
+
+ /* Clean up any temporary files. */
+
+ /* For the INSTALL_FROM file, be careful that it doesn't refer to the
+ working file, or the revert text base. (sigh) Hopefully, this will
+ be cleared up in the future. */
+ if (install_from != NULL
+ && strcmp(install_from, fb->local_abspath) != 0)
+ {
+ const char *revert_base_abspath;
+
+ SVN_ERR(svn_wc__text_revert_path(&revert_base_abspath, eb->db,
+ fb->local_abspath, pool));
+ if (strcmp(install_from, revert_base_abspath) != 0)
+ {
+ const svn_skel_t *work_item;
+
+ SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
+ install_from,
+ pool, pool));
+ SVN_ERR(svn_wc__db_wq_add(eb->db, fb->dir_baton->local_abspath,
+ work_item, pool));
+ }
+ }
+
if (fb->copied_text_base_abspath)
{
const svn_skel_t *work_item;
@@ -5734,7 +5733,6 @@ svn_wc_add_repos_file4(svn_wc_context_t
svn_stream_t *tmp_base_contents;
const char *text_base_abspath;
const char *temp_dir_abspath;
- svn_stringbuf_t *log_accum;
struct last_change_info *last_change = NULL;
svn_error_t *err;
const char *source_abspath = NULL;
@@ -5768,10 +5766,6 @@ svn_wc_add_repos_file4(svn_wc_context_t
copyfrom_url, repos_root);
}
- /* Accumulate log commands in this buffer until we're ready to close
- and run the log. */
- log_accum = svn_stringbuf_create("", pool);
-
/* If we're replacing the file then we need to save the destination file's
original text base and prop base before replacing it. This allows us to
revert the entire change.
@@ -5822,16 +5816,12 @@ svn_wc_add_repos_file4(svn_wc_context_t
SVN_ERR(svn_wc__text_revert_path(&dst_rtext, db, local_abspath,
pool));
- SVN_ERR(svn_wc__loggy_move(&log_accum, dir_abspath,
+ SVN_ERR(svn_wc__loggy_move(db, dir_abspath,
text_base_abspath, dst_rtext,
- pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
+ pool));
- SVN_ERR(svn_wc__loggy_revert_props_create(&log_accum, db,
- local_abspath,
- dir_abspath,
+ SVN_ERR(svn_wc__loggy_revert_props_create(db, local_abspath,
pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
}
}
}
@@ -5859,10 +5849,9 @@ svn_wc_add_repos_file4(svn_wc_context_t
| SVN_WC__ENTRY_MODIFY_COPIED;
}
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, dir_abspath,
+ SVN_ERR(svn_wc__loggy_entry_modify(db, dir_abspath,
local_abspath, &tmp_entry,
- modify_flags, pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
+ modify_flags, pool));
}
/* ### Clear working node status in preparation for writing a new node. */
@@ -5880,13 +5869,12 @@ svn_wc_add_repos_file4(svn_wc_context_t
have an explicid 'changed' value, so we set the value to 'undefined'. */
tmp_entry.text_time = 0;
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, dir_abspath,
+ SVN_ERR(svn_wc__loggy_entry_modify(db, dir_abspath,
local_abspath, &tmp_entry,
SVN_WC__ENTRY_MODIFY_KIND
| SVN_WC__ENTRY_MODIFY_TEXT_TIME
| SVN_WC__ENTRY_MODIFY_WORKING_SIZE,
- pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
+ pool));
}
/* Categorize the base properties. */
@@ -5951,18 +5939,16 @@ svn_wc_add_repos_file4(svn_wc_context_t
svn_wc_entry_t tmp_entry;
/* Write out log commands to set up the new text base and its checksum. */
- SVN_ERR(install_text_base(&log_accum, dir_abspath,
+ SVN_ERR(install_text_base(db, dir_abspath,
tmp_text_base_abspath, text_base_abspath,
- pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
+ pool));
tmp_entry.checksum = svn_checksum_to_cstring(base_checksum, pool);
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, dir_abspath,
+ SVN_ERR(svn_wc__loggy_entry_modify(db, dir_abspath,
local_abspath, &tmp_entry,
SVN_WC__ENTRY_MODIFY_CHECKSUM,
- pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
+ pool));
}
/* ### HACK: The following code should be performed in the same transaction as the install */
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/util.c?rev=933863&r1=933862&r2=933863&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/util.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/util.c Wed Apr 14 06:51:00 2010
@@ -543,3 +543,10 @@ svn_wc__cd_to_cd2(const svn_wc_conflict_
return new_conflict;
}
+
+svn_wc_status2_t *
+svn_wc__status2_from_3(const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
+{
+ return (svn_wc_status2_t *) svn_wc_dup_status3(status, scratch_pool);
+}
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql?rev=933863&r1=933862&r2=933863&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql Wed Apr 14 06:51:00 2010
@@ -232,12 +232,20 @@ delete from actual_node
where wc_id = ?1 and local_relpath = ?2;
-- STMT_UPDATE_BASE_DEPTH
-update base_node set depth = ?3
-where wc_id = ?1 and local_relpath = ?2;
+UPDATE BASE_NODE SET depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
-- STMT_UPDATE_WORKING_DEPTH
-update working_node set depth = ?3
-where wc_id = ?1 and local_relpath = ?2;
+UPDATE WORKING_NODE SET depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_BASE_EXCLUDED
+UPDATE BASE_NODE SET presence = 'excluded', depth = 'infinity'
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_WORKING_EXCLUDED
+UPDATE WORKING_NODE SET presence = 'excluded', depth = 'infinity'
+WHERE wc_id = ?1 AND local_relpath = ?2;
-- STMT_UPDATE_BASE_PRESENCE
update base_node set presence= ?3
@@ -271,6 +279,11 @@ DELETE FROM WORK_QUEUE WHERE id = ?1;
INSERT OR IGNORE INTO PRISTINE (checksum, md5_checksum, size, refcount)
VALUES (?1, ?2, ?3, 1);
+-- STMT_SELECT_PRISTINE_MD5_CHECKSUM
+SELECT md5_checksum
+FROM pristine
+WHERE checksum = ?1
+
-- STMT_SELECT_ACTUAL_CONFLICT_VICTIMS
SELECT local_relpath
FROM actual_node
@@ -424,14 +437,11 @@ where wc_id = ?1 and local_relpath = ?2;
update base_node set file_external = ?3
where wc_id = ?1 and local_relpath = ?2;
--- STMT_UPDATE_BASE_LAST_CHANGE
-update base_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
-where wc_id = ?1 and local_relpath = ?2;
-
-- STMT_UPDATE_WORKING_LAST_CHANGE
update working_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
where wc_id = ?1 and local_relpath = ?2;
+
/* ------------------------------------------------------------------------- */
/* these are used in upgrade.c */