Skip to content

Commit 8c1afdd

Browse files
committed
svnbrowse: Use libsvn_ra API directly to query directories. Do so for improved
performance (by reusing the same session) and more control of what is actually transmitted over the wire. * subversion/svnbrowse/svnbrowse.c (includes): Add svn_ra.h. (svn_browse__state_t): Change abspath to relpath and the revision is now just a number. Although most of the logic just ignore it for now. (svn_browse__model_t): Store ra_session and change how we store revision. (list_cb): Implement svn_ra_dirent_receiver_t instead of svn_client_list_func2_t. Take basename of relpath when processing it. (state_create): Change the API used to back the operation. (enter_path): Update state_create() invokation and change abspath back to relpath. (model_create): Ask for a numeric revision and add code to initialize ra_session. (view_draw): Add back the logic that combines root and relpath for the header. (sub_main): Use numeric revisions and treat current path of browser as a relative path. git-svn-id: https://svn.apache.org/repos/asf/subversion/trunk@1932742 13f79535-47bb-0310-9956-ffa450edef68
1 parent c0b7320 commit 8c1afdd

1 file changed

Lines changed: 38 additions & 31 deletions

File tree

subversion/svnbrowse/svnbrowse.c

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "svn_client.h"
2828
#include "svn_opt.h"
29+
#include "svn_ra.h"
2930
#include "svn_path.h"
3031
#include "svn_pools.h"
3132
#include "svn_cmdline.h"
@@ -45,8 +46,8 @@ typedef struct svn_browse__item_t {
4546
/* a state of a single directory */
4647
typedef struct svn_browse__state_t {
4748
/* information about this node */
48-
const char *abspath;
49-
svn_opt_revision_t revision;
49+
const char *relpath;
50+
svn_revnum_t revision;
5051

5152
/* stores the list of nodes in this state; an array of svn_browse__item_t */
5253
apr_array_header_t *list;
@@ -60,64 +61,66 @@ typedef struct svn_browse__state_t {
6061

6162
typedef struct svn_browse__model_t {
6263
const char *root;
63-
svn_opt_revision_t revision;
64+
svn_revnum_t revision;
6465

6566
svn_client_ctx_t *client;
67+
svn_ra_session_t *session;
6668

6769
svn_browse__state_t *current;
6870
apr_pool_t *pool;
6971
} svn_browse__model_t;
7072

7173
static svn_error_t *
72-
list_cb(void *baton,
73-
const char *path,
74-
const svn_dirent_t *dirent,
75-
const svn_lock_t *lock,
76-
const char *abs_path,
77-
const char *external_parent_url,
78-
const char *external_target,
74+
list_cb(const char *relpath,
75+
svn_dirent_t *dirent,
76+
void *baton,
7977
apr_pool_t *scratch_pool)
8078
{
8179
svn_browse__state_t *state = baton;
8280
svn_browse__item_t *item = apr_pcalloc(state->pool, sizeof(*item));
83-
item->relpath = apr_pstrdup(state->pool, path);
81+
item->relpath = svn_dirent_basename(relpath, state->pool);
8482
item->dirent = svn_dirent_dup(dirent, state->pool);
8583
APR_ARRAY_PUSH(state->list, svn_browse__item_t *) = item;
8684
return SVN_NO_ERROR;
8785
}
8886

8987
static svn_error_t *
9088
state_create(svn_browse__state_t **state_p,
91-
svn_client_ctx_t *ctx,
92-
const char *url,
93-
svn_opt_revision_t *revision,
89+
svn_ra_session_t *session,
90+
const char *relpath,
91+
svn_revnum_t revision,
9492
apr_pool_t *result_pool,
9593
apr_pool_t *scratch_pool)
9694
{
9795
svn_browse__state_t *state = apr_pcalloc(result_pool, sizeof(*state));
96+
svn_revnum_t revnum;
9897

99-
state->abspath = apr_pstrdup(result_pool, url);
98+
state->relpath = apr_pstrdup(result_pool, relpath);
10099
state->revision = state->revision;
101100
state->list = apr_array_make(result_pool, 0, sizeof(svn_browse__item_t *));
102101
state->selection = 0;
103102
state->pool = result_pool;
104103

105-
SVN_ERR(svn_client_list4(url, revision, revision, NULL, svn_depth_immediates,
106-
SVN_DIRENT_ALL, TRUE, TRUE, list_cb, state, ctx,
107-
scratch_pool));
104+
/* TODO: use svn_ra_get_dir2() as it automatically treats SVN_INVALID_REVNUM
105+
* as HEAD and returns a list directly. */
106+
107+
SVN_ERR(svn_ra_get_latest_revnum(session, &revnum, scratch_pool));
108+
109+
SVN_ERR(svn_ra_list(session, relpath, revnum, NULL, svn_depth_immediates,
110+
SVN_DIRENT_ALL, list_cb, state, scratch_pool));
108111

109112
*state_p = state;
110113
return SVN_NO_ERROR;
111114
}
112115

113116
static svn_error_t *
114-
enter_path(svn_browse__model_t *ctx, const char *abspath,
117+
enter_path(svn_browse__model_t *ctx, const char *relpath,
115118
apr_pool_t *scratch_pool)
116119
{
117120
svn_browse__state_t *newstate;
118121
apr_pool_t *state_pool = svn_pool_create(ctx->pool);
119122

120-
SVN_ERR(state_create(&newstate, ctx->client, abspath, &ctx->revision,
123+
SVN_ERR(state_create(&newstate, ctx->session, relpath, ctx->revision,
121124
state_pool, scratch_pool));
122125

123126
/* switch to the next state and nuke the previous one */
@@ -130,13 +133,14 @@ enter_path(svn_browse__model_t *ctx, const char *abspath,
130133
static svn_error_t *
131134
model_create(svn_browse__model_t **model_p,
132135
const char *url,
133-
svn_opt_revision_t revision,
136+
svn_revnum_t revision,
134137
apr_pool_t *result_pool,
135138
apr_pool_t *scratch_pool)
136139
{
137140
svn_browse__model_t *model = apr_pcalloc(result_pool, sizeof(*model));
138141
svn_auth_baton_t *auth;
139142
svn_client_ctx_t *client;
143+
svn_ra_session_t *session;
140144
apr_pool_t *state_pool;
141145
svn_browse__state_t *state;
142146

@@ -148,15 +152,18 @@ model_create(svn_browse__model_t **model_p,
148152
SVN_ERR(svn_client_create_context2(&client, NULL, result_pool));
149153
client->auth_baton = auth;
150154

155+
SVN_ERR(svn_client_open_ra_session2(&session, url, NULL, client, result_pool,
156+
scratch_pool));
157+
151158
/* the state should be in a separate pool so it's safe to free it */
152159
state_pool = svn_pool_create(result_pool);
153-
SVN_ERR(state_create(&state, client, url, &revision, state_pool,
160+
SVN_ERR(state_create(&state, session, "", revision, state_pool,
154161
scratch_pool));
155-
156162
/* TODO: we must use the repository root URL */
157-
model->root = apr_pstrdup(result_pool, url);
163+
SVN_ERR(svn_ra_get_session_url(session, &model->root, result_pool));
158164
model->revision = revision;
159165
model->client = client;
166+
model->session = session;
160167
model->current = state;
161168
model->pool = result_pool;
162169

@@ -181,8 +188,10 @@ static void
181188
view_draw(svn_browse__view_t *view, apr_pool_t *pool)
182189
{
183190
int i;
191+
const char *abspath = svn_path_url_add_component2(
192+
view->model->root, view->model->current->relpath, pool);
184193

185-
mvprintw(0, 4, "Browsing: %s", view->model->current->abspath);
194+
mvprintw(0, 4, "Browsing: %s", abspath);
186195

187196
for (i = 0; i < view->model->current->list->nelts; i++)
188197
{
@@ -215,7 +224,6 @@ static svn_error_t *
215224
sub_main(int *code, int argc, char *argv[], apr_pool_t *pool)
216225
{
217226
const char *url;
218-
svn_opt_revision_t revision;
219227
svn_browse__model_t *ctx;
220228
svn_browse__view_t *view;
221229
apr_pool_t *iterpool;
@@ -225,9 +233,8 @@ sub_main(int *code, int argc, char *argv[], apr_pool_t *pool)
225233
"usage: svnbrowse <URL>");
226234

227235
SVN_ERR(svn_uri_canonicalize_safe(&url, NULL, argv[1], pool, pool));
228-
revision.kind = svn_opt_revision_head;
229236

230-
SVN_ERR(model_create(&ctx, url, revision, pool, pool));
237+
SVN_ERR(model_create(&ctx, url, SVN_INVALID_REVNUM, pool, pool));
231238

232239
/* init the display */
233240
initscr();
@@ -275,14 +282,14 @@ sub_main(int *code, int argc, char *argv[], apr_pool_t *pool)
275282
case '\r':
276283
item = APR_ARRAY_IDX(ctx->current->list, ctx->current->selection,
277284
svn_browse__item_t *);
278-
new_url = svn_path_url_add_component2(ctx->current->abspath,
279-
item->relpath, iterpool);
285+
new_url = svn_relpath_join(ctx->current->relpath, item->relpath,
286+
iterpool);
280287
SVN_ERR(enter_path(ctx, new_url, iterpool));
281288
break;
282289
case KEY_BACKSPACE:
283290
case '-':
284291
case 'u':
285-
new_url = svn_uri_dirname(ctx->current->abspath, iterpool);
292+
new_url = svn_relpath_dirname(ctx->current->relpath, iterpool);
286293
SVN_ERR(enter_path(ctx, new_url, iterpool));
287294
break;
288295
/* TODO: quit via escape. some say just check for 27, but it I think it's

0 commit comments

Comments
 (0)