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 <avarab@gmail.com> Signed-off-by: Teng Long <dyroneteng@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ævar Arnfjörð Bjarmason committed
Mar 23, 2022 at 17:13 UTC
9c4d58ff2c385f49585197c8650356955e1fa02e
1 file changed
+125
-74
builtin/ls-tree.c
+125
-74
@@ -173,108 +173,157 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
173
return recurse;
174
}
175
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)
179
{
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;
180
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;
189
190
if (type == OBJ_BLOB) {
191
if (ls_options & LS_TREE_ONLY)
223
- return 0;
192
+ ret = 0;
193
} else if (type == OBJ_TREE &&
194
show_recursive(base->buf, base->len, pathname)) {
226
- recurse = READ_TREE_RECURSIVE;
195
+ *recurse = READ_TREE_RECURSIVE;
196
if (!(ls_options & LS_SHOW_TREES))
228
- return recurse;
197
+ ret = *recurse;
198
}
199
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
+}
202
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), "-");
253
}
254
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
+}
260
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);
293
return recurse;
294
}
295
296
struct ls_tree_cmdmode_to_fmt {
297
enum ls_tree_cmdmode mode;
298
const char *const fmt;
299
+ read_tree_fn_t fn;
300
};
301
302
static struct ls_tree_cmdmode_to_fmt ls_tree_cmdmode_format[] = {
303
{
304
.mode = MODE_DEFAULT,
305
.fmt = "%(objectmode) %(objecttype) %(objectname)%x09%(path)",
306
+ .fn = show_tree_default,
307
},
308
{
309
.mode = MODE_LONG,
310
.fmt = "%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)",
311
+ .fn = show_tree_long,
312
},
313
{
314
.mode = MODE_NAME_ONLY, /* And MODE_NAME_STATUS */
315
.fmt = "%(path)",
316
+ .fn = show_tree_name_only,
317
},
318
{
319
.mode = MODE_OBJECT_ONLY,
320
.fmt = "%(objectname)",
321
+ .fn = show_tree_object
322
+ },
323
+ {
324
+ /* fallback */
325
+ .fn = show_tree_default,
326
},
277
- { 0 },
327
};
328
329
int cmd_ls_tree(int argc, const char **argv, const char *prefix)
@@ -282,7 +331,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
331
struct object_id oid;
332
struct tree *tree;
333
int i, full_tree = 0;
285
- read_tree_fn_t fn = show_tree;
334
+ read_tree_fn_t fn = NULL;
335
const struct option ls_tree_options[] = {
336
OPT_BIT('d', NULL, &ls_options, N_("only show trees"),
337
LS_TREE_ONLY),
@@ -311,6 +360,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
360
OPT__ABBREV(&abbrev),
361
OPT_END()
362
};
363
+ struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
364
365
git_config(git_default_config, NULL);
366
ls_tree_prefix = prefix;
@@ -365,18 +415,19 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
415
* The generic show_tree_fmt() is slower than show_tree(), so
416
* take the fast path if possible.
417
*/
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)) {
422
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;
429
}
430
+ break;
431
}
432
433
return !!read_tree(the_repository, tree, &pathspec, fn, NULL);