You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/10 22:56:05 UTC
svn commit: r984206 [15/35] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/generator/ build/generator/templates/ build/hudson/
build/hudson/jobs/subversion-1.6.x-solaris/
build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hudson/jobs/subvers...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c Tue Aug 10 20:55:56 2010
@@ -34,6 +34,8 @@
#include "svn_path.h"
#include "wc.h"
+#include "log.h"
+#include "workqueue.h"
#include "adm_files.h"
#include "entries.h"
#include "props.h"
@@ -56,8 +58,8 @@ copy_props(svn_wc__db_t *db,
apr_hash_t *props;
apr_hash_index_t *hi;
- SVN_ERR(svn_wc__load_props(NULL, &props, db, src_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__get_actual_props(&props, db, src_abspath,
+ scratch_pool, scratch_pool));
for (hi = apr_hash_first(scratch_pool, props); hi; hi = apr_hash_next(hi))
{
const char *propname = svn__apr_hash_index_key(hi);
@@ -258,89 +260,7 @@ copy_added_dir_administratively(svn_wc_c
return SVN_NO_ERROR;
}
-/* A helper for copy_file_administratively() which sets *COPYFROM_URL
- and *COPYFROM_REV appropriately (possibly to NULL/SVN_INVALID_REVNUM).
- DST_URL may be NULL, in which case DST_REVISION is ignored. */
-static svn_error_t *
-determine_copyfrom_info(const char **copyfrom_url,
- svn_revnum_t *copyfrom_rev,
- svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_url,
- svn_revnum_t dst_revision,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- const char *url;
- const char *original_root_url;
- const char *original_repos_relpath;
- svn_revnum_t original_revision;
- svn_wc__db_status_t status;
-
- url = NULL;
- original_revision = SVN_INVALID_REVNUM;
-
- SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, &original_repos_relpath,
- &original_root_url, NULL, &original_revision,
- NULL, NULL, NULL, NULL, NULL, db, src_abspath,
- scratch_pool, scratch_pool));
- if (original_root_url && original_repos_relpath)
- {
- /* When copying/moving a file that was already explicitly
- copied/moved then we know the URL it was copied from... */
- url = svn_path_url_add_component2(original_root_url,
- original_repos_relpath, scratch_pool);
- }
- else if (status == svn_wc__db_status_added
- || status == svn_wc__db_status_obstructed_add)
- {
- /* ...But if this file is merely the descendant of an explicitly
- copied/moved directory, we need to do a bit more work to
- determine copyfrom_url and copyfrom_rev. */
- const char *op_root_abspath;
-
- SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL, NULL,
- NULL, &original_repos_relpath,
- &original_root_url, NULL,
- &original_revision, db, src_abspath,
- scratch_pool, scratch_pool));
- if (status == svn_wc__db_status_copied ||
- status == svn_wc__db_status_moved_here)
- {
- const char *src_parent_url;
- const char *src_relpath;
-
- src_parent_url = svn_path_url_add_component2(original_root_url,
- original_repos_relpath,
- scratch_pool);
- src_relpath = svn_dirent_is_child(op_root_abspath, src_abspath,
- scratch_pool);
- if (src_relpath)
- url = svn_path_url_add_component2(src_parent_url, src_relpath,
- scratch_pool);
- }
- }
-
- if (url && dst_url && strcmp(url, dst_url) == 0 &&
- original_revision == dst_revision)
- {
- /* Suppress copyfrom info when the copy source is the same as
- for the destination. */
- url = NULL;
- original_revision = SVN_INVALID_REVNUM;
- }
-
- if (url)
- *copyfrom_url = apr_pstrdup(result_pool, url);
- else
- *copyfrom_url = NULL;
- *copyfrom_rev = original_revision;
-
- return SVN_NO_ERROR;
-}
-
+#ifndef SVN_EXPERIMENTAL_COPY
/* This function effectively creates and schedules a file for
addition, but does extra administrative things to allow it to
function as a 'copy'.
@@ -426,20 +346,26 @@ copy_file_administratively(svn_wc_contex
apr_hash_t *props, *base_props;
svn_stream_t *base_contents;
svn_stream_t *contents;
- svn_boolean_t src_exists;
-
- src_exists = TRUE;
/* Are we moving or copying a file that is already moved or copied
but not committed? */
if (src_entry->copied)
{
- SVN_ERR(determine_copyfrom_info(©from_url, ©from_rev, db,
- src_abspath,
- dst_entry ? dst_entry->url : NULL,
- dst_entry ? dst_entry->revision
- : SVN_INVALID_REVNUM,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__node_get_copyfrom_info(©from_url, ©from_rev,
+ NULL, wc_ctx, src_abspath,
+ scratch_pool, scratch_pool));
+
+ /* If the COPYFROM information is the SAME as the destination
+ URL/REVISION, then omit the copyfrom info. */
+ if (dst_entry != NULL
+ && dst_entry->revision == copyfrom_rev
+ && copyfrom_url != NULL
+ && dst_entry->url != NULL
+ && strcmp(copyfrom_url, dst_entry->url) == 0)
+ {
+ copyfrom_url = NULL;
+ copyfrom_rev = SVN_INVALID_REVNUM;
+ }
}
else
{
@@ -449,8 +375,10 @@ copy_file_administratively(svn_wc_contex
}
/* Load source base and working props. */
- SVN_ERR(svn_wc__load_props(&base_props, &props, db,
- src_abspath, scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__get_pristine_props(&base_props, db, src_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__get_actual_props(&props, db, src_abspath,
+ scratch_pool, scratch_pool));
/* Copy working copy file to temporary location */
{
@@ -481,8 +409,6 @@ copy_file_administratively(svn_wc_contex
{
svn_error_clear(err);
- src_exists = FALSE;
-
err = svn_wc__get_pristine_contents(&contents, db, src_abspath,
scratch_pool, scratch_pool);
@@ -522,7 +448,8 @@ copy_file_administratively(svn_wc_contex
}
}
- SVN_ERR(svn_wc_get_pristine_contents2(&base_contents, wc_ctx, src_abspath,
+ SVN_ERR(svn_wc__get_pristine_contents(&base_contents,
+ wc_ctx->db, src_abspath,
scratch_pool, scratch_pool));
/* Above add/replace condition should have caught this already
* (-> error "Cannot copy..."). */
@@ -551,6 +478,7 @@ copy_file_administratively(svn_wc_contex
return SVN_NO_ERROR;
}
+#endif
/* Recursively crawl over a directory PATH and do a number of things:
@@ -631,9 +559,9 @@ post_copy_cleanup(svn_wc__db_t *db,
with creating a directory. See Issue #2101 for details. */
if (entry->deleted)
{
- apr_uint64_t flags = (SVN_WC__ENTRY_MODIFY_FORCE
- | SVN_WC__ENTRY_MODIFY_SCHEDULE
- | SVN_WC__ENTRY_MODIFY_DELETED);
+ int modify_flags = (SVN_WC__ENTRY_MODIFY_FORCE
+ | SVN_WC__ENTRY_MODIFY_SCHEDULE
+ | SVN_WC__ENTRY_MODIFY_DELETED);
svn_wc_entry_t tmp_entry;
tmp_entry.schedule = svn_wc_schedule_delete;
@@ -659,11 +587,11 @@ post_copy_cleanup(svn_wc__db_t *db,
schedule delete until the copy is committed, when they become
state deleted and everything works! */
tmp_entry.kind = svn_node_file;
- flags |= SVN_WC__ENTRY_MODIFY_KIND;
+ modify_flags |= SVN_WC__ENTRY_MODIFY_KIND;
}
- SVN_ERR(svn_wc__entry_modify2(db, child_abspath, svn_node_unknown,
- FALSE, &tmp_entry, flags, iterpool));
+ SVN_ERR(svn_wc__entry_modify(db, child_abspath, svn_node_unknown,
+ &tmp_entry, modify_flags, iterpool));
}
/* Remove lock stuffs. */
@@ -704,6 +632,8 @@ copy_dir_administratively(svn_wc_context
{
const svn_wc_entry_t *src_entry;
svn_wc__db_t *db = wc_ctx->db;
+ const char *dir_abspath;
+ const char *name;
/* Sanity check 1: You cannot make a copy of something that's not
under version control. */
@@ -725,18 +655,23 @@ copy_dir_administratively(svn_wc_context
schedulings, existences, etc.
### Should we be copying unversioned items within the directory? */
+ svn_dirent_split(dst_abspath, &dir_abspath, &name, scratch_pool);
SVN_ERR(svn_io_copy_dir_recursively(src_abspath,
- svn_dirent_dirname(dst_abspath,
- scratch_pool),
- svn_dirent_basename(dst_abspath, NULL),
- TRUE,
+ dir_abspath,
+ name,
+ TRUE /* copy_perms */,
cancel_func, cancel_baton,
scratch_pool));
- /* If this is part of a move, the copied directory will be locked,
- because the source directory was locked. Running cleanup will remove
- the locks, even though this directory has not yet been added to the
- parent. */
+ /* ### the wc.db databases have locks in them, based on the source paths.
+ ### go through and clean out those locks. this should go away in the
+ ### single-db case, but would probably also be fixed if we revamped
+ ### the copy algorithm to: copy all metadata, copy all pristines,
+ ### then install all working copy files from those pristines.
+ ###
+ ### hmm. that would not carry over local edits, however.
+ ### more thinking required...
+ */
SVN_ERR(svn_wc_cleanup3(wc_ctx, dst_abspath, cancel_func, cancel_baton,
scratch_pool));
@@ -759,35 +694,138 @@ copy_dir_administratively(svn_wc_context
SVN_ERR(svn_wc__get_entry(&dst_entry, db, dst_abspath, TRUE,
svn_node_dir, TRUE,
scratch_pool, scratch_pool));
- SVN_ERR(determine_copyfrom_info(©from_url, ©from_rev, db,
- src_abspath,
- dst_entry ? dst_entry->url : NULL,
- dst_entry ? dst_entry->revision
- : SVN_INVALID_REVNUM,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__node_get_copyfrom_info(©from_url, ©from_rev,
+ NULL, wc_ctx, src_abspath,
+ scratch_pool, scratch_pool));
+
+ /* If the COPYFROM information is the SAME as the destination
+ URL/REVISION, then omit the copyfrom info. */
+ if (dst_entry != NULL
+ && dst_entry->revision == copyfrom_rev
+ && copyfrom_url != NULL
+ && dst_entry->url != NULL
+ && strcmp(copyfrom_url, dst_entry->url) == 0)
+ {
+ copyfrom_url = NULL;
+ copyfrom_rev = SVN_INVALID_REVNUM;
+ }
/* The URL for a copied dir won't exist in the repository, which
will cause svn_wc_add4() below to fail. Set the URL to the
URL of the first copy for now to prevent this. */
tmp_entry.url = apr_pstrdup(scratch_pool, copyfrom_url);
- SVN_ERR(svn_wc__entry_modify2(db, dst_abspath, svn_node_dir, FALSE,
- &tmp_entry, SVN_WC__ENTRY_MODIFY_URL,
- scratch_pool));
+ SVN_ERR(svn_wc__entry_modify(db, dst_abspath, svn_node_dir,
+ &tmp_entry, SVN_WC__ENTRY_MODIFY_URL,
+ scratch_pool));
}
else
{
SVN_ERR(svn_wc__internal_get_ancestry(©from_url, ©from_rev,
- db, src_abspath, scratch_pool,
- scratch_pool));
+ db, src_abspath,
+ scratch_pool, scratch_pool));
}
- return svn_wc_add4(wc_ctx, dst_abspath, svn_depth_infinity,
- copyfrom_url, copyfrom_rev,
- cancel_func, cancel_baton,
- notify_copied, notify_baton, scratch_pool);
+ return svn_error_return(svn_wc_add4(wc_ctx, dst_abspath,
+ svn_depth_infinity,
+ copyfrom_url, copyfrom_rev,
+ cancel_func, cancel_baton,
+ notify_copied, notify_baton,
+ scratch_pool));
}
}
+#ifdef SVN_EXPERIMENTAL_COPY
+/* A replacement for both copy_file_administratively and
+ copy_added_file_administratively. Not yet fully working. Relies
+ on in-db-props. */
+static svn_error_t *
+copy_versioned_file(svn_wc_context_t *wc_ctx,
+ const char *src_abspath,
+ const char *dst_abspath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_skel_t *work_items = NULL;
+ const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
+ const char *tmpdir_abspath;
+ svn_stream_t *src, *src_pristine;
+ const char *tmp_dst_abspath;
+ svn_error_t *err;
+
+ SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, wc_ctx->db,
+ dst_abspath,
+ scratch_pool, scratch_pool));
+
+#ifndef SVN_EXPERIMENTAL_PRISTINE
+ SVN_ERR(svn_wc__get_pristine_contents(&src_pristine, wc_ctx->db,
+ src_abspath,
+ scratch_pool, scratch_pool));
+ if (src_pristine)
+ {
+ svn_skel_t *work_item;
+ svn_stream_t *tmp_pristine;
+ const char *tmp_pristine_abspath, *dst_pristine_abspath;
+
+ SVN_ERR(svn_stream_open_unique(&tmp_pristine, &tmp_pristine_abspath,
+ tmpdir_abspath, svn_io_file_del_none,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_stream_copy3(src_pristine, tmp_pristine,
+ cancel_func, cancel_baton, scratch_pool));
+ SVN_ERR(svn_wc__text_base_path(&dst_pristine_abspath, wc_ctx->db,
+ dst_abspath, scratch_pool));
+ SVN_ERR(svn_wc__loggy_move(&work_item, wc_ctx->db, dir_abspath,
+ tmp_pristine_abspath, dst_pristine_abspath,
+ scratch_pool));
+ work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+ }
+#endif
+
+ err = svn_stream_open_readonly(&src, src_abspath, scratch_pool, scratch_pool);
+ if (err)
+ {
+ if (!APR_STATUS_IS_ENOENT(err->apr_err))
+ return svn_error_return(err);
+ /* Source may not exist when recursively copying a directory. */
+ svn_error_clear(err);
+ }
+ else
+ {
+ svn_skel_t *work_item;
+ svn_stream_t *tmp_dst;
+
+ SVN_ERR(svn_stream_open_unique(&tmp_dst, &tmp_dst_abspath,
+ tmpdir_abspath, svn_io_file_del_none,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_io_copy_perms(src_abspath,
+ tmp_dst_abspath, scratch_pool));
+ SVN_ERR(svn_stream_copy3(src, tmp_dst,
+ cancel_func, cancel_baton, scratch_pool));
+ SVN_ERR(svn_wc__loggy_move(&work_item, wc_ctx->db, dir_abspath,
+ tmp_dst_abspath, dst_abspath,
+ scratch_pool));
+ work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+ }
+
+ SVN_ERR(svn_wc__db_op_copy(wc_ctx->db, src_abspath, dst_abspath,
+ work_items, scratch_pool));
+ SVN_ERR(svn_wc__wq_run(wc_ctx->db, dir_abspath,
+ cancel_func, cancel_baton, scratch_pool));
+
+ if (notify_func)
+ {
+ svn_wc_notify_t *notify
+ = svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
+ scratch_pool);
+ notify->kind = svn_node_file;
+ (*notify_func)(notify_baton, notify, scratch_pool);
+ }
+ return SVN_NO_ERROR;
+}
+#endif
+
/* Public Interface */
@@ -872,6 +910,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
if (src_kind == svn_node_file ||
(src_entry->kind == svn_node_file && src_kind == svn_node_none))
{
+#ifndef SVN_EXPERIMENTAL_COPY
/* Check if we are copying a file scheduled for addition,
these require special handling. */
if (src_entry->schedule == svn_wc_schedule_add
@@ -893,6 +932,42 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
notify_func, notify_baton,
scratch_pool));
}
+#else
+ svn_node_kind_t dst_kind, dst_db_kind;
+
+ /* This is the error checking from copy_file_administratively
+ but converted to wc-ng. It's not in copy_file since this
+ checking only needs to happen at the root of the copy and not
+ when called recursively. */
+ SVN_ERR(svn_io_check_path(dst_abspath, &dst_kind, scratch_pool));
+ if (dst_kind != svn_node_none)
+ return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
+ _("'%s' already exists and is in the way"),
+ svn_dirent_local_style(dst_abspath,
+ scratch_pool));
+ SVN_ERR(svn_wc_read_kind(&dst_db_kind, wc_ctx, dst_abspath, TRUE,
+ scratch_pool));
+ if (dst_db_kind != svn_node_none)
+ {
+ svn_boolean_t is_deleted, is_present;
+
+ SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, wc_ctx,
+ dst_abspath, scratch_pool));
+ SVN_ERR(svn_wc__node_is_status_present(&is_present, wc_ctx,
+ dst_abspath, scratch_pool));
+ if (is_present && !is_deleted)
+ return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
+ _("There is already a versioned item '%s'"),
+ svn_dirent_local_style(dst_abspath,
+ scratch_pool));
+
+ }
+
+ SVN_ERR(copy_versioned_file(wc_ctx, src_abspath, dst_abspath,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ scratch_pool));
+#endif
}
else if (src_kind == svn_node_dir)
{
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/crop.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/crop.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/crop.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/crop.c Tue Aug 10 20:55:56 2010
@@ -91,7 +91,8 @@ crop_children(svn_wc__db_t *db,
/* Update the depth of target first, if needed. */
if (dir_depth > depth)
{
- SVN_ERR(svn_wc__set_depth(db, local_abspath, depth, iterpool));
+ SVN_ERR(svn_wc__db_temp_op_set_dir_depth(db, local_abspath, depth,
+ iterpool));
}
/* Looping over current directory's SVN entries: */
@@ -126,7 +127,8 @@ crop_children(svn_wc__db_t *db,
? svn_depth_immediates
: svn_depth_files;
if (depth < remove_below)
- SVN_ERR(svn_wc__entry_remove(db, local_abspath, iterpool));
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
+ iterpool));
continue;
}
@@ -301,6 +303,7 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx,
revision,
kind,
svn_wc__db_status_excluded,
+ NULL, NULL,
scratch_pool));
if (notify_func)
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c Tue Aug 10 20:55:56 2010
@@ -26,6 +26,8 @@
deprecated functions in this file. */
#define SVN_DEPRECATED
+#include <apr_md5.h>
+
#include "svn_wc.h"
#include "svn_subst.h"
#include "svn_pools.h"
@@ -409,16 +411,23 @@ svn_wc_transmit_text_deltas2(const char
{
const char *local_abspath;
svn_wc_context_t *wc_ctx;
+ const svn_checksum_t *new_text_base_md5_checksum;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
svn_wc__adm_get_db(adm_access),
pool));
- SVN_ERR(svn_wc_transmit_text_deltas3(tempfile, digest, wc_ctx,
+ SVN_ERR(svn_wc_transmit_text_deltas3(tempfile,
+ digest ? &new_text_base_md5_checksum
+ : NULL,
+ NULL, wc_ctx,
local_abspath, fulltext, editor,
file_baton, pool, pool));
+ if (digest)
+ memcpy(digest, new_text_base_md5_checksum->digest, APR_MD5_DIGESTSIZE);
+
return svn_error_return(svn_wc_context_destroy(wc_ctx));
}
@@ -584,7 +593,7 @@ svn_wc_process_committed4(const char *pa
new_revnum, new_date, rev_author,
wcprop_changes_hash,
!remove_lock, !remove_changelist,
- checksum, NULL, pool));
+ checksum, NULL, NULL, pool));
/* Run the log file(s) we just created. */
return svn_error_return(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool));
@@ -741,13 +750,13 @@ svn_wc_add3(const char *path,
/* Make sure the caller gets the new access baton in the set. */
if (svn_wc__adm_retrieve_internal2(wc_db, local_abspath, pool) == NULL)
{
- svn_node_kind_t kind;
- svn_wc_adm_access_t *adm_access;
-
- SVN_ERR(svn_wc__node_get_kind(&kind, wc_ctx, local_abspath, FALSE, pool));
+ svn_wc__db_kind_t kind;
- if (kind == svn_node_dir)
+ SVN_ERR(svn_wc__db_read_kind(&kind, wc_db, local_abspath, FALSE, pool));
+ if (kind == svn_wc__db_kind_dir)
{
+ svn_wc_adm_access_t *adm_access;
+
/* Open the access baton in adm_access' pool to give it the same
lifetime */
SVN_ERR(svn_wc_adm_open3(&adm_access, parent_access, path, TRUE,
@@ -1044,17 +1053,14 @@ svn_wc_get_ancestry(char **url,
apr_pool_t *pool)
{
const char *local_abspath;
- svn_wc_context_t *wc_ctx;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
- svn_wc__adm_get_db(adm_access),
- pool));
-
- SVN_ERR(svn_wc_get_ancestry2((const char **)url, rev, wc_ctx, local_abspath,
- pool, pool));
- return svn_error_return(svn_wc_context_destroy(wc_ctx));
+ return svn_error_return(svn_wc__internal_get_ancestry(
+ (const char **)url, rev,
+ svn_wc__adm_get_db(adm_access),
+ local_abspath,
+ pool, pool));
}
svn_error_t *
@@ -1616,6 +1622,7 @@ wrap_4to3_dir_props_changed(const char *
static svn_error_t *
wrap_4to3_dir_opened(const char *local_dir_abspath,
svn_boolean_t *tree_conflicted,
+ svn_boolean_t *skip_children,
const char *path,
svn_revnum_t rev,
void *diff_baton,
@@ -1627,6 +1634,8 @@ wrap_4to3_dir_opened(const char *local_d
if (local_dir_abspath)
adm_access = svn_wc__adm_retrieve_internal2(b->db, local_dir_abspath,
scratch_pool);
+ if (skip_children)
+ *skip_children = FALSE;
return b->callbacks3->dir_opened(adm_access, tree_conflicted, path, rev,
b->baton);
@@ -2124,29 +2133,25 @@ svn_wc_merge_props2(svn_wc_notify_state_
svn_boolean_t dry_run,
svn_wc_conflict_resolver_func_t conflict_func,
void *conflict_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
- svn_wc_context_t *wc_ctx;
const char *local_abspath;
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
- svn_wc__adm_get_db(adm_access), pool));
-
- SVN_ERR(svn_wc_merge_props3(state,
- wc_ctx,
- local_abspath,
- NULL, /* left_version */
- NULL, /* right_version */
- baseprops,
- propchanges,
- base_merge,
- dry_run,
- conflict_func, conflict_baton,
- NULL, NULL,
- pool));
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
- return svn_error_return(svn_wc_context_destroy(wc_ctx));
+ return svn_error_return(svn_wc__perform_props_merge(
+ state,
+ svn_wc__adm_get_db(adm_access),
+ local_abspath,
+ NULL /* left_version */,
+ NULL /* right_version */,
+ baseprops,
+ propchanges,
+ base_merge,
+ dry_run,
+ conflict_func, conflict_baton,
+ NULL, NULL,
+ scratch_pool));
}
svn_error_t *
@@ -2224,19 +2229,23 @@ struct status4_wrapper_baton
void *old_baton;
const char *anchor_abspath;
const char *anchor_relpath;
+ svn_wc_context_t *wc_ctx;
};
/* */
static svn_error_t *
status4_wrapper_func(void *baton,
const char *local_abspath,
- const svn_wc_status2_t *status,
+ const svn_wc_status3_t *status,
apr_pool_t *scratch_pool)
{
struct status4_wrapper_baton *swb = baton;
- svn_wc_status2_t *dup = svn_wc_dup_status2(status, scratch_pool);
+ svn_wc_status2_t *dup;
const char *path = local_abspath;
+ SVN_ERR(svn_wc__status2_from_3(&dup, status, swb->wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+
if (swb->anchor_abspath != NULL)
{
path = svn_dirent_join(
@@ -2281,6 +2290,8 @@ svn_wc_get_status_editor4(const svn_delt
SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
wc_db, pool));
+ swb->wc_ctx = wc_ctx;
+
anchor_abspath = svn_wc__adm_access_abspath(anchor);
if (!svn_dirent_is_absolute(svn_wc_adm_access_path(anchor)))
@@ -2468,6 +2479,37 @@ svn_wc_status(svn_wc_status_t **status,
return SVN_NO_ERROR;
}
+svn_wc_status2_t *
+svn_wc_dup_status2(const svn_wc_status2_t *orig_stat,
+ apr_pool_t *pool)
+{
+ svn_wc_status2_t *new_stat = apr_palloc(pool, sizeof(*new_stat));
+
+ /* Shallow copy all members. */
+ *new_stat = *orig_stat;
+
+ /* Now go back and dup the deep items into this pool. */
+ if (orig_stat->entry)
+ new_stat->entry = svn_wc_entry_dup(orig_stat->entry, pool);
+
+ if (orig_stat->repos_lock)
+ new_stat->repos_lock = svn_lock_dup(orig_stat->repos_lock, pool);
+
+ if (orig_stat->url)
+ new_stat->url = apr_pstrdup(pool, orig_stat->url);
+
+ if (orig_stat->ood_last_cmt_author)
+ new_stat->ood_last_cmt_author
+ = apr_pstrdup(pool, orig_stat->ood_last_cmt_author);
+
+ if (orig_stat->tree_conflict)
+ new_stat->tree_conflict
+ = svn_wc__conflict_description_dup(orig_stat->tree_conflict, pool);
+
+ /* Return the new hotness. */
+ return new_stat;
+}
+
svn_wc_status_t *
svn_wc_dup_status(const svn_wc_status_t *orig_stat,
apr_pool_t *pool)
@@ -2515,13 +2557,16 @@ svn_wc_status2(svn_wc_status2_t **status
{
const char *local_abspath;
svn_wc_context_t *wc_ctx;
+ svn_wc_status3_t *stat3;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
svn_wc__adm_get_db(adm_access),
pool));
- SVN_ERR(svn_wc_status3(status, wc_ctx, local_abspath, pool, pool));
+ SVN_ERR(svn_wc_status3(&stat3, wc_ctx, local_abspath, pool, pool));
+ SVN_ERR(svn_wc__status2_from_3(status, stat3, wc_ctx, local_abspath,
+ pool, pool));
return svn_error_return(svn_wc_context_destroy(wc_ctx));
}
@@ -3160,7 +3205,7 @@ svn_wc_translated_file2(const char **xla
pool));
SVN_ERR(svn_wc_translated_file3(xlated_path, src, wc_ctx, versioned_abspath,
- flags, pool, pool));
+ flags, NULL, NULL, pool, pool));
if (! svn_dirent_is_absolute(versioned_file))
{
SVN_ERR(svn_io_temp_dir(&tmp_root, pool));
@@ -3710,15 +3755,15 @@ svn_wc_queue_committed2(svn_wc_committed
const apr_array_header_t *wcprop_changes,
svn_boolean_t remove_lock,
svn_boolean_t remove_changelist,
- const svn_checksum_t *checksum,
+ const svn_checksum_t *md5_checksum,
apr_pool_t *scratch_pool)
{
const char *local_abspath;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
return svn_wc_queue_committed3(queue, local_abspath, recurse, wcprop_changes,
- remove_lock, remove_changelist, checksum,
- scratch_pool);
+ remove_lock, remove_changelist, md5_checksum,
+ NULL /* sha1_checksum */, scratch_pool);
}
svn_error_t *
@@ -3732,18 +3777,18 @@ svn_wc_queue_committed(svn_wc_committed_
const unsigned char *digest,
apr_pool_t *pool)
{
- const svn_checksum_t *checksum;
+ const svn_checksum_t *md5_checksum;
if (digest)
- checksum = svn_checksum__from_digest(
+ md5_checksum = svn_checksum__from_digest(
digest, svn_checksum_md5,
svn_wc__get_committed_queue_pool(*queue));
else
- checksum = NULL;
+ md5_checksum = NULL;
return svn_wc_queue_committed2(*queue, path, adm_access, recurse,
wcprop_changes, remove_lock,
- remove_changelist, checksum, pool);
+ remove_changelist, md5_checksum, pool);
}
svn_error_t *
@@ -3766,3 +3811,45 @@ svn_wc_process_committed_queue(svn_wc_co
return SVN_NO_ERROR;
}
+#ifdef SVN_DISABLE_FULL_VERSION_MATCH
+/* This double underscore name is used by the 1.6 libsvn_client.
+ Keeping this name is sufficient for the 1.6 libsvn_client to link
+ against the 1.7 libraries. This is only needed for pre-release
+ testing, it's not needed when all the Subversion libraries are
+ upgraded together. */
+svn_error_t *
+svn_wc__entry_versioned_internal(const svn_wc_entry_t **entry,
+ const char *path,
+ svn_wc_adm_access_t *adm_access,
+ svn_boolean_t show_hidden,
+ const char *caller_filename,
+ int caller_lineno,
+ apr_pool_t *pool);
+svn_error_t *
+svn_wc__entry_versioned_internal(const svn_wc_entry_t **entry,
+ const char *path,
+ svn_wc_adm_access_t *adm_access,
+ svn_boolean_t show_hidden,
+ const char *caller_filename,
+ int caller_lineno,
+ apr_pool_t *pool)
+{
+ svn_wc_context_t *wc_ctx;
+ const char *local_abspath;
+
+ SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
+ svn_wc__adm_get_db(adm_access),
+ pool));
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+
+ SVN_ERR(svn_wc__get_entry_versioned(entry, wc_ctx, local_abspath,
+ svn_node_unknown, show_hidden,
+ FALSE, /* NEED_PARENT_STUB */
+ pool, pool));
+
+ SVN_ERR(svn_wc_context_destroy(wc_ctx));
+
+ return SVN_NO_ERROR;
+}
+#endif
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c Tue Aug 10 20:55:56 2010
@@ -125,6 +125,103 @@ reverse_propchanges(apr_hash_t *baseprop
}
+/* Set *RESULT_ABSPATH to the absolute path to a readable file containing
+ the pristine text of LOCAL_ABSPATH in DB, or to NULL if it does not have
+ any pristine text. If the node has more than one pristine text, get the
+ one that is "nearest" to the working version. That means the pristine
+ text of the copied file if this node is copied or moved here, else of the
+ replaced file if it is an add that replaces a file, else of its base
+ node, or NULL if it is a simple add or an add that replaces a non-file.
+
+ Rationale:
+
+ Which text-base do we want to use for the diff? If the node is replaced
+ by a new file, then the base of the replaced file is called (in WC-1) the
+ "revert base". If the replacement is a copy or move, then there is also
+ the base of the copied file to consider.
+
+ One could argue that we should never diff against the revert
+ base, and instead diff against the empty-file for both types of
+ replacement. After all, there is no ancestry relationship
+ between the working file and the base file. But my guess is that
+ in practice, users want to see the diff between their working
+ file and "the nearest versioned thing", whatever that is. I'm
+ not 100% sure this is the right decision, but it at least seems
+ to match our test suite's expectations. */
+static svn_error_t *
+get_nearest_pristine_text_as_file(const char **result_abspath,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+#ifdef SVN_EXPERIMENTAL_PRISTINE
+ const svn_checksum_t *checksum;
+
+ SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, &checksum,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ db, local_abspath, scratch_pool, scratch_pool));
+ if (checksum == NULL)
+ {
+ svn_error_t *err;
+
+ err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, &checksum,
+ NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool);
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ checksum = NULL;
+ }
+ else if (err)
+ return svn_error_return(err);
+ }
+
+ if (checksum != NULL)
+ {
+ SVN_ERR(svn_wc__db_pristine_get_path(result_abspath, db, local_abspath,
+ checksum,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+ }
+#else
+ svn_error_t *err;
+
+ err = svn_wc__text_base_path_to_read(result_abspath, db, local_abspath,
+ result_pool, scratch_pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ svn_error_clear(err);
+ else
+ return svn_error_return(err);
+
+ err = svn_wc__text_revert_path_to_read(result_abspath, db, local_abspath,
+ result_pool);
+
+ /* If there is no revert base to diff either, don't attempt to diff it.
+ ### This is a band-aid.
+ ### In WC-NG, files added within a copied subtree are marked "copied",
+ ### which will cause the code below to end up calling
+ ### eb->callbacks->file_changed() with a non-existent text-base.
+ ### Not sure how to properly tell apart a file added within a copied
+ ### subtree from a copied file. But eventually we'll have to get the
+ ### base text from the pristine store anyway and use tempfiles (or
+ ### streams, hopefully) for diffing, so this hack will just go away. */
+ if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ svn_error_clear(err);
+ else
+ return svn_error_return(err);
+#endif
+
+ *result_abspath = NULL;
+ return SVN_NO_ERROR;
+}
+
+
/*-------------------------------------------------------------------------*/
@@ -444,66 +541,6 @@ get_prop_mimetype(apr_hash_t *props)
}
-/* Set *MIMETYPE to the BASE version of the svn:mime-type property of
- file LOCAL_ABSPATH, using DB, or to NULL if no such property exists.
- BASEPROPS is optional: if present, use it to cache the BASE properties
- of the file.
-
- Return the property value and property hash allocated in RESULT_POOL,
- use SCRATCH_POOL for temporary accesses.
-*/
-static svn_error_t *
-get_base_mimetype(const char **mimetype,
- apr_hash_t **baseprops,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *props = NULL;
-
- if (baseprops == NULL)
- baseprops = &props;
-
- if (*baseprops == NULL)
- SVN_ERR(svn_wc__internal_propdiff(NULL, baseprops, db, local_abspath,
- result_pool, scratch_pool));
-
- *mimetype = get_prop_mimetype(*baseprops);
-
- return SVN_NO_ERROR;
-}
-
-
-/* Set *MIMETYPE to the WORKING version of the svn:mime-type property
- of file LOCAL_ABSPATH, using DB, or to NULL if no such property exists.
- WORKINGPROPS is optional: if present, use it to cache the WORKING
- properties of the file.
-
- Return the property value and property hash allocated in POOL.
-*/
-static svn_error_t *
-get_working_mimetype(const char **mimetype,
- apr_hash_t **workingprops,
- const char *local_abspath,
- svn_wc__db_t *db,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *props = NULL;
-
- if (workingprops == NULL)
- workingprops = &props;
-
- if (*workingprops == NULL)
- SVN_ERR(svn_wc__load_props(NULL, workingprops, db, local_abspath,
- result_pool, scratch_pool));
-
- *mimetype = get_prop_mimetype(*workingprops);
-
- return SVN_NO_ERROR;
-}
-
/* Return the property hash resulting from combining PROPS and PROPCHANGES.
*
* A note on pool usage: The returned hash and hash keys are allocated in
@@ -529,7 +566,7 @@ apply_propchanges(apr_hash_t *props,
}
-/* Called by directory_elements_diff when a file is to be compared. At this
+/* Diff the file PATH against its text base. At this
* stage we are dealing with a file that does exist in the working copy.
*
* DIR_BATON is the parent directory baton, PATH is the path to the file to
@@ -551,8 +588,9 @@ file_diff(struct dir_baton *db,
svn_boolean_t replaced;
svn_wc__db_status_t status;
svn_revnum_t revision;
- apr_array_header_t *propchanges = NULL;
- apr_hash_t *baseprops = NULL;
+ svn_revnum_t revert_base_revnum;
+ svn_boolean_t base_shadowed;
+ svn_wc__db_status_t base_status;
const char *local_abspath;
SVN_ERR_ASSERT(! eb->use_text_base);
@@ -570,83 +608,47 @@ file_diff(struct dir_baton *db,
SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, eb->db, local_abspath,
- pool, pool));
+ &base_shadowed, NULL, NULL,
+ eb->db, local_abspath, pool, pool));
+ if (base_shadowed)
+ SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, &revert_base_revnum,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ eb->db, local_abspath, pool, pool));
+
+ replaced = ((status == svn_wc__db_status_added
+ || status == svn_wc__db_status_obstructed_add)
+ && base_shadowed
+ && base_status != svn_wc__db_status_not_present);
+ /* Now refine ADDED to one of: ADDED, COPIED, MOVED_HERE. Note that only
+ the latter two have corresponding pristine info to diff against. */
if (status == svn_wc__db_status_added)
SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, eb->db, local_abspath,
pool, pool));
- /* Prep these two paths early. */
- SVN_ERR(svn_wc__text_base_path(&textbase, eb->db, local_abspath, FALSE,
- pool));
-
- /* If the regular text base is not there, we fall back to the revert
- text base (if that's not present either, we'll error later). But
- the logic here is subtler than one might at first expect.
-
- When the file has some non-replacement scheduling, then it can be
- expected to still have its regular text base. But what about
- when it's replaced or replaced-with-history? In both cases, a
- revert text-base will be present; in the latter case only, a
- regular text-base be present as well. So which text-base do we
- want to use for the diff?
-
- One could argue that we should never diff against the revert
- base, and instead diff against the empty-file for both types of
- replacement. After all, there is no ancestry relationship
- between the working file and the base file. But my guess is that
- in practice, users want to see the diff between their working
- file and "the nearest versioned thing", whatever that is. I'm
- not 100% sure this is the right decision, but it at least seems
- to match our test suite's expectations. */
- {
- svn_node_kind_t kind;
- SVN_ERR(svn_io_check_path(textbase, &kind, pool));
- if (kind == svn_node_none)
- SVN_ERR(svn_wc__text_revert_path(&textbase, eb->db, local_abspath,
- pool));
-
- /* If there is no revert base to diff either, don't attempt to diff it.
- * ### This is a band-aid.
- * ### In WC-NG, files added within a copied subtree are marked "copied",
- * ### which will cause the code below to end up calling
- * ### eb->callbacks->file_changed() with a non-existent text-base.
- * ### Not sure how to properly tell apart a file added within a copied
- * ### subtree from a copied file. But eventually we'll have to get the
- * ### base text from the pristine store anyway and use tempfiles (or
- * ### streams, hopefully) for diffing, so all this horrible statting
- * ### the disk for text bases, and this hack, will just go away. */
- SVN_ERR(svn_io_check_path(textbase, &kind, pool));
- if (kind == svn_node_none)
- textbase = NULL;
- }
+ /* A wc-wc diff of replaced files actually shows a diff against the
+ * revert-base, showing all previous lines as removed and adding all new
+ * lines. This does not happen for copied/moved-here files, not even with
+ * show_copies_as_adds == TRUE (in which case copy/move is really shown as
+ * an add, diffing against the empty file).
+ * So show the revert-base revision for plain replaces. */
+ if (replaced
+ && ! (status == svn_wc__db_status_copied
+ || status == svn_wc__db_status_moved_here))
+ revision = revert_base_revnum;
+
+ /* Set TEXTBASE to the path to the text-base file that we want to diff
+ against.
+
+ ### There shouldn't be cases where the result is NULL, but at present
+ there might be - see get_nearest_pristine_text_as_file(). */
+ SVN_ERR(get_nearest_pristine_text_as_file(&textbase, eb->db, local_abspath,
+ pool, pool));
SVN_ERR(get_empty_file(eb, &empty_file));
- /* Get property diffs if this is not schedule delete. */
- if (status != svn_wc__db_status_deleted)
- {
- svn_boolean_t modified;
-
- SVN_ERR(svn_wc__props_modified(&modified, eb->db, local_abspath,
- pool));
- if (modified)
- SVN_ERR(svn_wc__internal_propdiff(&propchanges, &baseprops, eb->db,
- local_abspath, pool, pool));
- else
- propchanges = apr_array_make(pool, 1, sizeof(svn_prop_t));
- }
- else
- {
- SVN_ERR(svn_wc__internal_propdiff(NULL, &baseprops, eb->db,
- local_abspath, pool, pool));
- }
-
- SVN_ERR(svn_wc__internal_is_replaced(&replaced, eb->db, local_abspath,
- pool));
-
/* Delete compares text-base against empty file, modifications to the
* working-copy version of the deleted file are not wanted.
* Replace is treated like a delete plus an add: two comparisons are
@@ -657,10 +659,12 @@ file_diff(struct dir_baton *db,
(replaced && ! eb->ignore_ancestry))
{
const char *base_mimetype;
+ apr_hash_t *baseprops;
- /* Get svn:mime-type from BASE props of PATH. */
- SVN_ERR(get_base_mimetype(&base_mimetype, &baseprops, eb->db,
- local_abspath, pool, pool));
+ /* Get svn:mime-type from pristine props (in BASE or WORKING) of PATH. */
+ SVN_ERR(svn_wc__get_pristine_props(&baseprops, eb->db, local_abspath,
+ pool, pool));
+ base_mimetype = get_prop_mimetype(baseprops);
SVN_ERR(eb->callbacks->file_deleted(NULL, NULL, NULL, path,
textbase,
@@ -690,14 +694,24 @@ file_diff(struct dir_baton *db,
{
const char *translated = NULL;
const char *working_mimetype;
-
- /* Get svn:mime-type from working props of PATH. */
- SVN_ERR(get_working_mimetype(&working_mimetype, NULL, local_abspath,
- eb->db, pool, pool));
+ apr_hash_t *baseprops;
+ apr_hash_t *workingprops;
+ apr_array_header_t *propchanges;
+
+ /* Get svn:mime-type from ACTUAL props of PATH. */
+ SVN_ERR(svn_wc__get_actual_props(&workingprops, eb->db, local_abspath,
+ pool, pool));
+ working_mimetype = get_prop_mimetype(workingprops);
+
+ /* Set the original properties to empty, then compute "changes" from
+ that. Essentially, all ACTUAL props will be "added". */
+ baseprops = apr_hash_make(pool);
+ SVN_ERR(svn_prop_diffs(&propchanges, workingprops, baseprops, pool));
SVN_ERR(svn_wc__internal_translated_file(
&translated, local_abspath, eb->db, local_abspath,
SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_USE_GLOBAL_TMP,
+ eb->cancel_func, eb->cancel_baton,
pool, pool));
SVN_ERR(eb->callbacks->file_added(NULL, NULL, NULL, NULL, path,
@@ -715,6 +729,11 @@ file_diff(struct dir_baton *db,
{
svn_boolean_t modified;
const char *translated = NULL;
+ apr_hash_t *baseprops;
+ const char *base_mimetype;
+ const char *working_mimetype;
+ apr_hash_t *workingprops;
+ apr_array_header_t *propchanges;
/* Here we deal with showing pure modifications. */
@@ -729,22 +748,45 @@ file_diff(struct dir_baton *db,
already expensive, translating twice for the sake of code
modularity is liveable. */
SVN_ERR(svn_wc__internal_translated_file(
- &translated, local_abspath, eb->db, local_abspath,
- SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_USE_GLOBAL_TMP,
- pool, pool));
+ &translated, local_abspath, eb->db, local_abspath,
+ SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_USE_GLOBAL_TMP,
+ eb->cancel_func, eb->cancel_baton,
+ pool, pool));
}
- if (modified || propchanges->nelts > 0)
+ /* Get the properties, the svn:mime-type values, and compute the
+ differences between the two. */
+ if (replaced
+ && eb->ignore_ancestry)
{
- const char *base_mimetype;
- const char *working_mimetype;
+ /* We don't want the normal pristine properties (which are
+ from the WORKING tree). We want the pristines associated
+ with the BASE tree, which are saved as "revert" props. */
+ SVN_ERR(svn_wc__get_revert_props(&baseprops,
+ eb->db, local_abspath,
+ pool, pool));
+ }
+ else
+ {
+ /* We can only fetch the pristine props (from BASE or WORKING) if
+ the node has not been replaced, or it was copied/moved here. */
+ SVN_ERR_ASSERT(!replaced
+ || status == svn_wc__db_status_copied
+ || status == svn_wc__db_status_moved_here);
+
+ SVN_ERR(svn_wc__get_pristine_props(&baseprops, eb->db, local_abspath,
+ pool, pool));
+ }
+ base_mimetype = get_prop_mimetype(baseprops);
+
+ SVN_ERR(svn_wc__get_actual_props(&workingprops, eb->db, local_abspath,
+ pool, pool));
+ working_mimetype = get_prop_mimetype(workingprops);
- /* Get svn:mime-type for both base and working file. */
- SVN_ERR(get_base_mimetype(&base_mimetype, &baseprops, eb->db,
- local_abspath, pool, pool));
- SVN_ERR(get_working_mimetype(&working_mimetype, NULL, local_abspath,
- eb->db, pool, pool));
+ SVN_ERR(svn_prop_diffs(&propchanges, workingprops, baseprops, pool));
+ if (modified || propchanges->nelts > 0)
+ {
SVN_ERR(eb->callbacks->file_changed(NULL, NULL, NULL, NULL,
path,
modified ? textbase : NULL,
@@ -982,25 +1024,28 @@ report_wc_file_as_added(struct dir_baton
emptyprops = apr_hash_make(pool);
if (eb->use_text_base)
- SVN_ERR(get_base_mimetype(&mimetype, &wcprops, eb->db, local_abspath,
- pool, pool));
+ SVN_ERR(svn_wc__get_pristine_props(&wcprops, eb->db, local_abspath,
+ pool, pool));
else
- SVN_ERR(get_working_mimetype(&mimetype, &wcprops, local_abspath,
- eb->db, pool, pool));
+ SVN_ERR(svn_wc__get_actual_props(&wcprops, eb->db, local_abspath,
+ pool, pool));
+ mimetype = get_prop_mimetype(wcprops);
SVN_ERR(svn_prop_diffs(&propchanges,
wcprops, emptyprops, pool));
if (eb->use_text_base)
- SVN_ERR(svn_wc__text_base_path(&source_file, eb->db, local_abspath, FALSE,
- pool));
+ SVN_ERR(svn_wc__text_base_path_to_read(&source_file,
+ eb->db, local_abspath,
+ pool, pool));
else
source_file = path;
SVN_ERR(svn_wc__internal_translated_file(
&translated_file, source_file, eb->db, local_abspath,
SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_USE_GLOBAL_TMP,
+ eb->cancel_func, eb->cancel_baton,
pool, pool));
SVN_ERR(eb->callbacks->file_added(db->local_abspath,
@@ -1049,11 +1094,11 @@ report_wc_directory_as_added(struct dir_
eb->changelist_hash, pool))
{
if (eb->use_text_base)
- SVN_ERR(svn_wc__internal_propdiff(NULL, &wcprops, eb->db, dir_abspath,
- pool, pool));
+ SVN_ERR(svn_wc__get_pristine_props(&wcprops, eb->db, dir_abspath,
+ pool, pool));
else
- SVN_ERR(svn_wc__load_props(NULL, &wcprops, eb->db, dir_abspath,
- pool, pool));
+ SVN_ERR(svn_wc__get_actual_props(&wcprops, eb->db, dir_abspath,
+ pool, pool));
SVN_ERR(svn_prop_diffs(&propchanges, wcprops, emptyprops, pool));
@@ -1221,11 +1266,13 @@ delete_entry(const char *path,
apr_hash_t *baseprops = NULL;
const char *base_mimetype;
- SVN_ERR(svn_wc__text_base_path(&textbase, eb->db, local_abspath,
- FALSE, pool));
-
- SVN_ERR(get_base_mimetype(&base_mimetype, &baseprops, eb->db,
- local_abspath, pool, pool));
+ SVN_ERR(svn_wc__text_base_path_to_read(&textbase,
+ eb->db, local_abspath,
+ pool, pool));
+
+ SVN_ERR(svn_wc__get_pristine_props(&baseprops, eb->db, local_abspath,
+ pool, pool));
+ base_mimetype = get_prop_mimetype(baseprops);
SVN_ERR(eb->callbacks->file_deleted(NULL, NULL, NULL, full_path,
textbase,
@@ -1332,19 +1379,22 @@ close_directory(void *dir_baton,
{
if (db->eb->use_text_base)
{
- SVN_ERR(svn_wc__internal_propdiff(NULL, &originalprops, eb->db,
- db->local_abspath, pool, pool));
+ SVN_ERR(svn_wc__get_pristine_props(&originalprops,
+ eb->db, db->local_abspath,
+ pool, pool));
}
else
{
apr_hash_t *base_props, *repos_props;
- SVN_ERR(svn_wc__load_props(NULL, &originalprops,
- eb->db, db->local_abspath, pool, pool));
+ SVN_ERR(svn_wc__get_actual_props(&originalprops,
+ eb->db, db->local_abspath,
+ pool, pool));
/* Load the BASE and repository directory properties. */
- SVN_ERR(svn_wc__internal_propdiff(NULL, &base_props, eb->db,
- db->local_abspath, pool, pool));
+ SVN_ERR(svn_wc__get_pristine_props(&base_props,
+ eb->db, db->local_abspath,
+ pool, pool));
repos_props = apply_propchanges(base_props, db->propchanges);
@@ -1575,8 +1625,8 @@ close_file(void *file_baton,
if (fb->added)
base_props = apr_hash_make(pool);
else
- SVN_ERR(svn_wc__internal_propdiff(NULL, &base_props, eb->db,
- fb->local_abspath, pool, pool));
+ SVN_ERR(svn_wc__get_pristine_props(&base_props, eb->db,
+ fb->local_abspath, pool, pool));
repos_props = apply_propchanges(base_props, fb->propchanges);
@@ -1587,8 +1637,9 @@ close_file(void *file_baton,
the same as BASE. */
temp_file_path = fb->temp_file_path;
if (!temp_file_path)
- SVN_ERR(svn_wc__text_base_path(&temp_file_path, eb->db, fb->local_abspath,
- FALSE, fb->pool));
+ SVN_ERR(svn_wc__text_base_path_to_read(&temp_file_path,
+ eb->db, fb->local_abspath,
+ fb->pool, pool));
/* If the file isn't in the working copy (either because it was added
in the BASE->repos diff or because we're diffing against WORKING
@@ -1651,13 +1702,15 @@ close_file(void *file_baton,
if (modified)
{
if (eb->use_text_base)
- SVN_ERR(svn_wc__text_base_path(&localfile, eb->db, fb->local_abspath,
- FALSE, fb->pool));
+ SVN_ERR(svn_wc__text_base_path_to_read(&localfile,
+ eb->db, fb->local_abspath,
+ fb->pool, pool));
else
/* a detranslated version of the working file */
SVN_ERR(svn_wc__internal_translated_file(
&localfile, fb->local_abspath, eb->db, fb->local_abspath,
SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_USE_GLOBAL_TMP,
+ eb->cancel_func, eb->cancel_baton,
pool, pool));
}
else
@@ -1669,8 +1722,9 @@ close_file(void *file_baton,
}
else
{
- SVN_ERR(svn_wc__load_props(NULL, &originalprops, eb->db,
- fb->local_abspath, pool, pool));
+ SVN_ERR(svn_wc__get_actual_props(&originalprops,
+ eb->db, fb->local_abspath,
+ pool, pool));
/* We have the repository properties in repos_props, and the
WORKING properties in originalprops. Recalculate
@@ -1797,6 +1851,7 @@ svn_wc_get_diff_editor6(const svn_delta_
void *inner_baton;
svn_delta_editor_t *tree_editor;
const svn_delta_editor_t *inner_editor;
+ const char *anchor_abspath;
SVN_ERR(make_edit_baton(&eb,
wc_ctx->db,
@@ -1826,12 +1881,14 @@ svn_wc_get_diff_editor6(const svn_delta_
inner_editor = tree_editor;
inner_baton = eb;
+ SVN_ERR(svn_dirent_get_absolute(&anchor_abspath, anchor_path, result_pool));
+
if (depth == svn_depth_unknown)
SVN_ERR(svn_wc__ambient_depth_filter_editor(&inner_editor,
&inner_baton,
inner_editor,
inner_baton,
- anchor_path,
+ anchor_abspath,
target,
wc_ctx->db,
result_pool));