~ubuntu-branches/ubuntu/trusty/subversion/trusty-proposed

« back to all changes in this revision

Viewing changes to subversion/libsvn_repos/rev_hunt.c

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft
  • Date: 2012-06-21 15:36:36 UTC
  • mfrom: (0.4.13 sid)
  • Revision ID: package-import@ubuntu.com-20120621153636-amqqmuidgwgxz1ly
Tags: 1.7.5-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Create pot file on build.
  - Build a python-subversion-dbg package.
  - Build-depend on python-dbg.
  - Build-depend on default-jre-headless/-jdk.
  - Do not apply java-build patch.
  - debian/rules: Manually create the doxygen output directory, otherwise
    we get weird build failures when running parallel builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *                their properties.
3
3
 *
4
4
 * ====================================================================
5
 
 * Copyright (c) 2000-2008 CollabNet.  All rights reserved.
6
 
 *
7
 
 * This software is licensed as described in the file COPYING, which
8
 
 * you should have received as part of this distribution.  The terms
9
 
 * are also available at http://subversion.tigris.org/license-1.html.
10
 
 * If newer versions of this license are posted there, you may use a
11
 
 * newer version instead, at your option.
12
 
 *
13
 
 * This software consists of voluntary contributions made by many
14
 
 * individuals.  For exact contribution history, see the revision
15
 
 * history and logs, available at http://subversion.tigris.org/.
 
5
 *    Licensed to the Apache Software Foundation (ASF) under one
 
6
 *    or more contributor license agreements.  See the NOTICE file
 
7
 *    distributed with this work for additional information
 
8
 *    regarding copyright ownership.  The ASF licenses this file
 
9
 *    to you under the Apache License, Version 2.0 (the
 
10
 *    "License"); you may not use this file except in compliance
 
11
 *    with the License.  You may obtain a copy of the License at
 
12
 *
 
13
 *      http://www.apache.org/licenses/LICENSE-2.0
 
14
 *
 
15
 *    Unless required by applicable law or agreed to in writing,
 
16
 *    software distributed under the License is distributed on an
 
17
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
18
 *    KIND, either express or implied.  See the License for the
 
19
 *    specific language governing permissions and limitations
 
20
 *    under the License.
16
21
 * ====================================================================
17
22
 */
18
23
 
28
33
#include "svn_string.h"
29
34
#include "svn_time.h"
30
35
#include "svn_sorts.h"
31
 
#include "svn_path.h"
32
36
#include "svn_props.h"
33
37
#include "svn_mergeinfo.h"
34
38
#include "repos.h"
 
39
#include "private/svn_fspath.h"
35
40
 
36
41
 
37
42
/* Note:  this binary search assumes that the datestamp properties on
272
277
            }
273
278
          else
274
279
            {
275
 
              return err;
 
280
              return svn_error_trace(err);
276
281
            }
277
282
        }
278
283
 
337
342
          svn_error_clear(err);
338
343
          return SVN_NO_ERROR;
339
344
        }
340
 
      return err;
 
345
      return svn_error_trace(err);
341
346
    }
342
347
 
343
348
  /* Ensure path was deleted at or before end revision. */
349
354
    }
350
355
  else if (err)
351
356
    {
352
 
      return err;
 
357
      return svn_error_trace(err);
353
358
    }
354
359
  else
355
360
    {
454
459
              mid_rev = (start + mid_rev) / 2;
455
460
            }
456
461
          else
457
 
            return err;
 
462
            return svn_error_trace(err);
458
463
        }
459
464
      else
460
465
        {
619
624
  SVN_ERR(svn_fs_copied_from(&copy_src_rev, &copy_src_path,
620
625
                             copy_root, copy_path, pool));
621
626
  if (! strcmp(copy_path, path) == 0)
622
 
    remainder = svn_path_is_child(copy_path, path, pool);
 
627
    remainder = svn_fspath__is_child(copy_path, path, pool);
623
628
  if (prev_path)
624
 
    *prev_path = svn_path_join(copy_src_path, remainder, pool);
 
629
    *prev_path = svn_fspath__join(copy_src_path, remainder, pool);
625
630
  if (appeared_rev)
626
631
    *appeared_rev = svn_fs_revision_root_revision(copy_root);
627
632
  if (prev_rev)
635
640
                               apr_hash_t **locations,
636
641
                               const char *fs_path,
637
642
                               svn_revnum_t peg_revision,
638
 
                               apr_array_header_t *location_revisions_orig,
 
643
                               const apr_array_header_t *location_revisions_orig,
639
644
                               svn_repos_authz_func_t authz_read_func,
640
645
                               void *authz_read_baton,
641
646
                               apr_pool_t *pool)
654
659
  /* Ensure that FS_PATH is absolute, because our path-math below will
655
660
     depend on that being the case.  */
656
661
  if (*fs_path != '/')
657
 
    fs_path = apr_pstrcat(pool, "/", fs_path, NULL);
 
662
    fs_path = apr_pstrcat(pool, "/", fs_path, (char *)NULL);
658
663
 
659
664
  /* Another sanity check. */
660
665
  if (authz_read_func)
726
731
                                  authz_read_baton, currpool));
727
732
          if (! readable)
728
733
            {
 
734
              svn_pool_destroy(lastpool);
 
735
              svn_pool_destroy(currpool);
 
736
 
729
737
              return SVN_NO_ERROR;
730
738
            }
731
739
        }
868
876
  /* Ensure that PATH is absolute, because our path-math will depend
869
877
     on that being the case.  */
870
878
  if (*path != '/')
871
 
    path = apr_pstrcat(pool, "/", path, NULL);
 
879
    path = apr_pstrcat(pool, "/", path, (char *)NULL);
872
880
 
873
881
  /* Auth check. */
874
882
  if (authz_read_func)
932
940
 
933
941
          /* authz_read_func requires path to have a leading slash. */
934
942
          const char *abs_path = apr_pstrcat(subpool, "/", segment->path,
935
 
                                             NULL);
 
943
                                             (char *)NULL);
936
944
 
937
945
          SVN_ERR(svn_fs_revision_root(&cur_rev_root, fs,
938
946
                                       segment->range_end, subpool));
1056
1064
                                                         APR_HASH_KEY_STRING);
1057
1065
      if (changed_path && changed_path->prop_mod)
1058
1066
        break;
1059
 
      if (svn_dirent_is_root(path, strlen(path)))
 
1067
      if (svn_fspath__is_root(path, strlen(path)))
1060
1068
        {
1061
1069
          svn_pool_destroy(subpool);
1062
1070
          *merged_mergeinfo = NULL;
1063
1071
          return SVN_NO_ERROR;
1064
1072
        }
1065
 
      path = svn_path_dirname(path, subpool);
 
1073
      path = svn_fspath__dirname(path, subpool);
1066
1074
    }
1067
1075
 
1068
1076
  /* First, find the mergeinfo difference for old_path_rev->revnum, and
1069
1077
     old_path_rev->revnum - 1. */
1070
 
  SVN_ERR(get_path_mergeinfo(&curr_mergeinfo, repos->fs, old_path_rev->path,
1071
 
                             old_path_rev->revnum, subpool));
 
1078
  err = get_path_mergeinfo(&curr_mergeinfo, repos->fs, old_path_rev->path,
 
1079
                           old_path_rev->revnum, subpool);
 
1080
  if (err)
 
1081
    {
 
1082
      if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
 
1083
        {
 
1084
          /* Issue #3896: If invalid mergeinfo is encountered the
 
1085
             best we can do is ignore it and act is if there are
 
1086
             no mergeinfo differences. */
 
1087
          svn_error_clear(err);
 
1088
          svn_pool_destroy(subpool);
 
1089
          *merged_mergeinfo = NULL;
 
1090
          return SVN_NO_ERROR;
 
1091
        }
 
1092
      else
 
1093
        {
 
1094
          return svn_error_trace(err);
 
1095
        }
 
1096
    }
 
1097
 
1072
1098
  err = get_path_mergeinfo(&prev_mergeinfo, repos->fs, old_path_rev->path,
1073
1099
                           old_path_rev->revnum - 1, subpool);
1074
 
  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
 
1100
  if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND
 
1101
              || err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR))
1075
1102
    {
1076
 
      /* If the path doesn't exist in the previous revision, assume no
1077
 
         merges */
 
1103
      /* If the path doesn't exist in the previous revision or it does exist
 
1104
         but has invalid mergeinfo (Issue #3896), assume no merges. */
1078
1105
      svn_error_clear(err);
1079
1106
      svn_pool_destroy(subpool);
1080
1107
      *merged_mergeinfo = NULL;
1086
1113
  /* Then calculate and merge the differences. */
1087
1114
  SVN_ERR(svn_mergeinfo_diff(&deleted, &changed, prev_mergeinfo, curr_mergeinfo,
1088
1115
                             FALSE, subpool));
1089
 
  if (apr_hash_count(deleted))
1090
 
    SVN_ERR(svn_mergeinfo_merge(changed, deleted, subpool));
 
1116
  SVN_ERR(svn_mergeinfo_merge(changed, deleted, subpool));
1091
1117
 
1092
1118
  /* Store the result. */
1093
1119
  if (apr_hash_count(changed))
1210
1236
static int
1211
1237
compare_path_revisions(const void *a, const void *b)
1212
1238
{
1213
 
  struct path_revision *a_pr = *(struct path_revision **)a;
1214
 
  struct path_revision *b_pr = *(struct path_revision **)b;
 
1239
  struct path_revision *a_pr = *(struct path_revision *const *)a;
 
1240
  struct path_revision *b_pr = *(struct path_revision *const *)b;
1215
1241
 
1216
1242
  if (a_pr->revnum == b_pr->revnum)
1217
1243
    return 0;
1221
1247
 
1222
1248
static svn_error_t *
1223
1249
find_merged_revisions(apr_array_header_t **merged_path_revisions_out,
1224
 
                      apr_array_header_t *mainline_path_revisions,
 
1250
                      svn_revnum_t start,
 
1251
                      const apr_array_header_t *mainline_path_revisions,
1225
1252
                      svn_repos_t *repos,
1226
1253
                      apr_hash_t *duplicate_path_revs,
1227
1254
                      svn_repos_authz_func_t authz_read_func,
1228
1255
                      void *authz_read_baton,
1229
1256
                      apr_pool_t *pool)
1230
1257
{
1231
 
  apr_array_header_t *old, *new;
 
1258
  const apr_array_header_t *old;
 
1259
  apr_array_header_t *new_merged_path_revs;
1232
1260
  apr_pool_t *iterpool, *last_pool;
1233
 
  apr_array_header_t *merged_path_revisions = apr_array_make(pool, 0,
1234
 
                                                sizeof(struct path_revision *));
 
1261
  apr_array_header_t *merged_path_revisions =
 
1262
    apr_array_make(pool, 0, sizeof(struct path_revision *));
1235
1263
 
1236
1264
  old = mainline_path_revisions;
1237
1265
  iterpool = svn_pool_create(pool);
1243
1271
      apr_pool_t *temp_pool;
1244
1272
 
1245
1273
      svn_pool_clear(iterpool);
1246
 
      new = apr_array_make(iterpool, 0, sizeof(struct path_revision *));
 
1274
      new_merged_path_revs = apr_array_make(iterpool, 0,
 
1275
                                            sizeof(struct path_revision *));
1247
1276
 
1248
1277
      /* Iterate over OLD, checking for non-empty mergeinfo.  If found, gather
1249
1278
         path_revisions for any merged revisions, and store those in NEW. */
1279
1308
                  svn_node_kind_t kind;
1280
1309
                  svn_fs_root_t *root;
1281
1310
 
 
1311
                  if (range->end < start)
 
1312
                    continue;
 
1313
 
1282
1314
                  svn_pool_clear(iterpool3);
 
1315
 
1283
1316
                  SVN_ERR(svn_fs_revision_root(&root, repos->fs, range->end,
1284
1317
                                               iterpool3));
1285
1318
                  SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool3));
1287
1320
                    continue;
1288
1321
 
1289
1322
                  /* Search and find revisions to add to the NEW list. */
1290
 
                  SVN_ERR(find_interesting_revisions(new, repos, path,
 
1323
                  SVN_ERR(find_interesting_revisions(new_merged_path_revs,
 
1324
                                                     repos, path,
1291
1325
                                                     range->start, range->end,
1292
1326
                                                     TRUE, TRUE,
1293
1327
                                                     duplicate_path_revs,
1302
1336
 
1303
1337
      /* Append the newly found path revisions with the old ones. */
1304
1338
      merged_path_revisions = apr_array_append(iterpool, merged_path_revisions,
1305
 
                                               new);
 
1339
                                               new_merged_path_revs);
1306
1340
 
1307
1341
      /* Swap data structures */
1308
 
      old = new;
 
1342
      old = new_merged_path_revs;
1309
1343
      temp_pool = last_pool;
1310
1344
      last_pool = iterpool;
1311
1345
      iterpool = temp_pool;
1312
1346
    }
1313
 
  while (new->nelts > 0);
 
1347
  while (new_merged_path_revs->nelts > 0);
1314
1348
 
1315
1349
  /* Sort MERGED_PATH_REVISIONS in increasing order by REVNUM. */
1316
1350
  qsort(merged_path_revisions->elts, merged_path_revisions->nelts,
1327
1361
 
1328
1362
struct send_baton
1329
1363
{
1330
 
  apr_pool_t *iter_pool;
 
1364
  apr_pool_t *iterpool;
1331
1365
  apr_pool_t *last_pool;
1332
1366
  apr_hash_t *last_props;
1333
1367
  const char *last_path;
1353
1387
  apr_pool_t *tmp_pool;  /* For swapping */
1354
1388
  svn_boolean_t contents_changed;
1355
1389
 
1356
 
  svn_pool_clear(sb->iter_pool);
 
1390
  svn_pool_clear(sb->iterpool);
1357
1391
 
1358
1392
  /* Get the revision properties. */
1359
1393
  SVN_ERR(svn_fs_revision_proplist(&rev_props, repos->fs,
1360
 
                                   path_rev->revnum, sb->iter_pool));
 
1394
                                   path_rev->revnum, sb->iterpool));
1361
1395
 
1362
1396
  /* Open the revision root. */
1363
1397
  SVN_ERR(svn_fs_revision_root(&root, repos->fs, path_rev->revnum,
1364
 
                               sb->iter_pool));
 
1398
                               sb->iterpool));
1365
1399
 
1366
1400
  /* Get the file's properties for this revision and compute the diffs. */
1367
1401
  SVN_ERR(svn_fs_node_proplist(&props, root, path_rev->path,
1368
 
                                   sb->iter_pool));
 
1402
                                   sb->iterpool));
1369
1403
  SVN_ERR(svn_prop_diffs(&prop_diffs, props, sb->last_props,
1370
 
                         sb->iter_pool));
 
1404
                         sb->iterpool));
1371
1405
 
1372
1406
  /* Check if the contents changed. */
1373
1407
  /* Special case: In the first revision, we always provide a delta. */
1374
1408
  if (sb->last_root)
1375
1409
    SVN_ERR(svn_fs_contents_changed(&contents_changed, sb->last_root,
1376
1410
                                    sb->last_path, root, path_rev->path,
1377
 
                                    sb->iter_pool));
 
1411
                                    sb->iterpool));
1378
1412
  else
1379
1413
    contents_changed = TRUE;
1380
1414
 
1383
1417
                  rev_props, path_rev->merged,
1384
1418
                  contents_changed ? &delta_handler : NULL,
1385
1419
                  contents_changed ? &delta_baton : NULL,
1386
 
                  prop_diffs, sb->iter_pool));
 
1420
                  prop_diffs, sb->iterpool));
1387
1421
 
1388
1422
  /* Compute and send delta if client asked for it.
1389
1423
     Note that this was initialized to NULL, so if !contents_changed,
1394
1428
      SVN_ERR(svn_fs_get_file_delta_stream(&delta_stream,
1395
1429
                                           sb->last_root, sb->last_path,
1396
1430
                                           root, path_rev->path,
1397
 
                                           sb->iter_pool));
 
1431
                                           sb->iterpool));
1398
1432
      /* And send. */
1399
1433
      SVN_ERR(svn_txdelta_send_txstream(delta_stream,
1400
1434
                                        delta_handler, delta_baton,
1401
 
                                        sb->iter_pool));
 
1435
                                        sb->iterpool));
1402
1436
    }
1403
1437
 
1404
1438
  /* Remember root, path and props for next iteration. */
1407
1441
  sb->last_props = props;
1408
1442
 
1409
1443
  /* Swap the pools. */
1410
 
  tmp_pool = sb->iter_pool;
1411
 
  sb->iter_pool = sb->last_pool;
 
1444
  tmp_pool = sb->iterpool;
 
1445
  sb->iterpool = sb->last_pool;
1412
1446
  sb->last_pool = tmp_pool;
1413
1447
 
1414
1448
  return SVN_NO_ERROR;
1460
1494
 
1461
1495
  /* If we are including merged revisions, go get those, too. */
1462
1496
  if (include_merged_revisions)
1463
 
    SVN_ERR(find_merged_revisions(&merged_path_revisions,
 
1497
    SVN_ERR(find_merged_revisions(&merged_path_revisions, start,
1464
1498
                                  mainline_path_revisions, repos,
1465
1499
                                  duplicate_path_revs, authz_read_func,
1466
1500
                                  authz_read_baton, pool));
1473
1507
 
1474
1508
  /* We switch betwwen two pools while looping, since we need information from
1475
1509
     the last iteration to be available. */
1476
 
  sb.iter_pool = svn_pool_create(pool);
 
1510
  sb.iterpool = svn_pool_create(pool);
1477
1511
  sb.last_pool = svn_pool_create(pool);
1478
1512
 
1479
1513
  /* We want the first txdelta to be against the empty file. */
1530
1564
    }
1531
1565
 
1532
1566
  svn_pool_destroy(sb.last_pool);
1533
 
  svn_pool_destroy(sb.iter_pool);
 
1567
  svn_pool_destroy(sb.iterpool);
1534
1568
 
1535
1569
  return SVN_NO_ERROR;
1536
1570
}