summaryrefslogtreecommitdiff
path: root/subversion/libsvn_repos/rev_hunt.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_repos/rev_hunt.c')
-rw-r--r--subversion/libsvn_repos/rev_hunt.c289
1 files changed, 144 insertions, 145 deletions
diff --git a/subversion/libsvn_repos/rev_hunt.c b/subversion/libsvn_repos/rev_hunt.c
index 77b1f2a..d6cc495 100644
--- a/subversion/libsvn_repos/rev_hunt.c
+++ b/subversion/libsvn_repos/rev_hunt.c
@@ -38,6 +38,8 @@
#include "svn_mergeinfo.h"
#include "repos.h"
#include "private/svn_fspath.h"
+#include "private/svn_fs_private.h"
+#include "private/svn_sorts_private.h"
/* Note: this binary search assumes that the datestamp properties on
@@ -171,12 +173,8 @@ svn_repos_get_committed_info(svn_revnum_t *committed_rev,
SVN_ERR(svn_fs_revision_proplist(&revprops, fs, *committed_rev, pool));
/* Extract date and author from these revprops. */
- committed_date_s = apr_hash_get(revprops,
- SVN_PROP_REVISION_DATE,
- sizeof(SVN_PROP_REVISION_DATE)-1);
- last_author_s = apr_hash_get(revprops,
- SVN_PROP_REVISION_AUTHOR,
- sizeof(SVN_PROP_REVISION_AUTHOR)-1);
+ committed_date_s = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
+ last_author_s = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
*committed_date = committed_date_s ? committed_date_s->data : NULL;
*last_author = last_author_s ? last_author_s->data : NULL;
@@ -233,7 +231,7 @@ svn_repos_history2(svn_fs_t *fs,
return svn_error_create(SVN_ERR_AUTHZ_UNREADABLE, NULL, NULL);
}
- SVN_ERR(svn_fs_node_history(&history, root, path, oldpool));
+ SVN_ERR(svn_fs_node_history2(&history, root, path, oldpool, oldpool));
/* Now, we loop over the history items, calling svn_fs_history_prev(). */
do
@@ -244,7 +242,8 @@ svn_repos_history2(svn_fs_t *fs,
apr_pool_t *tmppool;
svn_error_t *err;
- SVN_ERR(svn_fs_history_prev(&history, history, cross_copies, newpool));
+ SVN_ERR(svn_fs_history_prev2(&history, history, cross_copies, newpool,
+ oldpool));
/* Only continue if there is further history to deal with. */
if (! history)
@@ -311,12 +310,11 @@ svn_repos_deleted_rev(svn_fs_t *fs,
svn_revnum_t *deleted,
apr_pool_t *pool)
{
- apr_pool_t *subpool;
- svn_fs_root_t *root, *copy_root;
- const char *copy_path;
+ apr_pool_t *iterpool;
+ svn_fs_root_t *start_root, *root;
svn_revnum_t mid_rev;
- const svn_fs_id_t *start_node_id, *curr_node_id;
- svn_error_t *err;
+ svn_node_kind_t kind;
+ svn_fs_node_relation_t node_relation;
/* Validate the revision range. */
if (! SVN_IS_VALID_REVNUM(start))
@@ -337,32 +335,19 @@ svn_repos_deleted_rev(svn_fs_t *fs,
}
/* Ensure path exists in fs at start revision. */
- SVN_ERR(svn_fs_revision_root(&root, fs, start, pool));
- err = svn_fs_node_id(&start_node_id, root, path, pool);
- if (err)
+ SVN_ERR(svn_fs_revision_root(&start_root, fs, start, pool));
+ SVN_ERR(svn_fs_check_path(&kind, start_root, path, pool));
+ if (kind == svn_node_none)
{
- if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
- {
- /* Path must exist in fs at start rev. */
- *deleted = SVN_INVALID_REVNUM;
- svn_error_clear(err);
- return SVN_NO_ERROR;
- }
- return svn_error_trace(err);
+ /* Path must exist in fs at start rev. */
+ *deleted = SVN_INVALID_REVNUM;
+ return SVN_NO_ERROR;
}
/* Ensure path was deleted at or before end revision. */
SVN_ERR(svn_fs_revision_root(&root, fs, end, pool));
- err = svn_fs_node_id(&curr_node_id, root, path, pool);
- if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
- {
- svn_error_clear(err);
- }
- else if (err)
- {
- return svn_error_trace(err);
- }
- else
+ SVN_ERR(svn_fs_check_path(&kind, root, path, pool));
+ if (kind != svn_node_none)
{
/* path exists in the end node and the end node is equivalent
or otherwise equivalent to the start node. This can mean
@@ -389,9 +374,12 @@ svn_repos_deleted_rev(svn_fs_t *fs,
5) The start node was deleted and replaced by a node which
it does not share any history with.
*/
- SVN_ERR(svn_fs_node_id(&curr_node_id, root, path, pool));
- if (svn_fs_compare_ids(start_node_id, curr_node_id) != -1)
+ SVN_ERR(svn_fs_node_relation(&node_relation, start_root, path,
+ root, path, pool));
+ if (node_relation != svn_fs_node_unrelated)
{
+ svn_fs_root_t *copy_root;
+ const char *copy_path;
SVN_ERR(svn_fs_closest_copy(&copy_root, &copy_path, root,
path, pool));
if (!copy_root ||
@@ -445,36 +433,33 @@ svn_repos_deleted_rev(svn_fs_t *fs,
*/
mid_rev = (start + end) / 2;
- subpool = svn_pool_create(pool);
+ iterpool = svn_pool_create(pool);
while (1)
{
- svn_pool_clear(subpool);
+ svn_pool_clear(iterpool);
/* Get revision root and node id for mid_rev at that revision. */
- SVN_ERR(svn_fs_revision_root(&root, fs, mid_rev, subpool));
- err = svn_fs_node_id(&curr_node_id, root, path, subpool);
-
- if (err)
+ SVN_ERR(svn_fs_revision_root(&root, fs, mid_rev, iterpool));
+ SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool));
+ if (kind == svn_node_none)
{
- if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
- {
- /* Case D: Look lower in the range. */
- svn_error_clear(err);
- end = mid_rev;
- mid_rev = (start + mid_rev) / 2;
- }
- else
- return svn_error_trace(err);
+ /* Case D: Look lower in the range. */
+ end = mid_rev;
+ mid_rev = (start + mid_rev) / 2;
}
else
{
+ svn_fs_root_t *copy_root;
+ const char *copy_path;
/* Determine the relationship between the start node
and the current node. */
- int cmp = svn_fs_compare_ids(start_node_id, curr_node_id);
- SVN_ERR(svn_fs_closest_copy(&copy_root, &copy_path, root,
- path, subpool));
- if (cmp == -1 ||
+ SVN_ERR(svn_fs_node_relation(&node_relation, start_root, path,
+ root, path, iterpool));
+ if (node_relation != svn_fs_node_unrelated)
+ SVN_ERR(svn_fs_closest_copy(&copy_root, &copy_path, root,
+ path, iterpool));
+ if (node_relation == svn_fs_node_unrelated ||
(copy_root &&
(svn_fs_revision_root_revision(copy_root) > start)))
{
@@ -497,7 +482,7 @@ svn_repos_deleted_rev(svn_fs_t *fs,
}
}
- svn_pool_destroy(subpool);
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
@@ -542,7 +527,7 @@ check_ancestry_of_peg_path(svn_boolean_t *is_ancestor,
SVN_ERR(svn_fs_revision_root(&root, fs, future_revision, pool));
- SVN_ERR(svn_fs_node_history(&history, root, fs_path, lastpool));
+ SVN_ERR(svn_fs_node_history2(&history, root, fs_path, lastpool, lastpool));
/* Since paths that are different according to strcmp may still be
equivalent (due to number of consecutive slashes and the fact that
@@ -555,7 +540,8 @@ check_ancestry_of_peg_path(svn_boolean_t *is_ancestor,
{
apr_pool_t *tmppool;
- SVN_ERR(svn_fs_history_prev(&history, history, TRUE, currpool));
+ SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, currpool,
+ lastpool));
if (!history)
break;
@@ -657,14 +643,13 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
svn_revnum_t revision;
svn_boolean_t is_ancestor;
apr_pool_t *lastpool, *currpool;
- const svn_fs_id_t *id;
SVN_ERR_ASSERT(location_revisions_orig->elt_size == sizeof(svn_revnum_t));
/* Ensure that FS_PATH is absolute, because our path-math below will
depend on that being the case. */
if (*fs_path != '/')
- fs_path = apr_pstrcat(pool, "/", fs_path, (char *)NULL);
+ fs_path = apr_pstrcat(pool, "/", fs_path, SVN_VA_NULL);
/* Another sanity check. */
if (authz_read_func)
@@ -726,23 +711,6 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
if (! prev_path)
break;
- if (authz_read_func)
- {
- svn_boolean_t readable;
- svn_fs_root_t *tmp_root;
-
- SVN_ERR(svn_fs_revision_root(&tmp_root, fs, revision, currpool));
- SVN_ERR(authz_read_func(&readable, tmp_root, path,
- authz_read_baton, currpool));
- if (! readable)
- {
- svn_pool_destroy(lastpool);
- svn_pool_destroy(currpool);
-
- return SVN_NO_ERROR;
- }
- }
-
/* Assign the current path to all younger revisions until we reach
the copy target rev. */
while ((revision_ptr < revision_ptr_end)
@@ -765,6 +733,20 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
path = prev_path;
revision = prev_rev;
+ if (authz_read_func)
+ {
+ svn_boolean_t readable;
+ SVN_ERR(svn_fs_revision_root(&root, fs, revision, currpool));
+ SVN_ERR(authz_read_func(&readable, root, path,
+ authz_read_baton, currpool));
+ if (!readable)
+ {
+ svn_pool_destroy(lastpool);
+ svn_pool_destroy(currpool);
+ return SVN_NO_ERROR;
+ }
+ }
+
/* Clear last pool and switch. */
svn_pool_clear(lastpool);
tmppool = lastpool;
@@ -777,20 +759,22 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
the node existing at the same path. We will look up path@lrev
for each remaining location-revision and make sure it is related
to path@revision. */
- SVN_ERR(svn_fs_revision_root(&root, fs, revision, currpool));
- SVN_ERR(svn_fs_node_id(&id, root, path, pool));
+ SVN_ERR(svn_fs_revision_root(&root, fs, revision, lastpool));
while (revision_ptr < revision_ptr_end)
{
svn_node_kind_t kind;
- const svn_fs_id_t *lrev_id;
+ svn_fs_node_relation_t node_relation;
+ svn_fs_root_t *cur_rev_root;
svn_pool_clear(currpool);
- SVN_ERR(svn_fs_revision_root(&root, fs, *revision_ptr, currpool));
- SVN_ERR(svn_fs_check_path(&kind, root, path, currpool));
+ SVN_ERR(svn_fs_revision_root(&cur_rev_root, fs, *revision_ptr,
+ currpool));
+ SVN_ERR(svn_fs_check_path(&kind, cur_rev_root, path, currpool));
if (kind == svn_node_none)
break;
- SVN_ERR(svn_fs_node_id(&lrev_id, root, path, currpool));
- if (! svn_fs_check_related(id, lrev_id))
+ SVN_ERR(svn_fs_node_relation(&node_relation, root, path,
+ cur_rev_root, path, currpool));
+ if (node_relation == svn_fs_node_unrelated)
break;
/* The node exists at the same path; record that and advance. */
@@ -881,7 +865,7 @@ svn_repos_node_location_segments(svn_repos_t *repos,
/* Ensure that PATH is absolute, because our path-math will depend
on that being the case. */
if (*path != '/')
- path = apr_pstrcat(pool, "/", path, (char *)NULL);
+ path = apr_pstrcat(pool, "/", path, SVN_VA_NULL);
/* Auth check. */
if (authz_read_func)
@@ -945,7 +929,7 @@ svn_repos_node_location_segments(svn_repos_t *repos,
/* authz_read_func requires path to have a leading slash. */
const char *abs_path = apr_pstrcat(subpool, "/", segment->path,
- (char *)NULL);
+ SVN_VA_NULL);
SVN_ERR(svn_fs_revision_root(&cur_rev_root, fs,
segment->range_end, subpool));
@@ -982,37 +966,6 @@ svn_repos_node_location_segments(svn_repos_t *repos,
return SVN_NO_ERROR;
}
-/* Get the mergeinfo for PATH in REPOS at REVNUM and store it in MERGEINFO. */
-static svn_error_t *
-get_path_mergeinfo(apr_hash_t **mergeinfo,
- svn_fs_t *fs,
- const char *path,
- svn_revnum_t revnum,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_mergeinfo_catalog_t tmp_catalog;
- svn_fs_root_t *root;
- apr_array_header_t *paths = apr_array_make(scratch_pool, 1,
- sizeof(const char *));
-
- APR_ARRAY_PUSH(paths, const char *) = path;
-
- SVN_ERR(svn_fs_revision_root(&root, fs, revnum, scratch_pool));
- /* We do not need to call svn_repos_fs_get_mergeinfo() (which performs authz)
- because we will filter out unreadable revisions in
- find_interesting_revision(), above */
- SVN_ERR(svn_fs_get_mergeinfo2(&tmp_catalog, root, paths,
- svn_mergeinfo_inherited, FALSE, TRUE,
- result_pool, scratch_pool));
-
- *mergeinfo = svn_hash_gets(tmp_catalog, path);
- if (!*mergeinfo)
- *mergeinfo = apr_hash_make(result_pool);
-
- return SVN_NO_ERROR;
-}
-
static APR_INLINE svn_boolean_t
is_path_in_hash(apr_hash_t *duplicate_path_revs,
const char *path,
@@ -1031,7 +984,8 @@ struct path_revision
svn_revnum_t revnum;
const char *path;
- /* Does this path_rev have merges to also be included? */
+ /* Does this path_rev have merges to also be included? If so, this is
+ the union of both additions and (negated) deletions of mergeinfo. */
apr_hash_t *merged_mergeinfo;
/* Is this a merged revision? */
@@ -1040,6 +994,7 @@ struct path_revision
/* Check for merges in OLD_PATH_REV->PATH at OLD_PATH_REV->REVNUM. Store
the mergeinfo difference in *MERGED_MERGEINFO, allocated in POOL. The
+ difference is the union of both additions and (negated) deletions. The
returned *MERGED_MERGEINFO will be NULL if there are no changes. */
static svn_error_t *
get_merged_mergeinfo(apr_hash_t **merged_mergeinfo,
@@ -1050,7 +1005,7 @@ get_merged_mergeinfo(apr_hash_t **merged_mergeinfo,
{
apr_hash_t *curr_mergeinfo, *prev_mergeinfo, *deleted, *changed;
svn_error_t *err;
- svn_fs_root_t *root;
+ svn_fs_root_t *root, *prev_root;
apr_hash_t *changed_paths;
const char *path = old_path_rev->path;
@@ -1062,7 +1017,8 @@ get_merged_mergeinfo(apr_hash_t **merged_mergeinfo,
while (1)
{
svn_fs_path_change2_t *changed_path = svn_hash_gets(changed_paths, path);
- if (changed_path && changed_path->prop_mod)
+ if (changed_path && changed_path->prop_mod
+ && changed_path->mergeinfo_mod != svn_tristate_false)
break;
if (svn_fspath__is_root(path, strlen(path)))
{
@@ -1074,9 +1030,13 @@ get_merged_mergeinfo(apr_hash_t **merged_mergeinfo,
/* First, find the mergeinfo difference for old_path_rev->revnum, and
old_path_rev->revnum - 1. */
- err = get_path_mergeinfo(&curr_mergeinfo, repos->fs, old_path_rev->path,
- old_path_rev->revnum, scratch_pool,
- scratch_pool);
+ /* We do not need to call svn_repos_fs_get_mergeinfo() (which performs authz)
+ because we will filter out unreadable revisions in
+ find_interesting_revision() */
+ err = svn_fs__get_mergeinfo_for_path(&curr_mergeinfo,
+ root, old_path_rev->path,
+ svn_mergeinfo_inherited, TRUE,
+ scratch_pool, scratch_pool);
if (err)
{
if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
@@ -1094,9 +1054,12 @@ get_merged_mergeinfo(apr_hash_t **merged_mergeinfo,
}
}
- err = get_path_mergeinfo(&prev_mergeinfo, repos->fs, old_path_rev->path,
- old_path_rev->revnum - 1, scratch_pool,
- scratch_pool);
+ SVN_ERR(svn_fs_revision_root(&prev_root, repos->fs, old_path_rev->revnum - 1,
+ scratch_pool));
+ err = svn_fs__get_mergeinfo_for_path(&prev_mergeinfo,
+ prev_root, old_path_rev->path,
+ svn_mergeinfo_inherited, TRUE,
+ scratch_pool, scratch_pool);
if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND
|| err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR))
{
@@ -1109,7 +1072,8 @@ get_merged_mergeinfo(apr_hash_t **merged_mergeinfo,
else
SVN_ERR(err);
- /* Then calculate and merge the differences. */
+ /* Then calculate and merge the differences, combining additions and
+ (negated) deletions as all positive changes in CHANGES. */
SVN_ERR(svn_mergeinfo_diff2(&deleted, &changed, prev_mergeinfo,
curr_mergeinfo, FALSE, result_pool,
scratch_pool));
@@ -1157,7 +1121,8 @@ find_interesting_revisions(apr_array_header_t *path_revisions,
path, end);
/* Open a history object. */
- SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
+ SVN_ERR(svn_fs_node_history2(&history, root, path, scratch_pool,
+ scratch_pool));
while (1)
{
struct path_revision *path_rev;
@@ -1168,7 +1133,8 @@ find_interesting_revisions(apr_array_header_t *path_revisions,
svn_pool_clear(iterpool);
/* Fetch the history object to walk through. */
- SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
+ SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, iterpool,
+ iterpool));
if (!history)
break;
SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,
@@ -1290,16 +1256,14 @@ find_merged_revisions(apr_array_header_t **merged_path_revisions_out,
for (hi = apr_hash_first(iterpool, old_pr->merged_mergeinfo); hi;
hi = apr_hash_next(hi))
{
+ const char *path = apr_hash_this_key(hi);
+ svn_rangelist_t *rangelist = apr_hash_this_val(hi);
apr_pool_t *iterpool3;
- svn_rangelist_t *rangelist;
- const char *path;
int j;
svn_pool_clear(iterpool2);
iterpool3 = svn_pool_create(iterpool2);
- apr_hash_this(hi, (void *) &path, NULL, (void *) &rangelist);
-
for (j = 0; j < rangelist->nelts; j++)
{
svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, j,
@@ -1346,8 +1310,7 @@ find_merged_revisions(apr_array_header_t **merged_path_revisions_out,
while (new_merged_path_revs->nelts > 0);
/* Sort MERGED_PATH_REVISIONS in increasing order by REVNUM. */
- qsort(merged_path_revisions->elts, merged_path_revisions->nelts,
- sizeof(struct path_revision *), compare_path_revisions);
+ svn_sort__array(merged_path_revisions, compare_path_revisions);
/* Copy to the output array. */
*merged_path_revisions_out = apr_array_copy(result_pool,
@@ -1366,6 +1329,7 @@ struct send_baton
apr_hash_t *last_props;
const char *last_path;
svn_fs_root_t *last_root;
+ svn_boolean_t include_merged_revisions;
};
/* Send PATH_REV to HANDLER and HANDLER_BATON, using information provided by
@@ -1403,14 +1367,32 @@ send_path_revision(struct path_revision *path_rev,
SVN_ERR(svn_prop_diffs(&prop_diffs, props, sb->last_props,
sb->iterpool));
- /* Check if the contents changed. */
- /* Special case: In the first revision, we always provide a delta. */
- if (sb->last_root)
- SVN_ERR(svn_fs_contents_changed(&contents_changed, sb->last_root,
- sb->last_path, root, path_rev->path,
- sb->iterpool));
+ /* Check if the contents *may* have changed. */
+ if (! sb->last_root)
+ {
+ /* Special case: In the first revision, we always provide a delta. */
+ contents_changed = TRUE;
+ }
+ else if (sb->include_merged_revisions
+ && strcmp(sb->last_path, path_rev->path))
+ {
+ /* ### This is a HACK!!!
+ * Blame -g, in older clients anyways, relies on getting a notification
+ * whenever the path changes - even if there was no content change.
+ *
+ * TODO: A future release should take an extra parameter and depending
+ * on that either always send a text delta or only send it if there
+ * is a difference. */
+ contents_changed = TRUE;
+ }
else
- contents_changed = TRUE;
+ {
+ /* Did the file contents actually change?
+ * It could e.g. be a property-only change. */
+ SVN_ERR(svn_fs_contents_different(&contents_changed, sb->last_root,
+ sb->last_path, root, path_rev->path,
+ sb->iterpool));
+ }
/* We have all we need, give to the handler. */
SVN_ERR(handler(handler_baton, path_rev->path, path_rev->revnum,
@@ -1422,7 +1404,7 @@ send_path_revision(struct path_revision *path_rev,
/* Compute and send delta if client asked for it.
Note that this was initialized to NULL, so if !contents_changed,
no deltas will be computed. */
- if (delta_handler)
+ if (delta_handler && delta_handler != svn_delta_noop_window_handler)
{
/* Get the content delta. */
SVN_ERR(svn_fs_get_file_delta_stream(&delta_stream,
@@ -1479,6 +1461,7 @@ get_file_revs_backwards(svn_repos_t *repos,
last_pool = svn_pool_create(scratch_pool);
sb.iterpool = svn_pool_create(scratch_pool);
sb.last_pool = svn_pool_create(scratch_pool);
+ sb.include_merged_revisions = FALSE;
/* We want the first txdelta to be against the empty file. */
sb.last_root = NULL;
@@ -1496,7 +1479,7 @@ get_file_revs_backwards(svn_repos_t *repos,
path, end);
/* Open a history object. */
- SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
+ SVN_ERR(svn_fs_node_history2(&history, root, path, scratch_pool, iterpool));
while (1)
{
struct path_revision *path_rev;
@@ -1506,7 +1489,8 @@ get_file_revs_backwards(svn_repos_t *repos,
svn_pool_clear(iterpool);
/* Fetch the history object to walk through. */
- SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
+ SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, iterpool,
+ iterpool));
if (!history)
break;
SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,
@@ -1594,6 +1578,18 @@ svn_repos_get_file_revs2(svn_repos_t *repos,
struct send_baton sb;
int mainline_pos, merged_pos;
+ if (!SVN_IS_VALID_REVNUM(start)
+ || !SVN_IS_VALID_REVNUM(end))
+ {
+ svn_revnum_t youngest_rev;
+ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, repos->fs, scratch_pool));
+
+ if (!SVN_IS_VALID_REVNUM(start))
+ start = youngest_rev;
+ if (!SVN_IS_VALID_REVNUM(end))
+ end = youngest_rev;
+ }
+
if (end < start)
{
if (include_merged_revisions)
@@ -1621,6 +1617,9 @@ svn_repos_get_file_revs2(svn_repos_t *repos,
/* Create an empty hash table for the first property diff. */
sb.last_props = apr_hash_make(sb.last_pool);
+ /* Inform send_path_revision() whether workarounds / special behavior
+ * may be needed. */
+ sb.include_merged_revisions = include_merged_revisions;
/* Get the revisions we are interested in. */
duplicate_path_revs = apr_hash_make(scratch_pool);