doc: remove manpage-base-url workaround
[git.git] / builtin / ls-tree.c
blob64d8e54318c97ee8b9e74afdcc5a9607bf6f4325
1 /*
2 * GIT - The information manager from hell
4 * Copyright (C) Linus Torvalds, 2005
5 */
6 #include "cache.h"
7 #include "config.h"
8 #include "hex.h"
9 #include "object-store.h"
10 #include "blob.h"
11 #include "tree.h"
12 #include "commit.h"
13 #include "quote.h"
14 #include "builtin.h"
15 #include "parse-options.h"
16 #include "pathspec.h"
18 static const char * const ls_tree_usage[] = {
19 N_("git ls-tree [<options>] <tree-ish> [<path>...]"),
20 NULL
23 static void expand_objectsize(struct strbuf *line, const struct object_id *oid,
24 const enum object_type type, unsigned int padded)
26 if (type == OBJ_BLOB) {
27 unsigned long size;
28 if (oid_object_info(the_repository, oid, &size) < 0)
29 die(_("could not get object info about '%s'"),
30 oid_to_hex(oid));
31 if (padded)
32 strbuf_addf(line, "%7"PRIuMAX, (uintmax_t)size);
33 else
34 strbuf_addf(line, "%"PRIuMAX, (uintmax_t)size);
35 } else if (padded) {
36 strbuf_addf(line, "%7s", "-");
37 } else {
38 strbuf_addstr(line, "-");
42 struct ls_tree_options {
43 unsigned null_termination:1;
44 int abbrev;
45 enum ls_tree_path_options {
46 LS_RECURSIVE = 1 << 0,
47 LS_TREE_ONLY = 1 << 1,
48 LS_SHOW_TREES = 1 << 2,
49 } ls_options;
50 struct pathspec pathspec;
51 int chomp_prefix;
52 const char *ls_tree_prefix;
53 const char *format;
56 struct show_tree_data {
57 struct ls_tree_options *options;
58 unsigned mode;
59 enum object_type type;
60 const struct object_id *oid;
61 const char *pathname;
62 struct strbuf *base;
65 static size_t expand_show_tree(struct strbuf *sb, const char *start,
66 void *context)
68 struct show_tree_data *data = context;
69 struct ls_tree_options *options = data->options;
70 const char *end;
71 const char *p;
72 unsigned int errlen;
73 size_t len = strbuf_expand_literal_cb(sb, start, NULL);
75 if (len)
76 return len;
77 if (*start != '(')
78 die(_("bad ls-tree format: element '%s' does not start with '('"), start);
80 end = strchr(start + 1, ')');
81 if (!end)
82 die(_("bad ls-tree format: element '%s' does not end in ')'"), start);
84 len = end - start + 1;
85 if (skip_prefix(start, "(objectmode)", &p)) {
86 strbuf_addf(sb, "%06o", data->mode);
87 } else if (skip_prefix(start, "(objecttype)", &p)) {
88 strbuf_addstr(sb, type_name(data->type));
89 } else if (skip_prefix(start, "(objectsize:padded)", &p)) {
90 expand_objectsize(sb, data->oid, data->type, 1);
91 } else if (skip_prefix(start, "(objectsize)", &p)) {
92 expand_objectsize(sb, data->oid, data->type, 0);
93 } else if (skip_prefix(start, "(objectname)", &p)) {
94 strbuf_add_unique_abbrev(sb, data->oid, options->abbrev);
95 } else if (skip_prefix(start, "(path)", &p)) {
96 const char *name = data->base->buf;
97 const char *prefix = options->chomp_prefix ? options->ls_tree_prefix : NULL;
98 struct strbuf sbuf = STRBUF_INIT;
99 size_t baselen = data->base->len;
101 strbuf_addstr(data->base, data->pathname);
102 name = relative_path(data->base->buf, prefix, &sbuf);
103 quote_c_style(name, sb, NULL, 0);
104 strbuf_setlen(data->base, baselen);
105 strbuf_release(&sbuf);
106 } else {
107 errlen = (unsigned long)len;
108 die(_("bad ls-tree format: %%%.*s"), errlen, start);
110 return len;
113 static int show_recursive(struct ls_tree_options *options, const char *base,
114 size_t baselen, const char *pathname)
116 int i;
118 if (options->ls_options & LS_RECURSIVE)
119 return 1;
121 if (!options->pathspec.nr)
122 return 0;
124 for (i = 0; i < options->pathspec.nr; i++) {
125 const char *spec = options->pathspec.items[i].match;
126 size_t len, speclen;
128 if (strncmp(base, spec, baselen))
129 continue;
130 len = strlen(pathname);
131 spec += baselen;
132 speclen = strlen(spec);
133 if (speclen <= len)
134 continue;
135 if (spec[len] && spec[len] != '/')
136 continue;
137 if (memcmp(pathname, spec, len))
138 continue;
139 return 1;
141 return 0;
144 static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
145 const char *pathname, unsigned mode, void *context)
147 struct ls_tree_options *options = context;
148 int recurse = 0;
149 struct strbuf sb = STRBUF_INIT;
150 enum object_type type = object_type(mode);
151 struct show_tree_data cb_data = {
152 .options = options,
153 .mode = mode,
154 .type = type,
155 .oid = oid,
156 .pathname = pathname,
157 .base = base,
160 if (type == OBJ_TREE && show_recursive(options, base->buf, base->len, pathname))
161 recurse = READ_TREE_RECURSIVE;
162 if (type == OBJ_TREE && recurse && !(options->ls_options & LS_SHOW_TREES))
163 return recurse;
164 if (type == OBJ_BLOB && (options->ls_options & LS_TREE_ONLY))
165 return 0;
167 strbuf_expand(&sb, options->format, expand_show_tree, &cb_data);
168 strbuf_addch(&sb, options->null_termination ? '\0' : '\n');
169 fwrite(sb.buf, sb.len, 1, stdout);
170 strbuf_release(&sb);
171 return recurse;
174 static int show_tree_common(struct ls_tree_options *options, int *recurse,
175 struct strbuf *base, const char *pathname,
176 enum object_type type)
178 int ret = -1;
179 *recurse = 0;
181 if (type == OBJ_BLOB) {
182 if (options->ls_options & LS_TREE_ONLY)
183 ret = 0;
184 } else if (type == OBJ_TREE &&
185 show_recursive(options, base->buf, base->len, pathname)) {
186 *recurse = READ_TREE_RECURSIVE;
187 if (!(options->ls_options & LS_SHOW_TREES))
188 ret = *recurse;
191 return ret;
194 static void show_tree_common_default_long(struct ls_tree_options *options,
195 struct strbuf *base,
196 const char *pathname,
197 const size_t baselen)
199 const char *prefix = options->chomp_prefix ? options->ls_tree_prefix : NULL;
201 strbuf_addstr(base, pathname);
203 if (options->null_termination) {
204 struct strbuf sb = STRBUF_INIT;
205 const char *name = relative_path(base->buf, prefix, &sb);
207 fputs(name, stdout);
208 fputc('\0', stdout);
210 strbuf_release(&sb);
211 } else {
212 write_name_quoted_relative(base->buf, prefix, stdout, '\n');
215 strbuf_setlen(base, baselen);
218 static int show_tree_default(const struct object_id *oid, struct strbuf *base,
219 const char *pathname, unsigned mode,
220 void *context)
222 struct ls_tree_options *options = context;
223 int early;
224 int recurse;
225 enum object_type type = object_type(mode);
227 early = show_tree_common(options, &recurse, base, pathname, type);
228 if (early >= 0)
229 return early;
231 printf("%06o %s %s\t", mode, type_name(object_type(mode)),
232 find_unique_abbrev(oid, options->abbrev));
233 show_tree_common_default_long(options, base, pathname, base->len);
234 return recurse;
237 static int show_tree_long(const struct object_id *oid, struct strbuf *base,
238 const char *pathname, unsigned mode,
239 void *context)
241 struct ls_tree_options *options = context;
242 int early;
243 int recurse;
244 char size_text[24];
245 enum object_type type = object_type(mode);
247 early = show_tree_common(options, &recurse, base, pathname, type);
248 if (early >= 0)
249 return early;
251 if (type == OBJ_BLOB) {
252 unsigned long size;
253 if (oid_object_info(the_repository, oid, &size) == OBJ_BAD)
254 xsnprintf(size_text, sizeof(size_text), "BAD");
255 else
256 xsnprintf(size_text, sizeof(size_text),
257 "%" PRIuMAX, (uintmax_t)size);
258 } else {
259 xsnprintf(size_text, sizeof(size_text), "-");
262 printf("%06o %s %s %7s\t", mode, type_name(type),
263 find_unique_abbrev(oid, options->abbrev), size_text);
264 show_tree_common_default_long(options, base, pathname, base->len);
265 return recurse;
268 static int show_tree_name_only(const struct object_id *oid, struct strbuf *base,
269 const char *pathname, unsigned mode,
270 void *context)
272 struct ls_tree_options *options = context;
273 int early;
274 int recurse;
275 const size_t baselen = base->len;
276 enum object_type type = object_type(mode);
277 const char *prefix;
279 early = show_tree_common(options, &recurse, base, pathname, type);
280 if (early >= 0)
281 return early;
283 prefix = options->chomp_prefix ? options->ls_tree_prefix : NULL;
284 strbuf_addstr(base, pathname);
285 if (options->null_termination) {
286 struct strbuf sb = STRBUF_INIT;
287 const char *name = relative_path(base->buf, prefix, &sb);
289 fputs(name, stdout);
290 fputc('\0', stdout);
292 strbuf_release(&sb);
293 } else {
294 write_name_quoted_relative(base->buf, prefix, stdout, '\n');
296 strbuf_setlen(base, baselen);
297 return recurse;
300 static int show_tree_object(const struct object_id *oid, struct strbuf *base,
301 const char *pathname, unsigned mode,
302 void *context)
304 struct ls_tree_options *options = context;
305 int early;
306 int recurse;
307 enum object_type type = object_type(mode);
308 const char *str;
310 early = show_tree_common(options, &recurse, base, pathname, type);
311 if (early >= 0)
312 return early;
314 str = find_unique_abbrev(oid, options->abbrev);
315 if (options->null_termination) {
316 fputs(str, stdout);
317 fputc('\0', stdout);
318 } else {
319 puts(str);
321 return recurse;
324 enum ls_tree_cmdmode {
325 MODE_DEFAULT = 0,
326 MODE_LONG,
327 MODE_NAME_ONLY,
328 MODE_NAME_STATUS,
329 MODE_OBJECT_ONLY,
332 struct ls_tree_cmdmode_to_fmt {
333 enum ls_tree_cmdmode mode;
334 const char *const fmt;
335 read_tree_fn_t fn;
338 static struct ls_tree_cmdmode_to_fmt ls_tree_cmdmode_format[] = {
340 .mode = MODE_DEFAULT,
341 .fmt = "%(objectmode) %(objecttype) %(objectname)%x09%(path)",
342 .fn = show_tree_default,
345 .mode = MODE_LONG,
346 .fmt = "%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)",
347 .fn = show_tree_long,
350 .mode = MODE_NAME_ONLY, /* And MODE_NAME_STATUS */
351 .fmt = "%(path)",
352 .fn = show_tree_name_only,
355 .mode = MODE_OBJECT_ONLY,
356 .fmt = "%(objectname)",
357 .fn = show_tree_object
360 /* fallback */
361 .fn = show_tree_default,
365 int cmd_ls_tree(int argc, const char **argv, const char *prefix)
367 struct object_id oid;
368 struct tree *tree;
369 int i, full_tree = 0;
370 read_tree_fn_t fn = NULL;
371 enum ls_tree_cmdmode cmdmode = MODE_DEFAULT;
372 int null_termination = 0;
373 struct ls_tree_options options = { 0 };
374 const struct option ls_tree_options[] = {
375 OPT_BIT('d', NULL, &options.ls_options, N_("only show trees"),
376 LS_TREE_ONLY),
377 OPT_BIT('r', NULL, &options.ls_options, N_("recurse into subtrees"),
378 LS_RECURSIVE),
379 OPT_BIT('t', NULL, &options.ls_options, N_("show trees when recursing"),
380 LS_SHOW_TREES),
381 OPT_BOOL('z', NULL, &null_termination,
382 N_("terminate entries with NUL byte")),
383 OPT_CMDMODE('l', "long", &cmdmode, N_("include object size"),
384 MODE_LONG),
385 OPT_CMDMODE(0, "name-only", &cmdmode, N_("list only filenames"),
386 MODE_NAME_ONLY),
387 OPT_CMDMODE(0, "name-status", &cmdmode, N_("list only filenames"),
388 MODE_NAME_STATUS),
389 OPT_CMDMODE(0, "object-only", &cmdmode, N_("list only objects"),
390 MODE_OBJECT_ONLY),
391 OPT_SET_INT(0, "full-name", &options.chomp_prefix,
392 N_("use full path names"), 0),
393 OPT_BOOL(0, "full-tree", &full_tree,
394 N_("list entire tree; not just current directory "
395 "(implies --full-name)")),
396 OPT_STRING_F(0, "format", &options.format, N_("format"),
397 N_("format to use for the output"),
398 PARSE_OPT_NONEG),
399 OPT__ABBREV(&options.abbrev),
400 OPT_END()
402 struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
403 int ret;
405 git_config(git_default_config, NULL);
406 options.ls_tree_prefix = prefix;
407 if (prefix)
408 options.chomp_prefix = strlen(prefix);
410 argc = parse_options(argc, argv, prefix, ls_tree_options,
411 ls_tree_usage, 0);
412 options.null_termination = null_termination;
414 if (full_tree) {
415 options.ls_tree_prefix = prefix = NULL;
416 options.chomp_prefix = 0;
419 * We wanted to detect conflicts between --name-only and
420 * --name-status, but once we're done with that subsequent
421 * code should only need to check the primary name.
423 if (cmdmode == MODE_NAME_STATUS)
424 cmdmode = MODE_NAME_ONLY;
426 /* -d -r should imply -t, but -d by itself should not have to. */
427 if ( (LS_TREE_ONLY|LS_RECURSIVE) ==
428 ((LS_TREE_ONLY|LS_RECURSIVE) & options.ls_options))
429 options.ls_options |= LS_SHOW_TREES;
431 if (options.format && cmdmode)
432 usage_msg_opt(
433 _("--format can't be combined with other format-altering options"),
434 ls_tree_usage, ls_tree_options);
435 if (argc < 1)
436 usage_with_options(ls_tree_usage, ls_tree_options);
437 if (get_oid(argv[0], &oid))
438 die("Not a valid object name %s", argv[0]);
441 * show_recursive() rolls its own matching code and is
442 * generally ignorant of 'struct pathspec'. The magic mask
443 * cannot be lifted until it is converted to use
444 * match_pathspec() or tree_entry_interesting()
446 parse_pathspec(&options.pathspec, PATHSPEC_ALL_MAGIC &
447 ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
448 PATHSPEC_PREFER_CWD,
449 prefix, argv + 1);
450 for (i = 0; i < options.pathspec.nr; i++)
451 options.pathspec.items[i].nowildcard_len = options.pathspec.items[i].len;
452 options.pathspec.has_wildcard = 0;
453 tree = parse_tree_indirect(&oid);
454 if (!tree)
455 die("not a tree object");
457 * The generic show_tree_fmt() is slower than show_tree(), so
458 * take the fast path if possible.
460 while (m2f) {
461 if (!m2f->fmt) {
462 fn = options.format ? show_tree_fmt : show_tree_default;
463 } else if (options.format && !strcmp(options.format, m2f->fmt)) {
464 cmdmode = m2f->mode;
465 fn = m2f->fn;
466 } else if (!options.format && cmdmode == m2f->mode) {
467 fn = m2f->fn;
468 } else {
469 m2f++;
470 continue;
472 break;
475 ret = !!read_tree(the_repository, tree, &options.pathspec, fn, &options);
476 clear_pathspec(&options.pathspec);
477 return ret;