Skip to content

Commit 9c4d58f

Browse files
avargitster
authored andcommitted
ls-tree: split up "fast path" callbacks
Make the various if/else in the callbacks for the "fast path" a lot easier to read by just using common functions for the parts that are common, and have per-format callbacks for those parts that are different. Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Teng Long <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0f88783 commit 9c4d58f

File tree

1 file changed

+125
-74
lines changed

1 file changed

+125
-74
lines changed

builtin/ls-tree.c

Lines changed: 125 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -173,116 +173,165 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
173173
return recurse;
174174
}
175175

176-
static int show_default(struct show_tree_data *data)
176+
static int show_tree_common(struct show_tree_data *data, int *recurse,
177+
const struct object_id *oid, struct strbuf *base,
178+
const char *pathname, unsigned mode)
177179
{
178-
size_t baselen = data->base->len;
179-
180-
if (cmdmode == MODE_LONG) {
181-
char size_text[24];
182-
if (data->type == OBJ_BLOB) {
183-
unsigned long size;
184-
if (oid_object_info(the_repository, data->oid, &size) == OBJ_BAD)
185-
xsnprintf(size_text, sizeof(size_text), "BAD");
186-
else
187-
xsnprintf(size_text, sizeof(size_text),
188-
"%" PRIuMAX, (uintmax_t)size);
189-
} else {
190-
xsnprintf(size_text, sizeof(size_text), "-");
191-
}
192-
printf("%06o %s %s %7s\t", data->mode, type_name(data->type),
193-
find_unique_abbrev(data->oid, abbrev), size_text);
194-
} else {
195-
printf("%06o %s %s\t", data->mode, type_name(data->type),
196-
find_unique_abbrev(data->oid, abbrev));
197-
}
198-
baselen = data->base->len;
199-
strbuf_addstr(data->base, data->pathname);
200-
write_name_quoted_relative(data->base->buf,
201-
chomp_prefix ? ls_tree_prefix : NULL, stdout,
202-
line_termination);
203-
strbuf_setlen(data->base, baselen);
204-
return 1;
205-
}
206-
207-
static int show_tree(const struct object_id *oid, struct strbuf *base,
208-
const char *pathname, unsigned mode, void *context)
209-
{
210-
int recurse = 0;
211-
size_t baselen;
212180
enum object_type type = object_type(mode);
213-
struct show_tree_data data = {
214-
.mode = mode,
215-
.type = type,
216-
.oid = oid,
217-
.pathname = pathname,
218-
.base = base,
219-
};
181+
int ret = -1;
182+
183+
*recurse = 0;
184+
data->mode = mode;
185+
data->type = type;
186+
data->oid = oid;
187+
data->pathname = pathname;
188+
data->base = base;
220189

221190
if (type == OBJ_BLOB) {
222191
if (ls_options & LS_TREE_ONLY)
223-
return 0;
192+
ret = 0;
224193
} else if (type == OBJ_TREE &&
225194
show_recursive(base->buf, base->len, pathname)) {
226-
recurse = READ_TREE_RECURSIVE;
195+
*recurse = READ_TREE_RECURSIVE;
227196
if (!(ls_options & LS_SHOW_TREES))
228-
return recurse;
197+
ret = *recurse;
229198
}
230199

231-
if (cmdmode == MODE_OBJECT_ONLY) {
232-
printf("%s%c", find_unique_abbrev(oid, abbrev), line_termination);
233-
return recurse;
234-
}
200+
return ret;
201+
}
235202

236-
if (cmdmode == MODE_NAME_ONLY) {
237-
baselen = base->len;
238-
strbuf_addstr(base, pathname);
239-
write_name_quoted_relative(base->buf,
240-
chomp_prefix ? ls_tree_prefix : NULL,
241-
stdout, line_termination);
242-
strbuf_setlen(base, baselen);
243-
return recurse;
203+
static void show_tree_common_default_long(struct strbuf *base,
204+
const char *pathname,
205+
const size_t baselen)
206+
{
207+
strbuf_addstr(base, pathname);
208+
write_name_quoted_relative(base->buf,
209+
chomp_prefix ? ls_tree_prefix : NULL, stdout,
210+
line_termination);
211+
strbuf_setlen(base, baselen);
212+
}
213+
214+
static int show_tree_default(const struct object_id *oid, struct strbuf *base,
215+
const char *pathname, unsigned mode,
216+
void *context)
217+
{
218+
int early;
219+
int recurse;
220+
struct show_tree_data data = { 0 };
221+
222+
early = show_tree_common(&data, &recurse, oid, base, pathname, mode);
223+
if (early >= 0)
224+
return early;
225+
226+
printf("%06o %s %s\t", data.mode, type_name(data.type),
227+
find_unique_abbrev(data.oid, abbrev));
228+
show_tree_common_default_long(base, pathname, data.base->len);
229+
return recurse;
230+
}
231+
232+
static int show_tree_long(const struct object_id *oid, struct strbuf *base,
233+
const char *pathname, unsigned mode, void *context)
234+
{
235+
int early;
236+
int recurse;
237+
struct show_tree_data data = { 0 };
238+
char size_text[24];
239+
240+
early = show_tree_common(&data, &recurse, oid, base, pathname, mode);
241+
if (early >= 0)
242+
return early;
243+
244+
if (data.type == OBJ_BLOB) {
245+
unsigned long size;
246+
if (oid_object_info(the_repository, data.oid, &size) == OBJ_BAD)
247+
xsnprintf(size_text, sizeof(size_text), "BAD");
248+
else
249+
xsnprintf(size_text, sizeof(size_text),
250+
"%" PRIuMAX, (uintmax_t)size);
251+
} else {
252+
xsnprintf(size_text, sizeof(size_text), "-");
244253
}
245254

246-
if (cmdmode == MODE_LONG ||
247-
(!ls_options || (ls_options & LS_RECURSIVE)
248-
|| (ls_options & LS_SHOW_TREES)
249-
|| (ls_options & LS_TREE_ONLY)))
250-
show_default(&data);
255+
printf("%06o %s %s %7s\t", data.mode, type_name(data.type),
256+
find_unique_abbrev(data.oid, abbrev), size_text);
257+
show_tree_common_default_long(base, pathname, data.base->len);
258+
return 1;
259+
}
251260

261+
static int show_tree_name_only(const struct object_id *oid, struct strbuf *base,
262+
const char *pathname, unsigned mode, void *context)
263+
{
264+
int early;
265+
int recurse;
266+
const size_t baselen = base->len;
267+
struct show_tree_data data = { 0 };
268+
269+
early = show_tree_common(&data, &recurse, oid, base, pathname, mode);
270+
if (early >= 0)
271+
return early;
272+
273+
strbuf_addstr(base, pathname);
274+
write_name_quoted_relative(base->buf,
275+
chomp_prefix ? ls_tree_prefix : NULL,
276+
stdout, line_termination);
277+
strbuf_setlen(base, baselen);
278+
return recurse;
279+
}
280+
281+
static int show_tree_object(const struct object_id *oid, struct strbuf *base,
282+
const char *pathname, unsigned mode, void *context)
283+
{
284+
int early;
285+
int recurse;
286+
struct show_tree_data data = { 0 };
287+
288+
early = show_tree_common(&data, &recurse, oid, base, pathname, mode);
289+
if (early >= 0)
290+
return early;
291+
292+
printf("%s%c", find_unique_abbrev(oid, abbrev), line_termination);
252293
return recurse;
253294
}
254295

255296
struct ls_tree_cmdmode_to_fmt {
256297
enum ls_tree_cmdmode mode;
257298
const char *const fmt;
299+
read_tree_fn_t fn;
258300
};
259301

260302
static struct ls_tree_cmdmode_to_fmt ls_tree_cmdmode_format[] = {
261303
{
262304
.mode = MODE_DEFAULT,
263305
.fmt = "%(objectmode) %(objecttype) %(objectname)%x09%(path)",
306+
.fn = show_tree_default,
264307
},
265308
{
266309
.mode = MODE_LONG,
267310
.fmt = "%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)",
311+
.fn = show_tree_long,
268312
},
269313
{
270314
.mode = MODE_NAME_ONLY, /* And MODE_NAME_STATUS */
271315
.fmt = "%(path)",
316+
.fn = show_tree_name_only,
272317
},
273318
{
274319
.mode = MODE_OBJECT_ONLY,
275320
.fmt = "%(objectname)",
321+
.fn = show_tree_object
322+
},
323+
{
324+
/* fallback */
325+
.fn = show_tree_default,
276326
},
277-
{ 0 },
278327
};
279328

280329
int cmd_ls_tree(int argc, const char **argv, const char *prefix)
281330
{
282331
struct object_id oid;
283332
struct tree *tree;
284333
int i, full_tree = 0;
285-
read_tree_fn_t fn = show_tree;
334+
read_tree_fn_t fn = NULL;
286335
const struct option ls_tree_options[] = {
287336
OPT_BIT('d', NULL, &ls_options, N_("only show trees"),
288337
LS_TREE_ONLY),
@@ -311,6 +360,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
311360
OPT__ABBREV(&abbrev),
312361
OPT_END()
313362
};
363+
struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
314364

315365
git_config(git_default_config, NULL);
316366
ls_tree_prefix = prefix;
@@ -365,18 +415,19 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
365415
* The generic show_tree_fmt() is slower than show_tree(), so
366416
* take the fast path if possible.
367417
*/
368-
if (format) {
369-
struct ls_tree_cmdmode_to_fmt *m2f;
370-
371-
fn = show_tree_fmt;
372-
for (m2f = ls_tree_cmdmode_format; m2f->fmt; m2f++) {
373-
if (strcmp(format, m2f->fmt))
374-
continue;
375-
418+
while (m2f) {
419+
if (!m2f->fmt) {
420+
fn = format ? show_tree_fmt : show_tree_default;
421+
} else if (format && !strcmp(format, m2f->fmt)) {
376422
cmdmode = m2f->mode;
377-
fn = show_tree;
378-
break;
423+
fn = m2f->fn;
424+
} else if (!format && cmdmode == m2f->mode) {
425+
fn = m2f->fn;
426+
} else {
427+
m2f++;
428+
continue;
379429
}
430+
break;
380431
}
381432

382433
return !!read_tree(the_repository, tree, &pathspec, fn, NULL);

0 commit comments

Comments
 (0)