You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2011/04/29 10:27:58 UTC
svn commit: r1097725 - /subversion/trunk/subversion/libsvn_wc/diff_local.c
Author: rhuijben
Date: Fri Apr 29 08:27:58 2011
New Revision: 1097725
URL: http://svn.apache.org/viewvc?rev=1097725&view=rev
Log:
In the working copy local diff walker: Reduce the editor baton to a simple diff
baton containing only what is really necessary for the local diff.
* subversion/libsvn_wc/diff_local.c
(edit_baton): Rename to ...
(diff_baton): And remove unused/unneeded variables.
(get_empty_file): Update baton user. Add scratch_pool argument.
(file_diff): Update caller.
(make_edit_baton): Remove function; move implementation into svn_wc_diff6.
(walk_local_nodes_diff): Update caller Remove anchor checks.
(svn_wc_diff6): Rename pool to scratch_pool. Create the diff baton as
local variable.
Modified:
subversion/trunk/subversion/libsvn_wc/diff_local.c
Modified: subversion/trunk/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_local.c?rev=1097725&r1=1097724&r2=1097725&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_local.c Fri Apr 29 08:27:58 2011
@@ -120,24 +120,12 @@ get_pristine_file(const char **result_ab
/*-------------------------------------------------------------------------*/
-/* Overall crawler editor baton.
- */
-struct edit_baton {
+/* The diff baton */
+struct diff_baton
+{
/* A wc db. */
svn_wc__db_t *db;
- /* ANCHOR/TARGET represent the base of the hierarchy to be compared. */
- const char *target;
-
- /* The absolute path of the anchor directory */
- const char *anchor_abspath;
-
- /* Target revision */
- svn_revnum_t revnum;
-
- /* Was the root opened? */
- svn_boolean_t root_opened;
-
/* The callbacks and callback argument that implement the file comparison
functions */
const svn_wc_diff_callbacks4_t *callbacks;
@@ -155,12 +143,6 @@ struct edit_baton {
/* Are we producing a git-style diff? */
svn_boolean_t use_git_diff_format;
- /* Possibly diff repos against text-bases instead of working files. */
- svn_boolean_t use_text_base;
-
- /* Possibly show the diffs backwards. */
- svn_boolean_t reverse_order;
-
/* Empty file used to diff adds / deletes */
const char *empty_file;
@@ -174,85 +156,25 @@ struct edit_baton {
apr_pool_t *pool;
};
-/* Create a new edit baton. TARGET_PATH/ANCHOR are working copy paths
- * that describe the root of the comparison. CALLBACKS/CALLBACK_BATON
- * define the callbacks to compare files. DEPTH defines if and how to
- * descend into subdirectories; see public doc string for exactly how.
- * IGNORE_ANCESTRY defines whether to utilize node ancestry when
- * calculating diffs. USE_TEXT_BASE defines whether to compare
- * against working files or text-bases. REVERSE_ORDER defines which
- * direction to perform the diff.
- *
- * CHANGELISTS is a list of const char * changelist names, used to
- * filter diff output responses to only those items in one of the
- * specified changelists, empty (or NULL altogether) if no changelist
- * filtering is requested.
- */
-static svn_error_t *
-make_edit_baton(struct edit_baton **edit_baton,
- svn_wc__db_t *db,
- const char *anchor_abspath,
- const char *target,
- const svn_wc_diff_callbacks4_t *callbacks,
- void *callback_baton,
- svn_depth_t depth,
- svn_boolean_t ignore_ancestry,
- svn_boolean_t show_copies_as_adds,
- svn_boolean_t use_git_diff_format,
- svn_boolean_t use_text_base,
- svn_boolean_t reverse_order,
- const apr_array_header_t *changelists,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *pool)
-{
- apr_hash_t *changelist_hash = NULL;
- struct edit_baton *eb;
-
- SVN_ERR_ASSERT(svn_dirent_is_absolute(anchor_abspath));
-
- if (changelists && changelists->nelts)
- SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
-
- eb = apr_pcalloc(pool, sizeof(*eb));
- eb->db = db;
- eb->anchor_abspath = apr_pstrdup(pool, anchor_abspath);
- eb->target = apr_pstrdup(pool, target);
- eb->callbacks = callbacks;
- eb->callback_baton = callback_baton;
- eb->depth = depth;
- eb->ignore_ancestry = ignore_ancestry;
- eb->show_copies_as_adds = show_copies_as_adds;
- eb->use_git_diff_format = use_git_diff_format;
- eb->use_text_base = use_text_base;
- eb->reverse_order = reverse_order;
- eb->changelist_hash = changelist_hash;
- eb->cancel_func = cancel_func;
- eb->cancel_baton = cancel_baton;
- eb->pool = pool;
-
- *edit_baton = eb;
- return SVN_NO_ERROR;
-}
-
/* Get the empty file associated with the edit baton. This is cached so
* that it can be reused, all empty files are the same.
*/
static svn_error_t *
-get_empty_file(struct edit_baton *b,
- const char **empty_file)
+get_empty_file(struct diff_baton *eb,
+ const char **empty_file,
+ apr_pool_t *scratch_pool)
{
/* Create the file if it does not exist */
/* Note that we tried to use /dev/null in r857294, but
that won't work on Windows: it's impossible to stat NUL */
- if (!b->empty_file)
+ if (!eb->empty_file)
{
- SVN_ERR(svn_io_open_unique_file3(NULL, &b->empty_file, NULL,
+ SVN_ERR(svn_io_open_unique_file3(NULL, &eb->empty_file, NULL,
svn_io_file_del_on_pool_cleanup,
- b->pool, b->pool));
+ eb->pool, scratch_pool));
}
- *empty_file = b->empty_file;
+ *empty_file = eb->empty_file;
return SVN_NO_ERROR;
}
@@ -284,7 +206,7 @@ get_prop_mimetype(apr_hash_t *props)
* directory.
*/
static svn_error_t *
-file_diff(struct edit_baton *eb,
+file_diff(struct diff_baton *eb,
const char *local_abspath,
const char *path,
apr_pool_t *scratch_pool)
@@ -301,8 +223,6 @@ file_diff(struct edit_baton *eb,
svn_wc__db_status_t base_status;
svn_boolean_t use_base = FALSE;
- SVN_ERR_ASSERT(! eb->use_text_base);
-
/* If the item is not a member of a specified changelist (and there are
some specified changelists), skip it. */
if (! svn_wc__internal_changelist_match(db, local_abspath,
@@ -357,7 +277,7 @@ file_diff(struct edit_baton *eb,
SVN_ERR(get_pristine_file(&textbase, db, local_abspath,
use_base, scratch_pool, scratch_pool));
- SVN_ERR(get_empty_file(eb, &empty_file));
+ SVN_ERR(get_empty_file(eb, &empty_file, scratch_pool));
/* Delete compares text-base against empty file, modifications to the
* working-copy version of the deleted file are not wanted.
@@ -536,7 +456,7 @@ file_diff(struct edit_baton *eb,
* DIR_BATON is the baton for the directory.
*/
static svn_error_t *
-walk_local_nodes_diff(struct edit_baton *eb,
+walk_local_nodes_diff(struct diff_baton *eb,
const char *local_abspath,
const char *path,
svn_depth_t depth,
@@ -546,19 +466,8 @@ walk_local_nodes_diff(struct edit_baton
svn_wc__db_t *db = eb->db;
const apr_array_header_t *children;
int i;
- svn_boolean_t in_anchor_not_target;
apr_pool_t *iterpool;
- /* Everything we do below is useless if we are comparing to BASE. */
- if (eb->use_text_base)
- return SVN_NO_ERROR;
-
- /* Determine if this is the anchor directory if the anchor is different
- to the target. When the target is a file, the anchor is the parent
- directory and if this is that directory the non-target entries must be
- skipped. */
- in_anchor_not_target = ((*path == '\0') && (*eb->target != '\0'));
-
/* Check for local property mods on this directory, if we haven't
already reported them and we aren't changelist-filted.
### it should be noted that we do not currently allow directories
@@ -566,7 +475,6 @@ walk_local_nodes_diff(struct edit_baton
### changelist check will always fail. */
if (svn_wc__internal_changelist_match(db, local_abspath,
eb->changelist_hash, scratch_pool)
- && (! in_anchor_not_target)
&& (!compared || ! apr_hash_get(compared, path, 0)))
{
svn_boolean_t modified;
@@ -590,7 +498,7 @@ walk_local_nodes_diff(struct edit_baton
}
}
- if (depth == svn_depth_empty && !in_anchor_not_target)
+ if (depth == svn_depth_empty)
return SVN_NO_ERROR;
iterpool = svn_pool_create(scratch_pool);
@@ -610,13 +518,6 @@ walk_local_nodes_diff(struct edit_baton
if (eb->cancel_func)
SVN_ERR(eb->cancel_func(eb->cancel_baton));
- /* In the anchor directory, if the anchor is not the target then all
- entries other than the target should not be diff'd. Running diff
- on one file in a directory should not diff other files in that
- directory. */
- if (in_anchor_not_target && strcmp(eb->target, name))
- continue;
-
child_abspath = svn_dirent_join(local_abspath, name, iterpool);
SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
@@ -654,8 +555,7 @@ walk_local_nodes_diff(struct edit_baton
/* Check the subdir if in the anchor (the subdir is the target), or
if recursive */
- if (in_anchor_not_target
- || (depth > svn_depth_files)
+ if ((depth > svn_depth_files)
|| (depth == svn_depth_unknown))
{
svn_depth_t depth_below_here = depth;
@@ -696,16 +596,16 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
const apr_array_header_t *changelists,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
- struct edit_baton *eb;
+ struct diff_baton eb = { 0 };
const char *target;
const char *anchor_abspath;
svn_wc__db_kind_t kind;
SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, target_abspath, FALSE,
- pool));
+ scratch_pool));
if (kind == svn_wc__db_kind_dir)
{
@@ -713,25 +613,38 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
target = "";
}
else
- svn_dirent_split(&anchor_abspath, &target, target_abspath, pool);
+ svn_dirent_split(&anchor_abspath, &target, target_abspath, scratch_pool);
+
+ eb.db = wc_ctx->db;
+ eb.callbacks = callbacks;
+ eb.callback_baton = callback_baton;
+ eb.ignore_ancestry = ignore_ancestry;
+ eb.show_copies_as_adds = show_copies_as_adds;
+ eb.use_git_diff_format = use_git_diff_format;
+ eb.empty_file = NULL;
+
+ if (changelists && changelists->nelts)
+ SVN_ERR(svn_hash_from_cstring_keys(&eb.changelist_hash, changelists,
+ scratch_pool));
- SVN_ERR(make_edit_baton(&eb,
- wc_ctx->db,
- anchor_abspath,
- target,
- callbacks, callback_baton,
- depth, ignore_ancestry, show_copies_as_adds,
- use_git_diff_format,
- FALSE, FALSE, changelists,
- cancel_func, cancel_baton,
- pool));
-
- SVN_ERR(walk_local_nodes_diff(eb,
- eb->anchor_abspath,
- "",
- depth,
- NULL,
- eb->pool));
+ if (kind == svn_wc__db_kind_dir)
+ SVN_ERR(walk_local_nodes_diff(&eb,
+ anchor_abspath,
+ "",
+ depth,
+ NULL,
+ scratch_pool));
+ else
+ {
+ svn_wc_status3_t *status;
+ SVN_ERR(svn_wc_status3(&status, wc_ctx, target_abspath,
+ scratch_pool, scratch_pool));
+
+ if (status->node_status == svn_wc_status_deleted
+ || status->text_status != svn_wc_status_normal
+ || status->prop_status == svn_wc_status_modified)
+ SVN_ERR(file_diff(&eb, target_abspath, target, scratch_pool));
+ }
return SVN_NO_ERROR;
}