38
38
#include "svn_client.h"
39
39
#include "svn_hash.h"
41
#include "private/svn_client_private.h"
41
42
#include "private/svn_opt_private.h"
42
43
#include "private/svn_mergeinfo_private.h"
44
#include "private/svn_ra_private.h"
45
#include "private/svn_sorts_private.h"
43
46
#include "private/svn_wc_private.h"
44
#include "private/svn_ra_private.h"
45
47
#include "private/svn_fspath.h"
46
#include "private/svn_client_private.h"
47
48
#include "client.h"
48
49
#include "mergeinfo.h"
49
50
#include "svn_private_config.h"
223
224
SVN_ERR(svn_wc__node_get_base(NULL, &base_revision, NULL, NULL, NULL, NULL,
224
225
ctx->wc_ctx, local_abspath,
225
226
TRUE /* ignore_enoent */,
226
FALSE /* show_hidden */,
227
227
scratch_pool, scratch_pool));
229
229
iterpool = svn_pool_create(scratch_pool);
294
294
SVN_ERR(svn_wc__node_get_base(NULL, &parent_base_rev, NULL, NULL,
296
296
ctx->wc_ctx, local_abspath,
297
TRUE /* ignore_enoent */,
298
298
scratch_pool, scratch_pool));
300
300
/* ### This checks the WORKING changed_rev, so invalid on replacement
360
360
SVN_ERR(svn_mergeinfo_inheritable2(mergeinfo, *mergeinfo, NULL,
361
361
SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
362
362
TRUE, result_pool, scratch_pool));
363
svn_mergeinfo__remove_empty_rangelists(*mergeinfo, result_pool);
363
svn_mergeinfo__remove_empty_rangelists(*mergeinfo, scratch_pool);
430
430
hi = apr_hash_next(hi))
432
const char *node_abspath = svn__apr_hash_index_key(hi);
433
svn_string_t *propval = svn__apr_hash_index_val(hi);
432
const char *node_abspath = apr_hash_this_key(hi);
433
svn_string_t *propval = apr_hash_this_val(hi);
434
434
svn_mergeinfo_t subtree_mergeinfo;
435
435
const char *repos_relpath;
482
482
descendants. So if there is anything in the catalog it is the
483
483
mergeinfo for REL_PATH. */
484
484
*target_mergeinfo =
485
svn__apr_hash_index_val(apr_hash_first(pool, tgt_mergeinfo_cat));
485
apr_hash_this_val(apr_hash_first(pool, tgt_mergeinfo_cat));
582
582
so we can peek into our catalog, but it ought to be the only
583
583
thing in the catalog, so we'll just fetch the first hash item. */
584
584
*target_mergeinfo =
585
svn__apr_hash_index_val(apr_hash_first(pool, tgt_mergeinfo_cat));
585
apr_hash_this_val(apr_hash_first(pool, tgt_mergeinfo_cat));
623
623
a URL and without that we cannot get accurate mergeinfo for
624
624
TARGET_WCPATH. */
625
625
SVN_ERR(svn_wc__node_get_origin(NULL, &target_rev, &repos_relpath,
626
&repos_root, NULL, NULL,
626
&repos_root, NULL, NULL, NULL,
627
627
ctx->wc_ctx, local_abspath, FALSE,
628
628
scratch_pool, scratch_pool));
922
922
svn_mergeinfo_t target_mergeinfo;
923
923
svn_mergeinfo_t mergeinfo = NULL;
924
svn_boolean_t inherited;
925
const char *walk_path;
926
924
svn_error_t *err;
928
926
/* Get the TARGET_WCPATH's explicit mergeinfo. */
929
err = svn_client__get_wc_mergeinfo(&target_mergeinfo, &inherited,
930
svn_mergeinfo_inherited,
927
err = svn_client__get_wc_mergeinfo(&target_mergeinfo, NULL,
928
svn_mergeinfo_explicit,
934
931
ctx, pool, pool);
951
948
/* If TARGET_WCPATH has no explicit mergeinfo, there's nothing to
952
949
elide, we're done. */
953
if (inherited || target_mergeinfo == NULL)
950
if (target_mergeinfo == NULL)
954
951
return SVN_NO_ERROR;
956
953
/* Get TARGET_WCPATH's inherited mergeinfo from the WC. */
958
955
svn_mergeinfo_nearest_ancestor,
961
&walk_path, FALSE, ctx, pool, pool);
958
NULL, FALSE, ctx, pool, pool);
964
961
if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
1345
1342
hi = apr_hash_next(hi))
1348
const char *path = svn__apr_hash_index_key(hi);
1349
svn_log_changed_path2_t *change = svn__apr_hash_index_val(hi);
1345
const char *path = apr_hash_this_key(hi);
1346
svn_log_changed_path2_t *change = apr_hash_this_val(hi);
1350
1347
const char *target_fspath_affected;
1351
1348
svn_mergeinfo_t nearest_ancestor_mergeinfo;
1352
1349
svn_boolean_t found_this_revision = FALSE;
1431
1428
hi2 = apr_hash_next(hi2))
1433
const char *mergeinfo_path = svn__apr_hash_index_key(hi2);
1434
svn_rangelist_t *rangelist = svn__apr_hash_index_val(hi2);
1430
const char *mergeinfo_path = apr_hash_this_key(hi2);
1431
svn_rangelist_t *rangelist = apr_hash_this_val(hi2);
1436
1433
/* Does the mergeinfo for PATH reflect if
1437
1434
LOG_ENTRY->REVISION was previously merged
1608
1605
for (hi = apr_hash_first(scratch_pool, mergeinfo);
1609
1606
hi; hi = apr_hash_next(hi))
1611
const char *key = svn__apr_hash_index_key(hi);
1612
void *val = svn__apr_hash_index_val(hi);
1608
const char *key = apr_hash_this_key(hi);
1609
void *val = apr_hash_this_val(hi);
1614
1611
svn_hash_sets(full_path_mergeinfo,
1615
1612
svn_path_url_add_component2(repos_root_url, key + 1,
1928
1925
hi_catalog = apr_hash_next(hi_catalog))
1930
svn_mergeinfo_t subtree_mergeinfo = svn__apr_hash_index_val(hi_catalog);
1927
svn_mergeinfo_t subtree_mergeinfo = apr_hash_this_val(hi_catalog);
1931
1928
svn_mergeinfo_t subtree_history;
1932
1929
svn_mergeinfo_t subtree_source_history;
1933
1930
svn_mergeinfo_t subtree_inheritable_mergeinfo;
1934
1931
svn_mergeinfo_t subtree_noninheritable_mergeinfo;
1935
1932
svn_mergeinfo_t merged_noninheritable;
1936
1933
svn_mergeinfo_t merged;
1937
const char *subtree_path = svn__apr_hash_index_key(hi_catalog);
1934
const char *subtree_path = apr_hash_this_key(hi_catalog);
1938
1935
svn_boolean_t is_subtree = strcmp(subtree_path,
1939
1936
target_repos_relpath) != 0;
1940
1937
svn_pool_clear(iterpool);
2058
2055
svn_rangelist_t *deleted_rangelist;
2059
2056
svn_rangelist_t *added_rangelist;
2060
svn_rangelist_t *subtree_merged_rangelist =
2061
svn__apr_hash_index_val(hi);
2057
svn_rangelist_t *subtree_merged_rangelist = apr_hash_this_val(hi);
2063
2059
svn_pool_clear(iterpool);
2134
2130
svn_rangelist__initialize(youngest_range->end - 1,
2135
2131
youngest_range->end,
2136
2132
youngest_range->inheritable,
2139
2135
for (hi = apr_hash_first(scratch_pool, source_history);
2141
2137
hi = apr_hash_next(hi))
2143
const char *key = svn__apr_hash_index_key(hi);
2144
svn_rangelist_t *subtree_merged_rangelist =
2145
svn__apr_hash_index_val(hi);
2139
const char *key = apr_hash_this_key(hi);
2140
svn_rangelist_t *subtree_merged_rangelist = apr_hash_this_val(hi);
2146
2141
svn_rangelist_t *intersecting_rangelist;
2148
2143
svn_pool_clear(iterpool);
2230
2225
svn_mergeinfo_catalog_t mergeinfo_cat;
2231
2226
svn_mergeinfo_t mergeinfo;
2232
2227
apr_hash_index_t *hi;
2228
apr_pool_t *session_pool = svn_pool_create(pool);
2229
svn_ra_session_t *ra_session;
2234
2231
list = apr_array_make(pool, 1, sizeof(const char *));
2248
2245
1. The copyfrom source.
2249
2246
2. All remaining merge sources (unordered).
2248
SVN_ERR(svn_client__ra_session_from_path2(&ra_session, NULL, path_or_url,
2249
NULL, peg_revision, peg_revision,
2250
ctx, session_pool));
2252
/* ### TODO: Share ra_session batons to improve efficiency? */
2253
2252
SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
2254
peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
2253
peg_revision, FALSE, FALSE,
2254
ctx, ra_session, session_pool, session_pool));
2256
2256
if (mergeinfo_cat && apr_hash_count(mergeinfo_cat))
2258
2258
/* We asked only for the PATH_OR_URL's mergeinfo, not any of its
2259
2259
descendants. So if there is anything in the catalog it is the
2260
2260
mergeinfo for PATH_OR_URL. */
2261
mergeinfo = svn__apr_hash_index_val(apr_hash_first(pool, mergeinfo_cat));
2261
mergeinfo = apr_hash_this_val(apr_hash_first(session_pool,
2265
2266
mergeinfo = NULL;
2269
/* ### Should we only add the last source or all copy sources back to
2268
2271
SVN_ERR(svn_client__get_copy_source(©from_path, ©from_rev,
2269
path_or_url, peg_revision, ctx,
2272
path_or_url, peg_revision, ra_session,
2273
ctx, session_pool, session_pool));
2271
2274
if (copyfrom_path)
2273
2276
APR_ARRAY_PUSH(list, const char *) =
2279
for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
2282
for (hi = apr_hash_first(session_pool, mergeinfo);
2284
hi = apr_hash_next(hi))
2281
const char *rel_path = svn__apr_hash_index_key(hi);
2286
const char *rel_path = apr_hash_this_key(hi);
2283
2288
if (copyfrom_path == NULL || strcmp(rel_path, copyfrom_path) != 0)
2284
2289
APR_ARRAY_PUSH(list, const char *) = \