1080
1080
apr_hash_t *duplicate_path_revs,
1081
1081
svn_repos_authz_func_t authz_read_func,
1082
1082
void *authz_read_baton,
1083
apr_pool_t *result_pool,
1084
apr_pool_t *scratch_pool)
1085
apr_pool_t *iter_pool, *last_pool;
1086
apr_pool_t *iterpool, *last_pool;
1086
1087
svn_fs_history_t *history;
1087
1088
svn_fs_root_t *root;
1088
1089
svn_node_kind_t kind;
1090
1091
/* We switch between two pools while looping, since we need information from
1091
1092
the last iteration to be available. */
1092
iter_pool = svn_pool_create(pool);
1093
last_pool = svn_pool_create(pool);
1093
iterpool = svn_pool_create(result_pool);
1094
last_pool = svn_pool_create(result_pool);
1095
1096
/* The path had better be a file in this revision. */
1096
SVN_ERR(svn_fs_revision_root(&root, repos->fs, end, last_pool));
1097
SVN_ERR(svn_fs_check_path(&kind, root, path, pool));
1097
SVN_ERR(svn_fs_revision_root(&root, repos->fs, end, scratch_pool));
1098
SVN_ERR(svn_fs_check_path(&kind, root, path, scratch_pool));
1098
1099
if (kind != svn_node_file)
1099
1100
return svn_error_createf
1100
1101
(SVN_ERR_FS_NOT_FILE, NULL, _("'%s' is not a file in revision %ld"),
1103
1104
/* Open a history object. */
1104
SVN_ERR(svn_fs_node_history(&history, root, path, last_pool));
1105
SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
1108
struct path_revision *path_rev = apr_palloc(pool, sizeof(*path_rev));
1108
struct path_revision *path_rev;
1109
svn_revnum_t tmp_revnum;
1110
const char *tmp_path;
1109
1111
apr_pool_t *tmp_pool;
1111
svn_pool_clear(iter_pool);
1113
svn_pool_clear(iterpool);
1113
1115
/* Fetch the history object to walk through. */
1114
SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iter_pool));
1116
SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
1117
SVN_ERR(svn_fs_history_location(&path_rev->path, &path_rev->revnum,
1118
history, iter_pool));
1119
SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,
1120
history, iterpool));
1120
1122
/* Check to see if we already saw this path (and it's ancestors) */
1121
1123
if (include_merged_revisions
1122
&& is_path_in_hash(duplicate_path_revs, path_rev->path,
1123
path_rev->revnum, iter_pool))
1124
&& is_path_in_hash(duplicate_path_revs, tmp_path,
1125
tmp_revnum, iterpool))
1126
1128
/* Check authorization. */
1129
1131
svn_boolean_t readable;
1130
1132
svn_fs_root_t *tmp_root;
1132
SVN_ERR(svn_fs_revision_root(&tmp_root, repos->fs, path_rev->revnum,
1134
SVN_ERR(authz_read_func(&readable, tmp_root, path_rev->path,
1135
authz_read_baton, iter_pool));
1134
SVN_ERR(svn_fs_revision_root(&tmp_root, repos->fs, tmp_revnum,
1136
SVN_ERR(authz_read_func(&readable, tmp_root, tmp_path,
1137
authz_read_baton, iterpool));
1136
1138
if (! readable)
1140
path_rev->path = apr_pstrdup(pool, path_rev->path);
1142
/* We didn't break, so we must really want this path-rev. */
1143
path_rev = apr_palloc(result_pool, sizeof(*path_rev));
1144
path_rev->path = apr_pstrdup(result_pool, tmp_path);
1145
path_rev->revnum = tmp_revnum;
1141
1146
path_rev->merged = mark_as_merged;
1142
1147
APR_ARRAY_PUSH(path_revisions, struct path_revision *) = path_rev;
1144
1149
if (include_merged_revisions)
1145
1150
SVN_ERR(get_merged_mergeinfo(&path_rev->merged_mergeinfo, repos,
1151
path_rev, result_pool));
1148
1153
path_rev->merged_mergeinfo = NULL;
1151
1156
occurrences of it. We only care about this if including merged
1152
1157
revisions, 'cause that's the only time we can have duplicates. */
1153
1158
apr_hash_set(duplicate_path_revs,
1154
apr_psprintf(pool, "%s:%ld", path_rev->path,
1159
apr_psprintf(result_pool, "%s:%ld", path_rev->path,
1155
1160
path_rev->revnum),
1156
1161
APR_HASH_KEY_STRING, (void *)0xdeadbeef);
1192
1197
apr_pool_t *pool)
1194
1199
apr_array_header_t *old, *new;
1195
apr_pool_t *iter_pool, *last_pool;
1200
apr_pool_t *iterpool, *last_pool;
1196
1201
apr_array_header_t *merged_path_revisions = apr_array_make(pool, 0,
1197
1202
sizeof(struct path_revision *));
1199
1204
old = mainline_path_revisions;
1200
iter_pool = svn_pool_create(pool);
1205
iterpool = svn_pool_create(pool);
1201
1206
last_pool = svn_pool_create(pool);
1206
1211
apr_pool_t *temp_pool;
1208
svn_pool_clear(iter_pool);
1209
new = apr_array_make(iter_pool, 0, sizeof(struct path_revision *));
1213
svn_pool_clear(iterpool);
1214
new = apr_array_make(iterpool, 0, sizeof(struct path_revision *));
1211
1216
/* Iterate over OLD, checking for non-empty mergeinfo. If found, gather
1212
1217
path_revisions for any merged revisions, and store those in NEW. */
1213
1218
for (i = 0; i < old->nelts; i++)
1220
apr_pool_t *iterpool2;
1215
1221
apr_hash_index_t *hi;
1216
1222
struct path_revision *old_pr = APR_ARRAY_IDX(old, i,
1217
1223
struct path_revision *);
1218
1224
if (!old_pr->merged_mergeinfo)
1227
iterpool2 = svn_pool_create(iterpool);
1221
1229
/* Determine and trace the merge sources. */
1222
for (hi = apr_hash_first(iter_pool, old_pr->merged_mergeinfo); hi;
1230
for (hi = apr_hash_first(iterpool, old_pr->merged_mergeinfo); hi;
1223
1231
hi = apr_hash_next(hi))
1233
apr_pool_t *iterpool3;
1225
1234
apr_array_header_t *rangelist;
1226
1235
const char *path;
1238
svn_pool_clear(iterpool2);
1239
iterpool3 = svn_pool_create(iterpool2);
1229
1241
apr_hash_this(hi, (void *) &path, NULL, (void *) &rangelist);
1231
1243
for (j = 0; j < rangelist->nelts; j++)
1235
1247
svn_node_kind_t kind;
1236
1248
svn_fs_root_t *root;
1250
svn_pool_clear(iterpool3);
1238
1251
SVN_ERR(svn_fs_revision_root(&root, repos->fs, range->end,
1240
SVN_ERR(svn_fs_check_path(&kind, root, path, iter_pool));
1253
SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool3));
1241
1254
if (kind != svn_node_file)
1248
1261
duplicate_path_revs,
1249
1262
authz_read_func,
1250
authz_read_baton, pool));
1263
authz_read_baton, pool,
1266
svn_pool_destroy(iterpool3);
1268
svn_pool_destroy(iterpool2);
1255
1271
/* Append the newly found path revisions with the old ones. */
1256
merged_path_revisions = apr_array_append(iter_pool, merged_path_revisions,
1272
merged_path_revisions = apr_array_append(iterpool, merged_path_revisions,
1259
1275
/* Swap data structures */
1261
1277
temp_pool = last_pool;
1262
last_pool = iter_pool;
1263
iter_pool = temp_pool;
1278
last_pool = iterpool;
1279
iterpool = temp_pool;
1265
1281
while (new->nelts > 0);
1407
1423
SVN_ERR(find_interesting_revisions(mainline_path_revisions, repos, path,
1408
1424
start, end, include_merged_revisions,
1409
1425
FALSE, duplicate_path_revs,
1410
authz_read_func, authz_read_baton, pool));
1426
authz_read_func, authz_read_baton, pool,
1412
1429
/* If we are including merged revisions, go get those, too. */
1413
1430
if (include_merged_revisions)