~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/libsvn_wc/entries.c

  • Committer: Package Import Robot
  • Author(s): James McCoy, Peter Samuelson, James McCoy
  • Date: 2014-01-12 19:48:33 UTC
  • mfrom: (0.2.10)
  • Revision ID: package-import@ubuntu.com-20140112194833-w3axfwksn296jn5x
Tags: 1.8.5-1
[ Peter Samuelson ]
* New upstream release.  (Closes: #725787) Rediff patches:
  - Remove apr-abi1 (applied upstream), rename apr-abi2 to apr-abi
  - Remove loosen-sqlite-version-check (shouldn't be needed)
  - Remove java-osgi-metadata (applied upstream)
  - svnmucc prompts for a changelog if none is provided. (Closes: #507430)
  - Remove fix-bdb-version-detection, upstream uses "apu-config --dbm-libs"
  - Remove ruby-test-wc (applied upstream)
  - Fix “svn diff -r N file” when file has svn:mime-type set.
    (Closes: #734163)
  - Support specifying an encoding for mod_dav_svn's environment in which
    hooks are run.  (Closes: #601544)
  - Fix ordering of “svnadmin dump” paths with certain APR versions.
    (Closes: #687291)
  - Provide a better error message when authentication fails with an
    svn+ssh:// URL.  (Closes: #273874)
  - Updated Polish translations.  (Closes: #690815)

[ James McCoy ]
* Remove all traces of libneon, replaced by libserf.
* patches/sqlite_3.8.x_workaround: Upstream fix for wc-queries-test test
  failurse.
* Run configure with --with-apache-libexecdir, which allows removing part of
  patches/rpath.
* Re-enable auth-test as upstream has fixed the problem of picking up
  libraries from the environment rather than the build tree.
  (Closes: #654172)
* Point LD_LIBRARY_PATH at the built auth libraries when running the svn
  command during the build.  (Closes: #678224)
* Add a NEWS entry describing how to configure mod_dav_svn to understand
  UTF-8.  (Closes: #566148)
* Remove ancient transitional package, libsvn-ruby.
* Enable compatibility with Sqlite3 versions back to Wheezy.
* Enable hardening flags.  (Closes: #734918)
* patches/build-fixes: Enable verbose build logs.
* Build against the default ruby version.  (Closes: #722393)

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "svn_path.h"
35
35
#include "svn_ctype.h"
36
36
#include "svn_string.h"
 
37
#include "svn_hash.h"
37
38
 
38
39
#include "wc.h"
39
40
#include "adm_files.h"
 
41
#include "conflicts.h"
40
42
#include "entries.h"
41
43
#include "lock.h"
42
44
#include "tree_conflicts.h"
55
57
typedef struct db_node_t {
56
58
  apr_int64_t wc_id;
57
59
  const char *local_relpath;
58
 
  apr_int64_t op_depth;
 
60
  int op_depth;
59
61
  apr_int64_t repos_id;
60
62
  const char *repos_relpath;
61
63
  const char *parent_relpath;
62
64
  svn_wc__db_status_t presence;
63
65
  svn_revnum_t revision;
64
 
  svn_node_kind_t kind;  /* ### should switch to svn_wc__db_kind_t */
 
66
  svn_node_kind_t kind;
65
67
  svn_checksum_t *checksum;
66
 
  svn_filesize_t translated_size;
 
68
  svn_filesize_t recorded_size;
67
69
  svn_revnum_t changed_rev;
68
70
  apr_time_t changed_date;
69
71
  const char *changed_author;
70
72
  svn_depth_t depth;
71
 
  apr_time_t last_mod_time;
 
73
  apr_time_t recorded_time;
72
74
  apr_hash_t *properties;
73
75
  svn_boolean_t file_external;
 
76
  apr_array_header_t *inherited_props;
74
77
} db_node_t;
75
78
 
76
79
typedef struct db_actual_node_t {
148
151
                    apr_pool_t *scratch_pool)
149
152
{
150
153
  svn_wc__db_status_t status;
151
 
  svn_wc__db_kind_t kind;
 
154
  svn_node_kind_t kind;
152
155
  const char *repos_relpath;
153
156
  svn_revnum_t peg_revision;
154
157
  svn_revnum_t revision;
169
172
    }
170
173
 
171
174
  if (status == svn_wc__db_status_normal
172
 
      && kind == svn_wc__db_kind_file)
 
175
      && kind == svn_node_file)
173
176
    {
174
177
      entry->file_external_path = repos_relpath;
175
178
      if (SVN_IS_VALID_REVNUM(peg_revision))
204
207
*/
205
208
static svn_error_t *
206
209
get_info_for_deleted(svn_wc_entry_t *entry,
207
 
                     svn_wc__db_kind_t *kind,
 
210
                     svn_node_kind_t *kind,
208
211
                     const char **repos_relpath,
209
212
                     const svn_checksum_t **checksum,
 
213
                     svn_wc__db_lock_t **lock,
210
214
                     svn_wc__db_t *db,
211
215
                     const char *entry_abspath,
212
216
                     const svn_wc_entry_t *parent_entry,
229
233
                                       &entry->depth,
230
234
                                       checksum,
231
235
                                       NULL,
232
 
                                       NULL /* lock */,
233
 
                                       &entry->has_props,
 
236
                                       lock,
 
237
                                       &entry->has_props, NULL,
234
238
                                       NULL,
235
239
                                       db,
236
240
                                       entry_abspath,
237
241
                                       result_pool,
238
242
                                       scratch_pool));
239
 
 
240
 
      if (*repos_relpath == NULL)
241
 
        SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath,
242
 
                                           &entry->repos,
243
 
                                           &entry->uuid,
244
 
                                           db,
245
 
                                           entry_abspath,
246
 
                                           result_pool,
247
 
                                           scratch_pool));
248
243
    }
249
244
  else
250
245
    {
263
258
                                            &entry->depth,
264
259
                                            checksum,
265
260
                                            NULL,
266
 
                                            &entry->has_props,
 
261
                                            &entry->has_props, NULL,
267
262
                                            db,
268
263
                                            entry_abspath,
269
264
                                            result_pool,
272
267
 
273
268
     SVN_ERR(svn_wc__db_scan_deletion(NULL,
274
269
                                      NULL,
275
 
                                      &work_del_abspath,
 
270
                                      &work_del_abspath, NULL,
276
271
                                      db, entry_abspath,
277
272
                                      scratch_pool, scratch_pool));
278
273
 
304
299
          svn_wc__db_status_t status;
305
300
          SVN_ERR(svn_wc__db_base_get_info(&status, NULL, &entry->revision,
306
301
                                           NULL, NULL, NULL, NULL, NULL, NULL,
307
 
                                           NULL, NULL, NULL, NULL, NULL, NULL,
 
302
                                           NULL, NULL, NULL, lock, NULL, NULL,
 
303
                                           NULL,
308
304
                                           db, entry_abspath,
309
305
                                           result_pool, scratch_pool));
310
306
 
384
380
               apr_pool_t *result_pool,
385
381
               apr_pool_t *scratch_pool)
386
382
{
387
 
  svn_wc__db_kind_t kind;
 
383
  svn_node_kind_t kind;
388
384
  svn_wc__db_status_t status;
389
385
  svn_wc__db_lock_t *lock;
390
386
  const char *repos_relpath;
461
457
          child_abspath = svn_dirent_join(dir_abspath, child_name,
462
458
                                          scratch_pool);
463
459
 
464
 
          SVN_ERR(svn_wc__db_read_conflicts(&child_conflicts,
465
 
                                            db, child_abspath,
466
 
                                            scratch_pool, scratch_pool));
 
460
          SVN_ERR(svn_wc__read_conflicts(&child_conflicts,
 
461
                                         db, child_abspath,
 
462
                                         FALSE /* create tempfiles */,
 
463
                                         scratch_pool, scratch_pool));
467
464
 
468
465
          for (j = 0; j < child_conflicts->nelts; j++)
469
466
            {
475
472
                {
476
473
                  if (!tree_conflicts)
477
474
                    tree_conflicts = apr_hash_make(scratch_pool);
478
 
                  apr_hash_set(tree_conflicts, child_name,
479
 
                               APR_HASH_KEY_STRING, conflict);
 
475
                  svn_hash_sets(tree_conflicts, child_name, conflict);
480
476
                }
481
477
            }
482
478
        }
525
521
        {
526
522
          const char *work_del_abspath;
527
523
          SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
528
 
                                           &work_del_abspath,
 
524
                                           &work_del_abspath, NULL,
529
525
                                           db, entry_abspath,
530
526
                                           scratch_pool, scratch_pool));
531
527
 
572
568
                                           NULL, NULL, NULL,
573
569
                                           NULL, NULL, NULL,
574
570
                                           NULL, NULL, NULL,
575
 
                                           NULL, NULL, NULL,
 
571
                                           NULL, NULL, NULL, NULL,
576
572
                                           db, entry_abspath,
577
573
                                           scratch_pool,
578
574
                                           scratch_pool));
637
633
          /* ### scan_addition may need to be updated to avoid returning
638
634
             ### status_copied in this case.  */
639
635
        }
640
 
      else if (work_status == svn_wc__db_status_copied)
 
636
      /* For backwards-compatiblity purposes we treat moves just like
 
637
       * regular copies. */
 
638
      else if (work_status == svn_wc__db_status_copied ||
 
639
               work_status == svn_wc__db_status_moved_here)
641
640
        {
642
641
          entry->copied = TRUE;
643
642
 
662
661
          svn_boolean_t is_copied_child;
663
662
          svn_boolean_t is_mixed_rev = FALSE;
664
663
 
665
 
          SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied);
 
664
          SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied ||
 
665
                         work_status == svn_wc__db_status_moved_here);
666
666
 
667
667
          /* If this node inherits copyfrom information from an
668
668
             ancestor node, then it must be a copied child.  */
713
713
                                             &parent_repos_relpath,
714
714
                                             &parent_root_url,
715
715
                                             NULL, NULL,
716
 
                                             db,
717
 
                                             parent_abspath,
 
716
                                             db, parent_abspath,
718
717
                                             scratch_pool,
719
718
                                             scratch_pool);
720
719
              if (err)
826
825
                                   &kind,
827
826
                                   &repos_relpath,
828
827
                                   &checksum,
 
828
                                   &lock,
829
829
                                   db, entry_abspath,
830
830
                                   parent_entry,
831
831
                                   have_base, have_more_work,
836
836
  if (entry->depth == svn_depth_unknown)
837
837
    entry->depth = svn_depth_infinity;
838
838
 
839
 
  if (kind == svn_wc__db_kind_dir)
 
839
  if (kind == svn_node_dir)
840
840
    entry->kind = svn_node_dir;
841
 
  else if (kind == svn_wc__db_kind_file)
 
841
  else if (kind == svn_node_file)
842
842
    entry->kind = svn_node_file;
843
 
  else if (kind == svn_wc__db_kind_symlink)
 
843
  else if (kind == svn_node_symlink)
844
844
    entry->kind = svn_node_file;  /* ### no symlink kind */
845
845
  else
846
846
    entry->kind = svn_node_unknown;
878
878
 
879
879
  if (conflicted)
880
880
    {
881
 
      const apr_array_header_t *conflicts;
882
 
      int j;
883
 
      SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, entry_abspath,
884
 
                                        scratch_pool, scratch_pool));
885
 
 
886
 
      for (j = 0; j < conflicts->nelts; j++)
887
 
        {
888
 
          const svn_wc_conflict_description2_t *cd;
889
 
          cd = APR_ARRAY_IDX(conflicts, j,
890
 
                             const svn_wc_conflict_description2_t *);
891
 
 
892
 
          switch (cd->kind)
893
 
            {
894
 
            case svn_wc_conflict_kind_text:
895
 
              if (cd->base_abspath)
896
 
                entry->conflict_old = svn_dirent_basename(cd->base_abspath,
897
 
                                                          result_pool);
898
 
              if (cd->their_abspath)
899
 
                entry->conflict_new = svn_dirent_basename(cd->their_abspath,
900
 
                                                          result_pool);
901
 
              if (cd->my_abspath)
902
 
                entry->conflict_wrk = svn_dirent_basename(cd->my_abspath,
903
 
                                                          result_pool);
904
 
              break;
905
 
            case svn_wc_conflict_kind_property:
906
 
              entry->prejfile = svn_dirent_basename(cd->their_abspath,
907
 
                                                    result_pool);
908
 
              break;
909
 
            case svn_wc_conflict_kind_tree:
910
 
              break;
911
 
            }
 
881
      svn_skel_t *conflict;
 
882
      svn_boolean_t text_conflicted;
 
883
      svn_boolean_t prop_conflicted;
 
884
      SVN_ERR(svn_wc__db_read_conflict(&conflict, db, entry_abspath,
 
885
                                       scratch_pool, scratch_pool));
 
886
 
 
887
      SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, &text_conflicted,
 
888
                                         &prop_conflicted, NULL,
 
889
                                         db, dir_abspath, conflict,
 
890
                                         scratch_pool, scratch_pool));
 
891
 
 
892
      if (text_conflicted)
 
893
        {
 
894
          const char *my_abspath;
 
895
          const char *their_old_abspath;
 
896
          const char *their_abspath;
 
897
          SVN_ERR(svn_wc__conflict_read_text_conflict(&my_abspath,
 
898
                                                      &their_old_abspath,
 
899
                                                      &their_abspath,
 
900
                                                      db, dir_abspath,
 
901
                                                      conflict, scratch_pool,
 
902
                                                      scratch_pool));
 
903
 
 
904
          if (my_abspath)
 
905
            entry->conflict_wrk = svn_dirent_basename(my_abspath, result_pool);
 
906
 
 
907
          if (their_old_abspath)
 
908
            entry->conflict_old = svn_dirent_basename(their_old_abspath,
 
909
                                                      result_pool);
 
910
 
 
911
          if (their_abspath)
 
912
            entry->conflict_new = svn_dirent_basename(their_abspath,
 
913
                                                      result_pool);
 
914
        }
 
915
 
 
916
      if (prop_conflicted)
 
917
        {
 
918
          const char *prej_abspath;
 
919
 
 
920
          SVN_ERR(svn_wc__conflict_read_prop_conflict(&prej_abspath, NULL,
 
921
                                                      NULL, NULL, NULL,
 
922
                                                      db, dir_abspath,
 
923
                                                      conflict, scratch_pool,
 
924
                                                      scratch_pool));
 
925
 
 
926
          if (prej_abspath)
 
927
            entry->prejfile = svn_dirent_basename(prej_abspath, result_pool);
912
928
        }
913
929
    }
914
930
 
922
938
 
923
939
  /* Let's check for a file external.  ugh.  */
924
940
  if (status == svn_wc__db_status_normal
925
 
      && kind == svn_wc__db_kind_file)
 
941
      && kind == svn_node_file)
926
942
    SVN_ERR(check_file_external(entry, db, entry_abspath, dir_abspath,
927
943
                                result_pool, scratch_pool));
928
944
 
956
972
                         "" /* name */,
957
973
                         NULL /* parent_entry */,
958
974
                         result_pool, iterpool));
959
 
  apr_hash_set(entries, "", APR_HASH_KEY_STRING, parent_entry);
 
975
  svn_hash_sets(entries, "", parent_entry);
960
976
 
961
977
  /* Use result_pool so that the child names (used by reference, rather
962
978
     than copied) appear in result_pool.  */
973
989
      SVN_ERR(read_one_entry(&entry,
974
990
                             db, wc_id, local_abspath, name, parent_entry,
975
991
                             result_pool, iterpool));
976
 
      apr_hash_set(entries, entry->name, APR_HASH_KEY_STRING, entry);
 
992
      svn_hash_sets(entries, entry->name, entry);
977
993
    }
978
994
 
979
995
  svn_pool_destroy(iterpool);
1350
1366
 
1351
1367
      SVN_ERR(svn_wc__entry_is_hidden(&hidden, entry));
1352
1368
      if (!hidden)
1353
 
        apr_hash_set(*entries_pruned, key, APR_HASH_KEY_STRING, entry);
 
1369
        svn_hash_sets(*entries_pruned, key, entry);
1354
1370
    }
1355
1371
 
1356
1372
  return SVN_NO_ERROR;
1376
1392
}
1377
1393
 
1378
1394
svn_error_t *
1379
 
svn_wc_entries_read(apr_hash_t **entries,
1380
 
                    svn_wc_adm_access_t *adm_access,
1381
 
                    svn_boolean_t show_hidden,
1382
 
                    apr_pool_t *pool)
 
1395
svn_wc__entries_read_internal(apr_hash_t **entries,
 
1396
                              svn_wc_adm_access_t *adm_access,
 
1397
                              svn_boolean_t show_hidden,
 
1398
                              apr_pool_t *pool)
1383
1399
{
1384
1400
  apr_hash_t *new_entries;
1385
1401
 
1388
1404
    {
1389
1405
      svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
1390
1406
      const char *local_abspath = svn_wc__adm_access_abspath(adm_access);
1391
 
      apr_pool_t *result_pool = svn_wc_adm_access_pool(adm_access);
 
1407
      apr_pool_t *result_pool = svn_wc__adm_access_pool_internal(adm_access);
1392
1408
      svn_sqlite__db_t *sdb;
1393
1409
      struct entries_read_baton_t erb;
1394
1410
 
1412
1428
    *entries = new_entries;
1413
1429
  else
1414
1430
    SVN_ERR(prune_deleted(entries, new_entries,
1415
 
                          svn_wc_adm_access_pool(adm_access),
 
1431
                          svn_wc__adm_access_pool_internal(adm_access),
1416
1432
                          pool));
1417
1433
 
1418
1434
  return SVN_NO_ERROR;
1419
1435
}
1420
1436
 
 
1437
svn_error_t *
 
1438
svn_wc_entries_read(apr_hash_t **entries,
 
1439
                    svn_wc_adm_access_t *adm_access,
 
1440
                    svn_boolean_t show_hidden,
 
1441
                    apr_pool_t *pool)
 
1442
{
 
1443
  return svn_error_trace(svn_wc__entries_read_internal(entries, adm_access,
 
1444
                                                       show_hidden, pool));
 
1445
}
1421
1446
 
1422
1447
/* No transaction required: called from write_entry which is itself
1423
1448
   transaction-wrapped. */
1431
1456
  SVN_ERR_ASSERT(node->op_depth > 0 || node->repos_relpath);
1432
1457
 
1433
1458
  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
1434
 
  SVN_ERR(svn_sqlite__bindf(stmt, "isisnnnnsnrisnnni",
 
1459
  SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsnrisnnni",
1435
1460
                            node->wc_id,
1436
1461
                            node->local_relpath,
1437
1462
                            node->op_depth,
1441
1466
                            node->changed_rev,
1442
1467
                            node->changed_date,
1443
1468
                            node->changed_author,
1444
 
                            node->last_mod_time));
 
1469
                            node->recorded_time));
1445
1470
 
1446
1471
  if (node->repos_relpath)
1447
1472
    {
1449
1474
                                     node->repos_id));
1450
1475
      SVN_ERR(svn_sqlite__bind_text(stmt, 6,
1451
1476
                                    node->repos_relpath));
1452
 
      SVN_ERR(svn_sqlite__bind_int64(stmt, 7, node->revision));
 
1477
      SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, node->revision));
1453
1478
    }
1454
1479
 
1455
1480
  if (node->presence == svn_wc__db_status_normal)
1463
1488
  else if (node->presence == svn_wc__db_status_excluded)
1464
1489
    SVN_ERR(svn_sqlite__bind_text(stmt, 8, "excluded"));
1465
1490
  else if (node->presence == svn_wc__db_status_server_excluded)
1466
 
    SVN_ERR(svn_sqlite__bind_text(stmt, 8, "absent"));
 
1491
    SVN_ERR(svn_sqlite__bind_text(stmt, 8, "server-excluded"));
1467
1492
 
1468
1493
  if (node->kind == svn_node_none)
1469
1494
    SVN_ERR(svn_sqlite__bind_text(stmt, 10, "unknown"));
1491
1516
    SVN_ERR(svn_sqlite__bind_properties(stmt, 15, node->properties,
1492
1517
                                        scratch_pool));
1493
1518
 
1494
 
  if (node->translated_size != SVN_INVALID_FILESIZE)
1495
 
    SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->translated_size));
 
1519
  if (node->recorded_size != SVN_INVALID_FILESIZE)
 
1520
    SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->recorded_size));
1496
1521
 
1497
1522
  if (node->file_external)
1498
1523
    SVN_ERR(svn_sqlite__bind_int(stmt, 20, 1));
1499
1524
 
 
1525
  if (node->inherited_props)
 
1526
    SVN_ERR(svn_sqlite__bind_iprops(stmt, 23, node->inherited_props,
 
1527
                                    scratch_pool));
 
1528
 
1500
1529
  SVN_ERR(svn_sqlite__insert(NULL, stmt));
1501
1530
 
1502
1531
  return SVN_NO_ERROR;
1506
1535
/* */
1507
1536
static svn_error_t *
1508
1537
insert_actual_node(svn_sqlite__db_t *sdb,
 
1538
                   svn_wc__db_t *db,
 
1539
                   const char *wri_abspath,
1509
1540
                   const db_actual_node_t *actual_node,
1510
1541
                   apr_pool_t *scratch_pool)
1511
1542
{
1512
1543
  svn_sqlite__stmt_t *stmt;
 
1544
  svn_skel_t *conflict_data = NULL;
1513
1545
 
1514
1546
  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL_NODE));
1515
1547
 
1521
1553
    SVN_ERR(svn_sqlite__bind_properties(stmt, 4, actual_node->properties,
1522
1554
                                        scratch_pool));
1523
1555
 
1524
 
  if (actual_node->conflict_old)
1525
 
    {
1526
 
      SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->conflict_old));
1527
 
      SVN_ERR(svn_sqlite__bind_text(stmt, 6, actual_node->conflict_new));
1528
 
      SVN_ERR(svn_sqlite__bind_text(stmt, 7, actual_node->conflict_working));
1529
 
    }
1530
 
 
1531
 
  if (actual_node->prop_reject)
1532
 
    SVN_ERR(svn_sqlite__bind_text(stmt, 8, actual_node->prop_reject));
1533
 
 
1534
1556
  if (actual_node->changelist)
1535
 
    SVN_ERR(svn_sqlite__bind_text(stmt, 9, actual_node->changelist));
1536
 
 
1537
 
  if (actual_node->tree_conflict_data)
1538
 
    SVN_ERR(svn_sqlite__bind_text(stmt, 10, actual_node->tree_conflict_data));
 
1557
    SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->changelist));
 
1558
 
 
1559
  SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw(
 
1560
                                &conflict_data,
 
1561
                                db, wri_abspath,
 
1562
                                actual_node->local_relpath,
 
1563
                                actual_node->conflict_old,
 
1564
                                actual_node->conflict_working,
 
1565
                                actual_node->conflict_new,
 
1566
                                actual_node->prop_reject,
 
1567
                                actual_node->tree_conflict_data,
 
1568
                                actual_node->tree_conflict_data
 
1569
                                    ? strlen(actual_node->tree_conflict_data)
 
1570
                                    : 0,
 
1571
                                scratch_pool, scratch_pool));
 
1572
 
 
1573
  if (conflict_data)
 
1574
    {
 
1575
      svn_stringbuf_t *data = svn_skel__unparse(conflict_data, scratch_pool);
 
1576
 
 
1577
      SVN_ERR(svn_sqlite__bind_blob(stmt, 6, data->data, data->len));
 
1578
    }
1539
1579
 
1540
1580
  /* Execute and reset the insert clause. */
1541
1581
  return svn_error_trace(svn_sqlite__insert(NULL, stmt));
1542
1582
}
1543
1583
 
 
1584
static svn_boolean_t
 
1585
is_switched(db_node_t *parent,
 
1586
            db_node_t *child,
 
1587
            apr_pool_t *scratch_pool)
 
1588
{
 
1589
  if (parent && child)
 
1590
    {
 
1591
      if (parent->repos_id != child->repos_id)
 
1592
        return TRUE;
 
1593
 
 
1594
      if (parent->repos_relpath && child->repos_relpath)
 
1595
        {
 
1596
          const char *unswitched
 
1597
            = svn_relpath_join(parent->repos_relpath,
 
1598
                               svn_relpath_basename(child->local_relpath,
 
1599
                                                    scratch_pool),
 
1600
                               scratch_pool);
 
1601
          if (strcmp(unswitched, child->repos_relpath))
 
1602
            return TRUE;
 
1603
        }
 
1604
    }
 
1605
 
 
1606
  return FALSE;
 
1607
}
 
1608
 
1544
1609
struct write_baton {
1545
1610
  db_node_t *base;
1546
1611
  db_node_t *work;
1548
1613
  apr_hash_t *tree_conflicts;
1549
1614
};
1550
1615
 
 
1616
#define WRITE_ENTRY_ASSERT(expr) \
 
1617
  if (!(expr)) \
 
1618
    return svn_error_createf(SVN_ERR_ASSERTION_FAIL, NULL,  \
 
1619
                             _("Unable to upgrade '%s' at line %d"),    \
 
1620
                             svn_dirent_local_style( \
 
1621
                               svn_dirent_join(root_abspath, \
 
1622
                                               local_relpath,           \
 
1623
                                               scratch_pool),           \
 
1624
                               scratch_pool), __LINE__)
1551
1625
 
1552
1626
/* Write the information for ENTRY to WC_DB.  The WC_ID, REPOS_ID and
1553
1627
   REPOS_ROOT will all be used for writing ENTRY.
1663
1737
     replace+copied   replace+copied     [base|work]+work  [base|work]+work
1664
1738
  */
1665
1739
 
1666
 
  SVN_ERR_ASSERT(parent_node || entry->schedule == svn_wc_schedule_normal);
1667
 
  SVN_ERR_ASSERT(!parent_node || parent_node->base
1668
 
                 || parent_node->below_work || parent_node->work);
 
1740
  WRITE_ENTRY_ASSERT(parent_node || entry->schedule == svn_wc_schedule_normal);
 
1741
 
 
1742
  WRITE_ENTRY_ASSERT(!parent_node || parent_node->base
 
1743
                     || parent_node->below_work || parent_node->work);
1669
1744
 
1670
1745
  switch (entry->schedule)
1671
1746
    {
1710
1785
     BASE node to indicate the not-present node.  */
1711
1786
  if (entry->deleted)
1712
1787
    {
1713
 
      SVN_ERR_ASSERT(base_node || below_working_node);
1714
 
      SVN_ERR_ASSERT(!entry->incomplete);
 
1788
      WRITE_ENTRY_ASSERT(base_node || below_working_node);
 
1789
      WRITE_ENTRY_ASSERT(!entry->incomplete);
1715
1790
      if (base_node)
1716
1791
        base_node->presence = svn_wc__db_status_not_present;
1717
1792
      else
1719
1794
    }
1720
1795
  else if (entry->absent)
1721
1796
    {
1722
 
      SVN_ERR_ASSERT(base_node && !working_node && !below_working_node);
1723
 
      SVN_ERR_ASSERT(!entry->incomplete);
 
1797
      WRITE_ENTRY_ASSERT(base_node && !working_node && !below_working_node);
 
1798
      WRITE_ENTRY_ASSERT(!entry->incomplete);
1724
1799
      base_node->presence = svn_wc__db_status_server_excluded;
1725
1800
    }
1726
1801
 
1728
1803
    {
1729
1804
      if (entry->copyfrom_url)
1730
1805
        {
1731
 
          const char *relpath;
1732
 
 
1733
1806
          working_node->repos_id = repos_id;
1734
 
          relpath = svn_uri__is_child(this_dir->repos,
1735
 
                                      entry->copyfrom_url,
1736
 
                                      result_pool);
1737
 
          if (relpath == NULL)
1738
 
            working_node->repos_relpath = "";
1739
 
          else
1740
 
            working_node->repos_relpath = relpath;
 
1807
          working_node->repos_relpath = svn_uri_skip_ancestor(
 
1808
                                          this_dir->repos, entry->copyfrom_url,
 
1809
                                          result_pool);
1741
1810
          working_node->revision = entry->copyfrom_rev;
1742
1811
          working_node->op_depth
1743
1812
            = svn_wc__db_op_depth_for_upgrade(local_relpath);
1752
1821
          working_node->revision = parent_node->work->revision;
1753
1822
          working_node->op_depth = parent_node->work->op_depth;
1754
1823
        }
 
1824
      else if (parent_node->below_work
 
1825
                && parent_node->below_work->repos_relpath)
 
1826
        {
 
1827
          working_node->repos_id = repos_id;
 
1828
          working_node->repos_relpath
 
1829
            = svn_relpath_join(parent_node->below_work->repos_relpath,
 
1830
                               svn_relpath_basename(local_relpath, NULL),
 
1831
                               result_pool);
 
1832
          working_node->revision = parent_node->below_work->revision;
 
1833
          working_node->op_depth = parent_node->below_work->op_depth;
 
1834
        }
1755
1835
      else
1756
1836
        return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
1757
1837
                                 _("No copyfrom URL for '%s'"),
1827
1907
                                                               scratch_pool),
1828
1908
                                               scratch_pool, scratch_pool));
1829
1909
 
1830
 
          SVN_ERR_ASSERT(conflict->kind == svn_wc_conflict_kind_tree);
 
1910
          WRITE_ENTRY_ASSERT(conflict->kind == svn_wc_conflict_kind_tree);
1831
1911
 
1832
1912
          /* Fix dubious data stored by old clients, local adds don't have
1833
1913
             a repository URL. */
1840
1920
          /* Store in hash to be retrieved when writing the child
1841
1921
             row. */
1842
1922
          key = svn_dirent_skip_ancestor(root_abspath, conflict->local_abspath);
1843
 
          apr_hash_set(tree_conflicts, apr_pstrdup(result_pool, key),
1844
 
                       APR_HASH_KEY_STRING,
1845
 
                       svn_skel__unparse(new_skel, result_pool)->data);
 
1923
          svn_hash_sets(tree_conflicts, apr_pstrdup(result_pool, key),
 
1924
                        svn_skel__unparse(new_skel, result_pool)->data);
1846
1925
          skel = skel->next;
1847
1926
        }
1848
1927
    }
1851
1930
 
1852
1931
  if (parent_node && parent_node->tree_conflicts)
1853
1932
    {
1854
 
      const char *tree_conflict_data = apr_hash_get(parent_node->tree_conflicts,
1855
 
                                                    local_relpath,
1856
 
                                                    APR_HASH_KEY_STRING);
 
1933
      const char *tree_conflict_data =
 
1934
          svn_hash_gets(parent_node->tree_conflicts, local_relpath);
1857
1935
      if (tree_conflict_data)
1858
1936
        {
1859
1937
          actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
1862
1940
 
1863
1941
      /* Reset hash so that we don't write the row again when writing
1864
1942
         actual-only nodes */
1865
 
      apr_hash_set(parent_node->tree_conflicts, local_relpath,
1866
 
                   APR_HASH_KEY_STRING, NULL);
 
1943
      svn_hash_sets(parent_node->tree_conflicts, local_relpath, NULL);
1867
1944
    }
1868
1945
 
1869
1946
  if (entry->file_external_path != NULL)
1880
1957
      base_node->op_depth = 0;
1881
1958
      base_node->parent_relpath = parent_relpath;
1882
1959
      base_node->revision = entry->revision;
1883
 
      base_node->last_mod_time = entry->text_time;
1884
 
      base_node->translated_size = entry->working_size;
 
1960
      base_node->recorded_time = entry->text_time;
 
1961
      base_node->recorded_size = entry->working_size;
1885
1962
 
1886
1963
      if (entry->depth != svn_depth_exclude)
1887
1964
        base_node->depth = entry->depth;
1893
1970
 
1894
1971
      if (entry->deleted)
1895
1972
        {
1896
 
          SVN_ERR_ASSERT(base_node->presence == svn_wc__db_status_not_present);
 
1973
          WRITE_ENTRY_ASSERT(base_node->presence
 
1974
                             == svn_wc__db_status_not_present);
1897
1975
          /* ### should be svn_node_unknown, but let's store what we have. */
1898
1976
          base_node->kind = entry->kind;
1899
1977
        }
1900
1978
      else if (entry->absent)
1901
1979
        {
1902
 
          SVN_ERR_ASSERT(base_node->presence 
1903
 
                                == svn_wc__db_status_server_excluded);
 
1980
          WRITE_ENTRY_ASSERT(base_node->presence
 
1981
                             == svn_wc__db_status_server_excluded);
1904
1982
          /* ### should be svn_node_unknown, but let's store what we have. */
1905
1983
          base_node->kind = entry->kind;
1906
1984
 
1933
2011
              else if (entry->incomplete)
1934
2012
                {
1935
2013
                  /* ### nobody should have set the presence.  */
1936
 
                  SVN_ERR_ASSERT(base_node->presence
1937
 
                                 == svn_wc__db_status_normal);
 
2014
                  WRITE_ENTRY_ASSERT(base_node->presence
 
2015
                                     == svn_wc__db_status_normal);
1938
2016
                  base_node->presence = svn_wc__db_status_incomplete;
1939
2017
                }
1940
2018
            }
1995
2073
 
1996
2074
          if (entry->url != NULL)
1997
2075
            {
1998
 
              const char *relpath = svn_uri__is_child(this_dir->repos,
1999
 
                                                      entry->url,
2000
 
                                                      result_pool);
2001
 
              base_node->repos_relpath = relpath ? relpath : "";
 
2076
              base_node->repos_relpath = svn_uri_skip_ancestor(
 
2077
                                           this_dir->repos, entry->url,
 
2078
                                           result_pool);
2002
2079
            }
2003
2080
          else
2004
2081
            {
2005
 
              const char *relpath = svn_uri__is_child(this_dir->repos,
2006
 
                                                      this_dir->url,
2007
 
                                                      scratch_pool);
2008
 
              if (relpath == NULL)
 
2082
              const char *relpath = svn_uri_skip_ancestor(this_dir->repos,
 
2083
                                                          this_dir->url,
 
2084
                                                          scratch_pool);
 
2085
              if (relpath == NULL || *relpath == '\0')
2009
2086
                base_node->repos_relpath = entry->name;
2010
2087
              else
2011
2088
                base_node->repos_relpath =
2026
2103
      if (entry->file_external_path)
2027
2104
        base_node->file_external = TRUE;
2028
2105
 
 
2106
      /* Switched nodes get an empty iprops cache. */
 
2107
      if (parent_node
 
2108
          && is_switched(parent_node->base, base_node, scratch_pool))
 
2109
        base_node->inherited_props
 
2110
          = apr_array_make(scratch_pool, 0, sizeof(svn_prop_inherited_item_t*));
 
2111
 
2029
2112
      SVN_ERR(insert_node(sdb, base_node, scratch_pool));
2030
2113
 
2031
2114
      /* We have to insert the lock after the base node, because the node
2057
2140
      below_working_node->presence = svn_wc__db_status_normal;
2058
2141
      below_working_node->kind = entry->kind;
2059
2142
      below_working_node->repos_id = work->repos_id;
 
2143
 
 
2144
      /* This is just guessing. If the node below would have been switched
 
2145
         or if it was updated to a different version, the guess would
 
2146
         fail. But we don't have better information pre wc-ng :( */
2060
2147
      if (work->repos_relpath)
2061
2148
        below_working_node->repos_relpath
2062
2149
          = svn_relpath_join(work->repos_relpath, entry->name,
2079
2166
            below_working_node->checksum =
2080
2167
              text_base_info->revert_base.sha1_checksum;
2081
2168
        }
2082
 
      below_working_node->translated_size = 0;
 
2169
      below_working_node->recorded_size = 0;
2083
2170
      below_working_node->changed_rev = SVN_INVALID_REVNUM;
2084
2171
      below_working_node->changed_date = 0;
2085
2172
      below_working_node->changed_author = NULL;
2086
2173
      below_working_node->depth = svn_depth_infinity;
2087
 
      below_working_node->last_mod_time = 0;
 
2174
      below_working_node->recorded_time = 0;
2088
2175
      below_working_node->properties = NULL;
 
2176
 
 
2177
      if (working_node
 
2178
          && entry->schedule == svn_wc_schedule_delete
 
2179
          && working_node->repos_relpath)
 
2180
        {
 
2181
          /* We are lucky, our guesses above are not necessary. The known
 
2182
             correct information is in working. But our op_depth design
 
2183
             expects more information here */
 
2184
          below_working_node->repos_relpath = working_node->repos_relpath;
 
2185
          below_working_node->repos_id = working_node->repos_id;
 
2186
          below_working_node->revision = working_node->revision;
 
2187
 
 
2188
          /* Nice for 'svn status' */
 
2189
          below_working_node->changed_rev = entry->cmt_rev;
 
2190
          below_working_node->changed_date = entry->cmt_date;
 
2191
          below_working_node->changed_author = entry->cmt_author;
 
2192
 
 
2193
          /* And now remove it from WORKING, because in wc-ng code
 
2194
             should read it from the lower layer */
 
2195
          working_node->repos_relpath = NULL;
 
2196
          working_node->repos_id = 0;
 
2197
          working_node->revision = SVN_INVALID_REVNUM;
 
2198
        }
 
2199
 
2089
2200
      SVN_ERR(insert_node(sdb, below_working_node, scratch_pool));
2090
2201
    }
2091
2202
 
2096
2207
      working_node->local_relpath = local_relpath;
2097
2208
      working_node->parent_relpath = parent_relpath;
2098
2209
      working_node->changed_rev = SVN_INVALID_REVNUM;
2099
 
      working_node->last_mod_time = entry->text_time;
2100
 
      working_node->translated_size = entry->working_size;
 
2210
      working_node->recorded_time = entry->text_time;
 
2211
      working_node->recorded_size = entry->working_size;
2101
2212
 
2102
2213
      if (entry->depth != svn_depth_exclude)
2103
2214
        working_node->depth = entry->depth;
2157
2268
              if (entry->incomplete)
2158
2269
                {
2159
2270
                  /* We shouldn't be overwriting another status.  */
2160
 
                  SVN_ERR_ASSERT(working_node->presence
2161
 
                                 == svn_wc__db_status_normal);
 
2271
                  WRITE_ENTRY_ASSERT(working_node->presence
 
2272
                                     == svn_wc__db_status_normal);
2162
2273
                  working_node->presence = svn_wc__db_status_incomplete;
2163
2274
                }
2164
2275
            }
2201
2312
      actual_node->local_relpath = local_relpath;
2202
2313
      actual_node->parent_relpath = parent_relpath;
2203
2314
 
2204
 
      SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
 
2315
      SVN_ERR(insert_actual_node(sdb, db, tmp_entry_abspath,
 
2316
                                 actual_node, scratch_pool));
2205
2317
    }
2206
2318
 
2207
2319
  if (entry_node)
2229
2341
static svn_error_t *
2230
2342
write_actual_only_entries(apr_hash_t *tree_conflicts,
2231
2343
                          svn_sqlite__db_t *sdb,
 
2344
                          svn_wc__db_t *db,
 
2345
                          const char *wri_abspath,
2232
2346
                          apr_int64_t wc_id,
2233
2347
                          const char *parent_relpath,
2234
2348
                          apr_pool_t *scratch_pool)
2247
2361
      actual_node->parent_relpath = parent_relpath;
2248
2362
      actual_node->tree_conflict_data = svn__apr_hash_index_val(hi);
2249
2363
 
2250
 
      SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
 
2364
      SVN_ERR(insert_actual_node(sdb, db, wri_abspath, actual_node,
 
2365
                                 scratch_pool));
2251
2366
    }
2252
2367
 
2253
2368
  return SVN_NO_ERROR;
2275
2390
  struct write_baton *dir_node;
2276
2391
 
2277
2392
  /* Get a copy of the "this dir" entry for comparison purposes. */
2278
 
  this_dir = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR,
2279
 
                          APR_HASH_KEY_STRING);
 
2393
  this_dir = svn_hash_gets(entries, SVN_WC_ENTRY_THIS_DIR);
2280
2394
 
2281
2395
  /* If there is no "this dir" entry, something is wrong. */
2282
2396
  if (! this_dir)
2307
2421
      const svn_wc_entry_t *this_entry = svn__apr_hash_index_val(hi);
2308
2422
      const char *child_abspath, *child_relpath;
2309
2423
      svn_wc__text_base_info_t *text_base_info
2310
 
        = apr_hash_get(text_bases_info, name, APR_HASH_KEY_STRING);
 
2424
        = svn_hash_gets(text_bases_info, name);
2311
2425
 
2312
2426
      svn_pool_clear(iterpool);
2313
2427
 
2329
2443
    }
2330
2444
 
2331
2445
  if (dir_node->tree_conflicts)
2332
 
    SVN_ERR(write_actual_only_entries(dir_node->tree_conflicts, sdb,
2333
 
                                      wc_id, dir_relpath, iterpool));
 
2446
    SVN_ERR(write_actual_only_entries(dir_node->tree_conflicts, sdb, db,
 
2447
                                      new_root_abspath, wc_id, dir_relpath,
 
2448
                                      iterpool));
2334
2449
 
2335
2450
  *dir_baton = dir_node;
2336
2451
  svn_pool_destroy(iterpool);
2425
2540
  svn_error_t *err;
2426
2541
  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
2427
2542
 
2428
 
  err = svn_wc_entries_read(&entries, adm_access, show_hidden, pool);
 
2543
  err = svn_wc__entries_read_internal(&entries, adm_access, show_hidden,
 
2544
                                      pool);
2429
2545
 
2430
2546
  if (err)
2431
2547
    SVN_ERR(walk_callbacks->handle_error(dirpath, err, walk_baton, pool));
2432
2548
 
2433
2549
  /* As promised, always return the '.' entry first. */
2434
 
  dot_entry = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR,
2435
 
                           APR_HASH_KEY_STRING);
 
2550
  dot_entry = svn_hash_gets(entries, SVN_WC_ENTRY_THIS_DIR);
2436
2551
  if (! dot_entry)
2437
2552
    return walk_callbacks->handle_error
2438
2553
      (dirpath, svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
2544
2659
  const char *local_abspath;
2545
2660
  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
2546
2661
  svn_error_t *err;
2547
 
  svn_wc__db_kind_t kind;
 
2662
  svn_node_kind_t kind;
2548
2663
  svn_depth_t depth;
2549
2664
 
2550
2665
  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2568
2683
        walk_baton, pool);
2569
2684
    }
2570
2685
 
2571
 
  if (kind == svn_wc__db_kind_file || depth == svn_depth_exclude)
 
2686
  if (kind == svn_node_file || depth == svn_depth_exclude)
2572
2687
    {
2573
2688
      const svn_wc_entry_t *entry;
2574
2689
 
2610
2725
      return SVN_NO_ERROR;
2611
2726
    }
2612
2727
 
2613
 
  if (kind == svn_wc__db_kind_dir)
 
2728
  if (kind == svn_node_dir)
2614
2729
    return walker_helper(path, adm_access, walk_callbacks, walk_baton,
2615
2730
                         walk_depth, show_hidden, cancel_func, cancel_baton,
2616
2731
                         pool);