static svn_error_t *
test_entries_alloc(apr_pool_t *pool)
{
  svn_wc__db_t *db;
  const char *local_abspath;
  svn_wc_adm_access_t *adm_access;
  apr_hash_t *entries;
  const svn_wc_entry_t *entry;
  const char *local_relpath;

#undef WC_NAME
#define WC_NAME "test_entries_alloc"

  SVN_ERR(create_open(&db, &local_abspath, WC_NAME, pool));

  SVN_ERR(svn_wc_adm_open3(&adm_access,
                           NULL /* associated */,
                           svn_dirent_join("fake-wc", WC_NAME, pool),
                           FALSE /* write_lock */,
                           0 /* levels_to_lock */,
                           NULL /* cancel_func */,
                           NULL /* cancel_baton */,
                           pool));
  SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE /* show_hidden */,
                              pool));

  /* The wcroot has 12 BASE children + 1 WORKING child + "this dir".  */
  SVN_TEST_ASSERT(apr_hash_count(entries) == 14);

  /* The "D" entry in the entries hash should be what we get from the
     svn_wc_entry() entrypoint.  */
  local_relpath = svn_dirent_join_many(pool,
                                       "fake-wc",
                                       WC_NAME,
                                       "D",
                                       NULL);
  SVN_ERR(svn_wc_entry(&entry, local_relpath, adm_access, TRUE, pool));
  SVN_TEST_ASSERT(entry == apr_hash_get(entries, "D", APR_HASH_KEY_STRING));

  /* This entry should be missing.  */
  SVN_ERR(svn_wc_entry(&entry, "missing", adm_access, TRUE, pool));
  SVN_TEST_ASSERT(entry == NULL);

  return SVN_NO_ERROR;
}
static svn_error_t *
test_stubs(apr_pool_t *pool)
{
  svn_wc__db_t *db;
  const char *local_abspath;
  const char *local_relpath;
  svn_wc_adm_access_t *adm_access;
  svn_wc_adm_access_t *subdir_access;
  const svn_wc_entry_t *stub_entry;
  const svn_wc_entry_t *entry;
  const svn_wc_entry_t *test_entry;
  apr_hash_t *entries;

#undef WC_NAME
#define WC_NAME "test_stubs"

  SVN_ERR(create_open(&db, &local_abspath, WC_NAME, pool));

  /* The "M" entry is a subdir. Let's ensure we can reach its stub,
     and the actual contents.  */
  local_relpath = svn_dirent_join_many(pool,
                                       "fake-wc",
                                       WC_NAME,
                                       "M",
                                       NULL);

  SVN_ERR(svn_wc_adm_open3(&adm_access,
                           NULL /* associated */,
                           svn_dirent_join("fake-wc", WC_NAME, pool),
                           FALSE /* write_lock */,
                           0 /* levels_to_lock */,
                           NULL /* cancel_func */,
                           NULL /* cancel_baton */,
                           pool));

  /* Ensure we get the stub. NOTE: do this before we have associated the
     subdir baton with ADM_ACCESS.  */
  SVN_ERR(svn_wc_entry(&stub_entry, local_relpath, adm_access, TRUE, pool));
  SVN_TEST_STRING_ASSERT(stub_entry->name, "M");

  SVN_ERR(svn_wc_adm_open3(&subdir_access,
                           adm_access,
                           local_relpath,
                           FALSE /* write_lock */,
                           0 /* levels_to_lock */,
                           NULL /* cancel_func */,
                           NULL /* cancel_baton */,
                           pool));

  /* Ensure we get the real entry.  */
  SVN_ERR(svn_wc_entry(&entry, local_relpath, subdir_access, TRUE, pool));
  SVN_TEST_STRING_ASSERT(entry->name, "");

  /* Ensure that we get the SAME entry, even using the parent baton.  */
  SVN_ERR(svn_wc_entry(&test_entry, local_relpath, adm_access, TRUE, pool));
  SVN_TEST_ASSERT(test_entry == entry);

  /* Ensure we get the stub when reading entries with ADM_ACCESS.  */
  SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE /* show_hidden */,
                              pool));
  SVN_TEST_ASSERT(stub_entry
                  == apr_hash_get(entries, "M", APR_HASH_KEY_STRING));

  /* Ensure we get the real entry when reading entries with SUBDIR_ACCESS.  */
  SVN_ERR(svn_wc_entries_read(&entries, subdir_access, TRUE /* show_hidden */,
                              pool));
  SVN_TEST_ASSERT(entry
                  == apr_hash_get(entries, "", APR_HASH_KEY_STRING));

  return SVN_NO_ERROR;
}
Beispiel #3
0
static svn_error_t *
entries_dump(const char *dir_path, svn_wc_adm_access_t *related, apr_pool_t *pool)
{
  svn_wc_adm_access_t *adm_access = NULL;
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  svn_boolean_t locked;
  svn_error_t *err;
  svn_wc_context_t *wc_ctx = NULL;
  const char *dir_abspath;

  err = svn_wc_adm_open3(&adm_access, related, dir_path, FALSE, 0,
                         NULL, NULL, pool);
  if (!err)
    {
      SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
                                             svn_wc__adm_get_db(adm_access),
                                             pool));
      SVN_ERR(svn_dirent_get_absolute(&dir_abspath, dir_path, pool));

      SVN_ERR(svn_wc_locked2(NULL, &locked, wc_ctx, dir_abspath, pool));
      SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE, pool));
    }
  else if (err && err->apr_err == SVN_ERR_WC_LOCKED
           && related
           && ! strcmp(dir_path, svn_wc_adm_access_path(related)))
    {
      /* Common caller error: Can't open a baton when there is one. */
      svn_error_clear(err);

      SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
                                             svn_wc__adm_get_db(related),
                                             pool));
      SVN_ERR(svn_dirent_get_absolute(&dir_abspath, dir_path, pool));

      SVN_ERR(svn_wc_locked2(NULL, &locked, wc_ctx, dir_abspath, pool));
      SVN_ERR(svn_wc_entries_read(&entries, related, TRUE, pool));
    }
  else
    {
      const char *lockfile_path;
      svn_node_kind_t kind;

      /* ### Should svn_wc_adm_open3 be returning UPGRADE_REQUIRED? */
      if (err->apr_err != SVN_ERR_WC_NOT_DIRECTORY)
        return err;
      svn_error_clear(err);
      adm_access = NULL;
      SVN_ERR(svn_dirent_get_absolute(&dir_abspath, dir_path, pool));
      SVN_ERR(svn_wc__read_entries_old(&entries, dir_abspath, pool, pool));
      lockfile_path = svn_dirent_join_many(pool, dir_path,
                                           svn_wc_get_adm_dir(pool),
                                           "lock", SVN_VA_NULL);
      SVN_ERR(svn_io_check_path(lockfile_path, &kind, pool));
      locked = (kind == svn_node_file);
    }

  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
    {
      const char *key = apr_hash_this_key(hi);
      const svn_wc_entry_t *entry = apr_hash_this_val(hi);

      SVN_ERR_ASSERT(strcmp(key, entry->name) == 0);

      printf("e = Entry()\n");
      str_value("name", entry->name);
      int_value("revision", entry->revision);
      str_value("url", entry->url);
      str_value("repos", entry->repos);
      str_value("uuid", entry->uuid);
      int_value("kind", entry->kind);
      int_value("schedule", entry->schedule);
      bool_value("copied", entry->copied);
      bool_value("deleted", entry->deleted);
      bool_value("absent", entry->absent);
      bool_value("incomplete", entry->incomplete);
      str_value("copyfrom_url", entry->copyfrom_url);
      int_value("copyfrom_rev", entry->copyfrom_rev);
      str_value("conflict_old", entry->conflict_old);
      str_value("conflict_new", entry->conflict_new);
      str_value("conflict_wrk", entry->conflict_wrk);
      str_value("prejfile", entry->prejfile);
      /* skip: text_time */
      /* skip: prop_time */
      /* skip: checksum */
      int_value("cmt_rev", entry->cmt_rev);
      /* skip: cmt_date */
      str_value("cmt_author", entry->cmt_author);
      str_value("lock_token", entry->lock_token);
      str_value("lock_owner", entry->lock_owner);
      str_value("lock_comment", entry->lock_comment);
      /* skip: lock_creation_date */
      /* skip: has_props */
      /* skip: has_prop_mods */
      /* skip: cachable_props */
      /* skip: present_props */
      str_value("changelist", entry->changelist);
      /* skip: working_size */
      /* skip: keep_local */
      int_value("depth", entry->depth);
      /* skip: tree_conflict_data */
      bool_value("file_external", entry->file_external_path != NULL);
      /* skip: file_external_peg_rev */
      /* skip: file_external_rev */
      bool_value("locked", locked && *entry->name == '\0');
      printf("entries['%s'] = e\n", (const char *)key);
    }

  if (wc_ctx)
    SVN_ERR(svn_wc_context_destroy(wc_ctx));

  if (adm_access)
    SVN_ERR(svn_wc_adm_close2(adm_access, pool));

  return SVN_NO_ERROR;
}
Beispiel #4
0
svn_error_t *
svn_wc_relocate3(const char *path,
                 svn_wc_adm_access_t *adm_access,
                 const char *from,
                 const char *to,
                 svn_boolean_t recurse,
                 svn_wc_relocation_validator3_t validator,
                 void *validator_baton,
                 apr_pool_t *pool)
{
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  const svn_wc_entry_t *entry;
  apr_pool_t *subpool;

  SVN_ERR(svn_wc_entry(&entry, path, adm_access, TRUE, pool));
  if (! entry)
    return svn_error_create(SVN_ERR_ENTRY_NOT_FOUND, NULL, NULL);

  if (entry->kind == svn_node_file
      || entry->depth == svn_depth_exclude)
    return relocate_entry(adm_access, entry, from, to,
                          validator, validator_baton, TRUE /* sync */,
                          pool);

  /* Relocate THIS_DIR first, in order to pre-validate the relocated URL
     of all of the other entries.  This is technically cheating because
     it relies on knowledge of the libsvn_client implementation, but it
     significantly cuts down on the number of expensive validations the
     validator has to do.  ### Should svn_wc.h document the ordering? */
  SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE, pool));
  entry = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);
  SVN_ERR(relocate_entry(adm_access, entry, from, to,
                         validator, validator_baton, FALSE, pool));

  subpool = svn_pool_create(pool);

  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
    {
      const void *key;
      void *val;

      apr_hash_this(hi, &key, NULL, &val);
      entry = val;

      if (strcmp(key, SVN_WC_ENTRY_THIS_DIR) == 0)
        continue;

      svn_pool_clear(subpool);

      if (recurse && (entry->kind == svn_node_dir)
          && (! entry->deleted || (entry->schedule == svn_wc_schedule_add))
          && ! entry->absent
          && (entry->depth != svn_depth_exclude))
        {
          svn_wc_adm_access_t *subdir_access;
          const char *subdir = svn_path_join(path, key, subpool);
          if (svn_wc__adm_missing(adm_access, subdir))
            continue;
          SVN_ERR(svn_wc_adm_retrieve(&subdir_access, adm_access,
                                      subdir, subpool));
          SVN_ERR(svn_wc_relocate3(subdir, subdir_access, from, to,
                                   recurse, validator,
                                   validator_baton, subpool));
        }
      SVN_ERR(relocate_entry(adm_access, entry, from, to,
                             validator, validator_baton, FALSE, subpool));
    }

  svn_pool_destroy(subpool);

  SVN_ERR(svn_wc__props_delete(path, svn_wc__props_wcprop, adm_access, pool));
  return svn_wc__entries_write(entries, adm_access, pool);
}