diff options
Diffstat (limited to 'subversion/tests/cmdline/entries-dump.c')
-rw-r--r-- | subversion/tests/cmdline/entries-dump.c | 140 |
1 files changed, 121 insertions, 19 deletions
diff --git a/subversion/tests/cmdline/entries-dump.c b/subversion/tests/cmdline/entries-dump.c index d508a95..e4edc61 100644 --- a/subversion/tests/cmdline/entries-dump.c +++ b/subversion/tests/cmdline/entries-dump.c @@ -30,6 +30,7 @@ #define SVN_DEPRECATED #include "svn_types.h" +#include "svn_cmdline.h" #include "svn_pools.h" #include "svn_wc.h" #include "svn_dirent_uri.h" @@ -37,6 +38,7 @@ #include "private/svn_wc_private.h" #include "../../libsvn_wc/wc.h" +#include "../../libsvn_wc/lock.h" static void str_value(const char *name, const char *value) @@ -65,24 +67,46 @@ bool_value(const char *name, svn_boolean_t value) } static svn_error_t * -entries_dump(const char *dir_path, apr_pool_t *pool) +entries_dump(const char *dir_path, svn_wc_adm_access_t *related, apr_pool_t *pool) { - svn_wc_adm_access_t *adm_access; + 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, NULL, dir_path, FALSE, 0, + err = svn_wc_adm_open3(&adm_access, related, dir_path, FALSE, 0, NULL, NULL, pool); if (!err) { - SVN_ERR(svn_wc_locked(&locked, dir_path, pool)); + 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 *dir_abspath, *lockfile_path; + const char *lockfile_path; svn_node_kind_t kind; /* ### Should svn_wc_adm_open3 be returning UPGRADE_REQUIRED? */ @@ -101,12 +125,8 @@ entries_dump(const char *dir_path, apr_pool_t *pool) for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi)) { - const void *key; - void *value; - const svn_wc_entry_t *entry; - - apr_hash_this(hi, &key, NULL, &value); - entry = value; + const char *key = svn__apr_hash_index_key(hi); + const svn_wc_entry_t *entry = svn__apr_hash_index_val(hi); SVN_ERR_ASSERT(strcmp(key, entry->name) == 0); @@ -147,13 +167,16 @@ entries_dump(const char *dir_path, apr_pool_t *pool) /* skip: keep_local */ int_value("depth", entry->depth); /* skip: tree_conflict_data */ - /* skip: file_external_path */ + 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)); @@ -167,6 +190,7 @@ struct directory_walk_baton svn_wc_context_t *wc_ctx; const char *root_abspath; const char *prefix_path; + svn_wc_adm_access_t *adm_access; }; /* svn_wc__node_found_func_t implementation for directory_dump */ @@ -251,6 +275,81 @@ directory_dump(const char *path, return svn_error_trace(svn_wc_context_destroy(bt.wc_ctx)); } +static svn_error_t * +tree_dump_dir(const char *local_abspath, + svn_node_kind_t kind, + void *walk_baton, + apr_pool_t *scratch_pool) +{ + struct directory_walk_baton *bt = walk_baton; + const char *path; + + if (kind != svn_node_dir) + return SVN_NO_ERROR; + + /* If LOCAL_ABSPATH a child of or equal to ROOT_ABSPATH, then display + a relative path starting with PREFIX_PATH. */ + path = svn_dirent_skip_ancestor(bt->root_abspath, local_abspath); + if (path) + path = svn_dirent_join(bt->prefix_path, path, scratch_pool); + else + path = local_abspath; + + printf("entries = {}\n"); + SVN_ERR(entries_dump(path, bt->adm_access, scratch_pool)); + + printf("dirs['%s'] = entries\n", path); + return SVN_NO_ERROR; + +} + +static svn_error_t * +tree_dump_txn(void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool) +{ + struct directory_walk_baton *bt = baton; + + SVN_ERR(svn_wc__internal_walk_children(bt->wc_ctx->db, bt->root_abspath, FALSE, + NULL, tree_dump_dir, bt, + svn_depth_infinity, + NULL, NULL, scratch_pool)); + + return SVN_NO_ERROR; +} + +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_ERR(svn_sqlite__with_lock(sdb, tree_dump_txn, &bt, scratch_pool)); + + /* 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; +} + int main(int argc, const char *argv[]) { @@ -262,18 +361,19 @@ main(int argc, const char *argv[]) if (argc < 2 || argc > 4) { - fprintf(stderr, "USAGE: entries-dump [--entries|--subdirs] DIR_PATH\n"); + fprintf(stderr, "USAGE: entries-dump [--entries|--subdirs|--tree-dump] DIR_PATH\n"); exit(1); } - if (apr_initialize() != APR_SUCCESS) + if (svn_cmdline_init("entries-dump", stderr) != EXIT_SUCCESS) { - fprintf(stderr, "apr_initialize() failed.\n"); - exit(1); + return EXIT_FAILURE; } - /* set up the global pool */ - pool = svn_pool_create(NULL); + /* Create our top-level pool. Use a separate mutexless allocator, + * given this application is single threaded. + */ + pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE)); path = svn_dirent_internal_style(argv[argc-1], pool); @@ -283,9 +383,11 @@ main(int argc, const char *argv[]) cmd = NULL; if (!cmd || !strcmp(cmd, "--entries")) - err = entries_dump(path, pool); + err = entries_dump(path, NULL, pool); else if (!strcmp(cmd, "--subdirs")) err = directory_dump(path, pool); + else if (!strcmp(cmd, "--tree-dump")) + err = tree_dump(path, pool); else err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, "Invalid command '%s'", |