コード例 #1
0
ファイル: add.c プロジェクト: vocho/openqnx
svn_error_t *
svn_client_add4(const char *path,
                svn_depth_t depth,
                svn_boolean_t force,
                svn_boolean_t no_ignore,
                svn_boolean_t add_parents,
                svn_client_ctx_t *ctx,
                apr_pool_t *pool)
{
  svn_error_t *err, *err2;
  svn_wc_adm_access_t *adm_access;
  const char *parent_dir;

  if (add_parents)
    {
      apr_pool_t *subpool;

      SVN_ERR(svn_path_get_absolute(&path, path, pool));
      parent_dir = svn_path_dirname(path, pool);

      subpool = svn_pool_create(pool);
      SVN_ERR(add_parent_dirs(parent_dir, &adm_access, ctx, subpool));
      SVN_ERR(svn_wc_adm_close(adm_access));
      svn_pool_destroy(subpool);

      SVN_ERR(svn_wc_adm_open3(&adm_access, NULL, parent_dir,
                               TRUE, 0, ctx->cancel_func, ctx->cancel_baton,
                               pool));
    }
  else
    {
      parent_dir = svn_path_dirname(path, pool);
      SVN_ERR(svn_wc_adm_open3(&adm_access, NULL, parent_dir,
                               TRUE, 0, ctx->cancel_func, ctx->cancel_baton,
                               pool));
    }

  err = add(path, depth, force, no_ignore, adm_access, ctx, pool);

  err2 = svn_wc_adm_close(adm_access);
  if (err2)
    {
      if (err)
        svn_error_clear(err2);
      else
        err = err2;
    }

  return err;
}
コード例 #2
0
ファイル: adm_files.c プロジェクト: aosm/subversion
svn_error_t *
svn_wc_ensure_adm3(const char *path,
                   const char *uuid,
                   const char *url,
                   const char *repos,
                   svn_revnum_t revision,
                   svn_depth_t depth,
                   apr_pool_t *pool)
{
  svn_wc_adm_access_t *adm_access;
  const svn_wc_entry_t *entry;
  int format;

  SVN_ERR(svn_wc_check_wc(path, &format, pool));

  /* Early out: we know we're not dealing with an existing wc, so
     just create one. */
  if (format == 0)
    return init_adm(path, uuid, url, repos, revision, depth, pool);

  /* Now, get the existing url and repos for PATH. */
  SVN_ERR(svn_wc_adm_open3(&adm_access, NULL, path, FALSE, 0,
                           NULL, NULL, pool));
  SVN_ERR(svn_wc__entry_versioned(&entry, path, adm_access, FALSE, pool));
  SVN_ERR(svn_wc_adm_close2(adm_access, pool));

  /* When the directory exists and is scheduled for deletion do not
   * check the revision or the URL.  The revision can be any
   * arbitrary revision and the URL may differ if the add is
   * being driven from a merge which will have a different URL. */
  if (entry->schedule != svn_wc_schedule_delete)
    {
      if (entry->revision != revision)
        return
          svn_error_createf
          (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
           _("Revision %ld doesn't match existing revision %ld in '%s'"),
           revision, entry->revision, path);

      /** ### comparing URLs, should they be canonicalized first? */
      if (strcmp(entry->url, url) != 0)
        return
          svn_error_createf
          (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
           _("URL '%s' doesn't match existing URL '%s' in '%s'"),
           url, entry->url, path);
    }

  return SVN_NO_ERROR;
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: add.c プロジェクト: vocho/openqnx
/* Go up the directory tree, looking for a versioned directory.  If found,
   add all the intermediate directories.  Otherwise, return
   SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
static svn_error_t *
add_parent_dirs(const char *path,
                svn_wc_adm_access_t **parent_access,
                svn_client_ctx_t *ctx,
                apr_pool_t *pool)
{
  svn_wc_adm_access_t *adm_access;
  svn_error_t *err;

  err = svn_wc_adm_open3(&adm_access, NULL, path, TRUE, 0,
                         ctx->cancel_func, ctx->cancel_baton, pool);

  if (err && err->apr_err == SVN_ERR_WC_NOT_DIRECTORY)
    {
      if (svn_dirent_is_root(path, strlen(path)))
        {
          svn_error_clear(err);

          return svn_error_create
            (SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL, NULL);
        }
      else
        {
          const char *parent_path = svn_path_dirname(path, pool);

          svn_error_clear(err);
          SVN_ERR(add_parent_dirs(parent_path, &adm_access, ctx, pool));
          SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access, parent_path,
                                      pool));
          SVN_ERR(svn_wc_add2(path, adm_access, NULL, SVN_INVALID_REVNUM,
                              ctx->cancel_func, ctx->cancel_baton,
                              ctx->notify_func2, ctx->notify_baton2, pool));
        }
    }
  else if (err)
    {
      return err;
    }

  if (parent_access)
    *parent_access = adm_access;

  return SVN_NO_ERROR;
}
コード例 #5
0
ファイル: entries-dump.c プロジェクト: gunjanms/svnmigration
static svn_error_t *
tree_dump(const char *path,
          apr_pool_t *scratch_pool)
{
  struct directory_walk_baton bt;
  svn_sqlite__db_t *sdb;
  svn_wc__db_t *db;

  bt.prefix_path = path;

  /* Obtain an access baton to allow re-using the same wc_db for all access */
  SVN_ERR(svn_wc_adm_open3(&bt.adm_access, NULL, path, FALSE, 0, NULL, NULL,
                           scratch_pool));

  db = svn_wc__adm_get_db(bt.adm_access);

  SVN_ERR(svn_wc__context_create_with_db(&bt.wc_ctx, NULL, db, scratch_pool));

  SVN_ERR(svn_dirent_get_absolute(&bt.root_abspath, path, scratch_pool));

  /* And now get us a transaction on the database to avoid obtaining and
     releasing locks all the time */
  SVN_ERR(svn_wc__db_temp_borrow_sdb(&sdb, bt.wc_ctx->db, bt.root_abspath,
                                     scratch_pool));

  SVN_SQLITE__WITH_LOCK(
      svn_wc__internal_walk_children(db, bt.root_abspath, FALSE,
                                     NULL, tree_dump_dir, &bt,
                                     svn_depth_infinity,
                                     NULL, NULL, scratch_pool),
      sdb);

  /* And close everything we've opened */
  SVN_ERR(svn_wc_context_destroy(bt.wc_ctx));
  SVN_ERR(svn_wc_adm_close2(bt.adm_access, scratch_pool));

  return SVN_NO_ERROR;
}
コード例 #6
0
static svn_error_t *
test_access_baton_like_locking(apr_pool_t *pool)
{
  svn_wc__db_t *db;
  svn_wc_context_t *wc_ctx, *wc_ctx2;
  const char *local_abspath;
  const char *D, *D1, *D2, *D3, *D4;
  svn_boolean_t locked_here, locked;
  svn_error_t *err;
  svn_wc_adm_access_t *adm_access, *subdir_access;

#undef WC_NAME
#define WC_NAME "test_access_batons"
  SVN_ERR(create_open(&db, &local_abspath, WC_NAME, pool));

  D = svn_dirent_join(local_abspath, "DD", pool);

  D1 = svn_dirent_join(D, "DD", pool);
  D2 = svn_dirent_join(D1, "DD", pool);
  D3 = svn_dirent_join(D2, "DD", pool);
  D4 = svn_dirent_join(D3, "DD", pool);

  SVN_ERR(svn_io_make_dir_recursively(D4, pool));

  /* Use the legacy interface */
  SVN_ERR(svn_wc_adm_open3(&adm_access, NULL, local_abspath, TRUE, 0,
                           NULL, NULL, pool));
  SVN_ERR(svn_wc_add3(D, adm_access, svn_depth_infinity, NULL,
                      SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_adm_retrieve(&subdir_access, adm_access, D, pool));
  SVN_ERR(svn_wc_add3(D1, subdir_access, svn_depth_infinity, NULL,
                      SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_adm_retrieve(&subdir_access, adm_access, D1, pool));
  SVN_ERR(svn_wc_add3(D2, subdir_access, svn_depth_infinity, NULL,
                      SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_adm_retrieve(&subdir_access, adm_access, D2, pool));
  SVN_ERR(svn_wc_add3(D3, subdir_access, svn_depth_infinity, NULL,
                      SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_add3(D4, subdir_access, svn_depth_infinity, NULL,
                      SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_locked(&locked, D3, pool));
  SVN_TEST_ASSERT(locked);
  SVN_ERR(svn_wc_locked(&locked, D4, pool));
  SVN_TEST_ASSERT(locked);
  SVN_ERR(svn_wc_delete3(D4, subdir_access, NULL, NULL, NULL, NULL, FALSE,
                         pool));
  SVN_ERR(svn_wc_locked(&locked, D4, pool));
  SVN_TEST_ASSERT(!locked);
  SVN_ERR(svn_wc_revert3(D, adm_access, svn_depth_infinity, FALSE,
                         NULL, NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_locked(&locked, D3, pool));
  SVN_TEST_ASSERT(!locked);
  SVN_ERR(svn_wc_locked(&locked, local_abspath, pool));
  SVN_TEST_ASSERT(locked);
  SVN_ERR(svn_wc_adm_close2(adm_access, pool));

  SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));

  /* Obtain a lock for the root, which is extended on each level */
  SVN_ERR(svn_wc__db_wclock_obtain(wc_ctx->db, local_abspath, 0, FALSE, pool));
  SVN_ERR(svn_io_make_dir_recursively(D4, pool));
  SVN_ERR(svn_wc_add4(wc_ctx, D, svn_depth_infinity, NULL, SVN_INVALID_REVNUM,
                      NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_add4(wc_ctx, D1, svn_depth_infinity, NULL, SVN_INVALID_REVNUM,
                      NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_add4(wc_ctx, D2, svn_depth_infinity, NULL, SVN_INVALID_REVNUM,
                      NULL, NULL, NULL, NULL, pool));
  SVN_ERR(svn_wc_add4(wc_ctx, D3, svn_depth_infinity, NULL, SVN_INVALID_REVNUM,
                      NULL, NULL, NULL, NULL, pool));

  SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx, D3, pool));
  SVN_TEST_ASSERT(locked_here && locked);

  /* Test if the not added path is already locked */
  SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx, D4, pool));
  SVN_TEST_ASSERT(!locked_here && !locked);

  SVN_ERR(svn_wc_add4(wc_ctx, D4, svn_depth_infinity, NULL, SVN_INVALID_REVNUM,
                      NULL, NULL, NULL, NULL, pool));

  SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx, D4, pool));
  SVN_TEST_ASSERT(locked_here && locked);

  SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, local_abspath, pool));
  /* Should be unlocked */
  SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx, local_abspath, pool));
  SVN_TEST_ASSERT(!locked_here && !locked);

  /* Lock shouldn't be released */
  SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx, D, pool));
  SVN_TEST_ASSERT(locked_here && locked);

  SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, D, pool));
  SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, D1, pool));
  SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, D2, pool));
  SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, D3, pool));

  /* Try reobtaining lock on D3; should succeed */
  SVN_ERR(svn_wc__db_wclock_obtain(wc_ctx->db, D3, 0, FALSE, pool));
  SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, D4, pool));


  /* D3 should still be locked; try stealing in a different context */
  SVN_ERR(svn_wc_context_create(&wc_ctx2, NULL, pool, pool));
  SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx2, D3, pool));
  SVN_TEST_ASSERT(!locked_here && locked);

  err = svn_wc__db_wclock_obtain(wc_ctx2->db, D3, 0, FALSE, pool);

  if (err && err->apr_err != SVN_ERR_WC_LOCKED)
    return svn_error_trace(err);
  svn_error_clear(err);

  SVN_TEST_ASSERT(err != NULL); /* Can't lock, as it is still locked */

  err = svn_wc__db_wclock_release(wc_ctx2->db, D4, pool);
  if (err && err->apr_err != SVN_ERR_WC_NOT_LOCKED)
    return svn_error_trace(err);
  svn_error_clear(err);

  SVN_TEST_ASSERT(err != NULL); /* Can't unlock, as it is not ours */

  /* Now steal the lock */
  SVN_ERR(svn_wc__db_wclock_obtain(wc_ctx2->db, D3, 0, TRUE, pool));

  /* We should own the lock now */
  SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx2, D3, pool));
  SVN_TEST_ASSERT(locked_here && locked);

  err = svn_wc__db_wclock_release(wc_ctx2->db, D4, pool);
  if (err && err->apr_err != SVN_ERR_WC_NOT_LOCKED)
    return svn_error_trace(err);
  svn_error_clear(err);

  SVN_TEST_ASSERT(err != NULL); /* Can't unlock a not locked path */

  /* Now create a separate working copy from the same repository directly
     below this WC and test if our code really sees it as a separate wc,
     for locking and normal operation */
  {
    const char *url, *repos_root_url, *repos_uuid;
    const char *subdir = svn_dirent_join(local_abspath, "sub-wc", pool);

    svn_boolean_t is_root;
    SVN_ERR(svn_wc__node_get_url(&url, wc_ctx, local_abspath, pool, pool));
    SVN_ERR(svn_wc__node_get_repos_info(&repos_root_url, &repos_uuid,
                                        wc_ctx, local_abspath,
                                        pool, pool));

    SVN_ERR(svn_io_make_dir_recursively(subdir, pool));
    SVN_ERR(svn_wc_ensure_adm3(subdir, repos_uuid,
                               svn_path_url_add_component2(url, "sub-wc", pool),
                               repos_root_url, 0, svn_depth_infinity,
                               pool));

    SVN_ERR(svn_wc__check_wc_root(&is_root, NULL, NULL, wc_ctx->db, subdir,
                                  pool));

    SVN_TEST_ASSERT(is_root);

    SVN_ERR(svn_wc__check_wc_root(&is_root, NULL, NULL, wc_ctx2->db, subdir,
                                  pool));

    /* This test was added to show a regression where the next check failed,
       but the check above this succeeded */
    SVN_TEST_ASSERT(is_root);

    SVN_ERR(svn_wc_locked2(&locked_here, &locked, wc_ctx2, subdir, pool));
    SVN_TEST_ASSERT(!locked_here && !locked);
  }

  return SVN_NO_ERROR;
}
コード例 #7
0
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;
}
コード例 #8
0
ファイル: status.c プロジェクト: aosm/subversion
svn_error_t *
svn_client_status4(svn_revnum_t *result_rev,
                   const char *path,
                   const svn_opt_revision_t *revision,
                   svn_wc_status_func3_t status_func,
                   void *status_baton,
                   svn_depth_t depth,
                   svn_boolean_t get_all,
                   svn_boolean_t update,
                   svn_boolean_t no_ignore,
                   svn_boolean_t ignore_externals,
                   const apr_array_header_t *changelists,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
{
  svn_wc_adm_access_t *anchor_access, *target_access;
  svn_wc_traversal_info_t *traversal_info = svn_wc_init_traversal_info(pool);
  const char *anchor, *target;
  const svn_delta_editor_t *editor;
  void *edit_baton, *set_locks_baton;
  const svn_wc_entry_t *entry = NULL;
  struct status_baton sb;
  apr_array_header_t *ignores;
  svn_error_t *err;
  apr_hash_t *changelist_hash = NULL;
  svn_revnum_t edit_revision = SVN_INVALID_REVNUM;

  if (changelists && changelists->nelts)
    SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));

  sb.real_status_func = status_func;
  sb.real_status_baton = status_baton;
  sb.deleted_in_repos = FALSE;
  sb.changelist_hash = changelist_hash;

  /* Try to open the target directory. If the target is a file or an
     unversioned directory, open the parent directory instead */
  err = svn_wc_adm_open3(&anchor_access, NULL, path, FALSE,
                         SVN_DEPTH_IS_RECURSIVE(depth) ? -1 : 1,
                         ctx->cancel_func, ctx->cancel_baton,
                         pool);
  if (err && err->apr_err == SVN_ERR_WC_NOT_DIRECTORY)
    {
      svn_error_clear(err);
      SVN_ERR(svn_wc_adm_open_anchor(&anchor_access, &target_access, &target,
                                     path, FALSE,
                                     SVN_DEPTH_IS_RECURSIVE(depth) ? -1 : 1,
                                     ctx->cancel_func, ctx->cancel_baton,
                                     pool));
    }
  else if (!err)
    {
      target = "";
      target_access = anchor_access;
    }
  else
    return err;

  anchor = svn_wc_adm_access_path(anchor_access);

  /* Get the status edit, and use our wrapping status function/baton
     as the callback pair. */
  SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
  SVN_ERR(svn_wc_get_status_editor4(&editor, &edit_baton, &set_locks_baton,
                                    &edit_revision, anchor_access, target,
                                    depth, get_all, no_ignore, ignores,
                                    tweak_status, &sb, ctx->cancel_func,
                                    ctx->cancel_baton, traversal_info,
                                    pool));

  /* If we want to know about out-of-dateness, we crawl the working copy and
     let the RA layer drive the editor for real.  Otherwise, we just close the
     edit.  :-) */
  if (update)
    {
      svn_ra_session_t *ra_session;
      const char *URL;
      svn_node_kind_t kind;
      svn_boolean_t server_supports_depth;

      /* Get full URL from the ANCHOR. */
      if (! entry)
        SVN_ERR(svn_wc__entry_versioned(&entry, anchor, anchor_access, FALSE,
                                        pool));
      if (! entry->url)
        return svn_error_createf
          (SVN_ERR_ENTRY_MISSING_URL, NULL,
           _("Entry '%s' has no URL"),
           svn_path_local_style(anchor, pool));
      URL = apr_pstrdup(pool, entry->url);

      /* Open a repository session to the URL. */
      SVN_ERR(svn_client__open_ra_session_internal(&ra_session, URL, anchor,
                                                   anchor_access, NULL,
                                                   FALSE, TRUE,
                                                   ctx, pool));

      /* Verify that URL exists in HEAD.  If it doesn't, this can save
         us a whole lot of hassle; if it does, the cost of this
         request should be minimal compared to the size of getting
         back the average amount of "out-of-date" information. */
      SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM,
                                &kind, pool));
      if (kind == svn_node_none)
        {
          /* Our status target does not exist in HEAD of the
             repository.  If we're just adding this thing, that's
             fine.  But if it was previously versioned, then it must
             have been deleted from the repository. */
          if (entry->schedule != svn_wc_schedule_add)
            sb.deleted_in_repos = TRUE;

          /* And now close the edit. */
          SVN_ERR(editor->close_edit(edit_baton, pool));
        }
      else
        {
          svn_revnum_t revnum;
          report_baton_t rb;

          if (revision->kind == svn_opt_revision_head)
            {
              /* Cause the revision number to be omitted from the request,
                 which implies HEAD. */
              revnum = SVN_INVALID_REVNUM;
            }
          else
            {
              /* Get a revision number for our status operation. */
              SVN_ERR(svn_client__get_revision_number
                      (&revnum, NULL, ra_session, revision, target, pool));
            }

          /* Do the deed.  Let the RA layer drive the status editor. */
          SVN_ERR(svn_ra_do_status2(ra_session, &rb.wrapped_reporter,
                                    &rb.wrapped_report_baton,
                                    target, revnum, depth, editor,
                                    edit_baton, pool));

          /* Init the report baton. */
          rb.ancestor = apr_pstrdup(pool, URL);
          rb.set_locks_baton = set_locks_baton;
          rb.ctx = ctx;
          rb.pool = pool;

          SVN_ERR(svn_ra_has_capability(ra_session, &server_supports_depth,
                                        SVN_RA_CAPABILITY_DEPTH, pool));

          /* Drive the reporter structure, describing the revisions
             within PATH.  When we call reporter->finish_report,
             EDITOR will be driven to describe differences between our
             working copy and HEAD. */
          SVN_ERR(svn_wc_crawl_revisions4(path, target_access,
                                          &lock_fetch_reporter, &rb, FALSE,
                                          depth, TRUE, (! server_supports_depth),
                                          FALSE, NULL, NULL, NULL, pool));
        }
    }
  else
    {
      SVN_ERR(editor->close_edit(edit_baton, pool));
    }

  if (ctx->notify_func2 && update)
    {
      svn_wc_notify_t *notify
        = svn_wc_create_notify(path, svn_wc_notify_status_completed, pool);
      notify->revision = edit_revision;
      (ctx->notify_func2)(ctx->notify_baton2, notify, pool);
    }

  /* If the caller wants the result revision, give it to them. */
  if (result_rev)
    *result_rev = edit_revision;

  /* Close the access baton here, as svn_client__do_external_status()
     calls back into this function and thus will be re-opening the
     working copy. */
  SVN_ERR(svn_wc_adm_close2(anchor_access, pool));

  /* If there are svn:externals set, we don't want those to show up as
     unversioned or unrecognized, so patch up the hash.  If caller wants
     all the statuses, we will change unversioned status items that
     are interesting to an svn:externals property to
     svn_wc_status_unversioned, otherwise we'll just remove the status
     item altogether.

     We only descend into an external if depth is svn_depth_infinity or
     svn_depth_unknown.  However, there are conceivable behaviors that
     would involve descending under other circumstances; thus, we pass
     depth anyway, so the code will DTRT if we change the conditional
     in the future.
  */
  if (SVN_DEPTH_IS_RECURSIVE(depth) && (! ignore_externals))
    SVN_ERR(svn_client__do_external_status(traversal_info, status_func,
                                           status_baton, depth, get_all,
                                           update, no_ignore, ctx, pool));

  return SVN_NO_ERROR;
}
コード例 #9
0
ファイル: entries-dump.c プロジェクト: gunjanms/svnmigration
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;
}