]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/ls-tree.c
Merge branch 'jk/clone-allow-bare-and-o-together'
[thirdparty/git.git] / builtin / ls-tree.c
CommitLineData
7912c070
PB
1/*
2 * GIT - The information manager from hell
3 *
4 * Copyright (C) Linus Torvalds, 2005
5 */
6#include "cache.h"
b2141fc1 7#include "config.h"
cbd53a21 8#include "object-store.h"
6af1f019
JH
9#include "blob.h"
10#include "tree.h"
f35a6d3b 11#include "commit.h"
22ddf719 12#include "quote.h"
aae01bda 13#include "builtin.h"
61fdbcf9 14#include "parse-options.h"
64acde94 15#include "pathspec.h"
7912c070 16
e99d59ff 17static int line_termination = '\n';
6af1f019 18#define LS_RECURSIVE 1
315f22c8
TL
19#define LS_TREE_ONLY (1 << 1)
20#define LS_SHOW_TREES (1 << 2)
96f1e58f
DR
21static int abbrev;
22static int ls_options;
f0096c06 23static struct pathspec pathspec;
96f1e58f 24static int chomp_prefix;
a633fca0 25static const char *ls_tree_prefix;
455923e0 26static const char *format;
e8151715
ÆAB
27struct show_tree_data {
28 unsigned mode;
29 enum object_type type;
30 const struct object_id *oid;
31 const char *pathname;
32 struct strbuf *base;
33};
aa1c48df 34
61fdbcf9 35static const char * const ls_tree_usage[] = {
373f9221 36 N_("git ls-tree [<options>] <tree-ish> [<path>...]"),
61fdbcf9
SB
37 NULL
38};
0f8f45cb 39
315f22c8 40static enum ls_tree_cmdmode {
455923e0
ÆAB
41 MODE_DEFAULT = 0,
42 MODE_LONG,
315f22c8 43 MODE_NAME_ONLY,
0f887835 44 MODE_NAME_STATUS,
cab851c2 45 MODE_OBJECT_ONLY,
315f22c8
TL
46} cmdmode;
47
455923e0
ÆAB
48static void expand_objectsize(struct strbuf *line, const struct object_id *oid,
49 const enum object_type type, unsigned int padded)
50{
51 if (type == OBJ_BLOB) {
52 unsigned long size;
53 if (oid_object_info(the_repository, oid, &size) < 0)
54 die(_("could not get object info about '%s'"),
55 oid_to_hex(oid));
56 if (padded)
57 strbuf_addf(line, "%7"PRIuMAX, (uintmax_t)size);
58 else
59 strbuf_addf(line, "%"PRIuMAX, (uintmax_t)size);
60 } else if (padded) {
61 strbuf_addf(line, "%7s", "-");
62 } else {
63 strbuf_addstr(line, "-");
64 }
65}
66
67static size_t expand_show_tree(struct strbuf *sb, const char *start,
68 void *context)
69{
70 struct show_tree_data *data = context;
71 const char *end;
72 const char *p;
73 unsigned int errlen;
74 size_t len = strbuf_expand_literal_cb(sb, start, NULL);
75
76 if (len)
77 return len;
78 if (*start != '(')
79 die(_("bad ls-tree format: element '%s' does not start with '('"), start);
80
81 end = strchr(start + 1, ')');
82 if (!end)
83 die(_("bad ls-tree format: element '%s' does not end in ')'"), start);
84
85 len = end - start + 1;
86 if (skip_prefix(start, "(objectmode)", &p)) {
87 strbuf_addf(sb, "%06o", data->mode);
88 } else if (skip_prefix(start, "(objecttype)", &p)) {
89 strbuf_addstr(sb, type_name(data->type));
90 } else if (skip_prefix(start, "(objectsize:padded)", &p)) {
91 expand_objectsize(sb, data->oid, data->type, 1);
92 } else if (skip_prefix(start, "(objectsize)", &p)) {
93 expand_objectsize(sb, data->oid, data->type, 0);
94 } else if (skip_prefix(start, "(objectname)", &p)) {
95 strbuf_add_unique_abbrev(sb, data->oid, abbrev);
96 } else if (skip_prefix(start, "(path)", &p)) {
97 const char *name = data->base->buf;
98 const char *prefix = chomp_prefix ? ls_tree_prefix : NULL;
99 struct strbuf quoted = STRBUF_INIT;
100 struct strbuf sbuf = STRBUF_INIT;
101 strbuf_addstr(data->base, data->pathname);
102 name = relative_path(data->base->buf, prefix, &sbuf);
103 quote_c_style(name, &quoted, NULL, 0);
104 strbuf_addbuf(sb, &quoted);
105 strbuf_release(&sbuf);
106 strbuf_release(&quoted);
107 } else {
108 errlen = (unsigned long)len;
109 die(_("bad ls-tree format: %%%.*s"), errlen, start);
110 }
111 return len;
112}
113
132ceda4 114static int show_recursive(const char *base, size_t baselen, const char *pathname)
0f8f45cb 115{
e1e24edc 116 int i;
0f8f45cb
LT
117
118 if (ls_options & LS_RECURSIVE)
119 return 1;
120
e1e24edc 121 if (!pathspec.nr)
0f8f45cb
LT
122 return 0;
123
e1e24edc
BW
124 for (i = 0; i < pathspec.nr; i++) {
125 const char *spec = pathspec.items[i].match;
132ceda4 126 size_t len, speclen;
0f8f45cb 127
0f8f45cb
LT
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;
b294ed63
JH
135 if (spec[len] && spec[len] != '/')
136 continue;
0f8f45cb
LT
137 if (memcmp(pathname, spec, len))
138 continue;
139 return 1;
140 }
e1e24edc 141 return 0;
0f8f45cb 142}
aa1c48df 143
455923e0 144static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
5cf88fd8 145 const char *pathname, unsigned mode, void *context UNUSED)
6af1f019 146{
455923e0
ÆAB
147 size_t baselen;
148 int recurse = 0;
149 struct strbuf sb = STRBUF_INIT;
150 enum object_type type = object_type(mode);
151
152 struct show_tree_data data = {
153 .mode = mode,
154 .type = type,
155 .oid = oid,
156 .pathname = pathname,
157 .base = base,
158 };
159
160 if (type == OBJ_TREE && show_recursive(base->buf, base->len, pathname))
161 recurse = READ_TREE_RECURSIVE;
162 if (type == OBJ_TREE && recurse && !(ls_options & LS_SHOW_TREES))
163 return recurse;
164 if (type == OBJ_BLOB && (ls_options & LS_TREE_ONLY))
f5984671 165 return 0;
ab1630a3 166
1cf9952d 167 baselen = base->len;
455923e0
ÆAB
168 strbuf_expand(&sb, format, expand_show_tree, &data);
169 strbuf_addch(&sb, line_termination);
170 fwrite(sb.buf, sb.len, 1, stdout);
171 strbuf_release(&sb);
172 strbuf_setlen(base, baselen);
173 return recurse;
174}
175
9c4d58ff
ÆAB
176static 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)
315f22c8 179{
87af0ddf 180 enum object_type type = object_type(mode);
9c4d58ff
ÆAB
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;
ab1630a3 189
87af0ddf
TL
190 if (type == OBJ_BLOB) {
191 if (ls_options & LS_TREE_ONLY)
9c4d58ff 192 ret = 0;
87af0ddf
TL
193 } else if (type == OBJ_TREE &&
194 show_recursive(base->buf, base->len, pathname)) {
9c4d58ff 195 *recurse = READ_TREE_RECURSIVE;
87af0ddf 196 if (!(ls_options & LS_SHOW_TREES))
9c4d58ff 197 ret = *recurse;
6af1f019 198 }
ab1630a3 199
9c4d58ff
ÆAB
200 return ret;
201}
cab851c2 202
9c4d58ff
ÆAB
203static 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
214static int show_tree_default(const struct object_id *oid, struct strbuf *base,
215 const char *pathname, unsigned mode,
5cf88fd8 216 void *context UNUSED)
9c4d58ff
ÆAB
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
232static int show_tree_long(const struct object_id *oid, struct strbuf *base,
555ff1c8 233 const char *pathname, unsigned mode,
5cf88fd8 234 void *context UNUSED)
9c4d58ff
ÆAB
235{
236 int early;
237 int recurse;
238 struct show_tree_data data = { 0 };
239 char size_text[24];
240
241 early = show_tree_common(&data, &recurse, oid, base, pathname, mode);
242 if (early >= 0)
243 return early;
244
245 if (data.type == OBJ_BLOB) {
246 unsigned long size;
247 if (oid_object_info(the_repository, data.oid, &size) == OBJ_BAD)
248 xsnprintf(size_text, sizeof(size_text), "BAD");
249 else
250 xsnprintf(size_text, sizeof(size_text),
251 "%" PRIuMAX, (uintmax_t)size);
252 } else {
253 xsnprintf(size_text, sizeof(size_text), "-");
a5bbda8b 254 }
315f22c8 255
9c4d58ff
ÆAB
256 printf("%06o %s %s %7s\t", data.mode, type_name(data.type),
257 find_unique_abbrev(data.oid, abbrev), size_text);
258 show_tree_common_default_long(base, pathname, data.base->len);
350296cc 259 return recurse;
9c4d58ff 260}
315f22c8 261
9c4d58ff 262static int show_tree_name_only(const struct object_id *oid, struct strbuf *base,
555ff1c8 263 const char *pathname, unsigned mode,
5cf88fd8 264 void *context UNUSED)
9c4d58ff
ÆAB
265{
266 int early;
267 int recurse;
268 const size_t baselen = base->len;
269 struct show_tree_data data = { 0 };
270
271 early = show_tree_common(&data, &recurse, oid, base, pathname, mode);
272 if (early >= 0)
273 return early;
274
1cf9952d
NTND
275 strbuf_addstr(base, pathname);
276 write_name_quoted_relative(base->buf,
277 chomp_prefix ? ls_tree_prefix : NULL,
278 stdout, line_termination);
279 strbuf_setlen(base, baselen);
9c4d58ff
ÆAB
280 return recurse;
281}
282
283static int show_tree_object(const struct object_id *oid, struct strbuf *base,
555ff1c8 284 const char *pathname, unsigned mode,
5cf88fd8 285 void *context UNUSED)
9c4d58ff
ÆAB
286{
287 int early;
288 int recurse;
289 struct show_tree_data data = { 0 };
290
291 early = show_tree_common(&data, &recurse, oid, base, pathname, mode);
292 if (early >= 0)
293 return early;
294
295 printf("%s%c", find_unique_abbrev(oid, abbrev), line_termination);
889f7838 296 return recurse;
6af1f019 297}
0f2303f7 298
455923e0
ÆAB
299struct ls_tree_cmdmode_to_fmt {
300 enum ls_tree_cmdmode mode;
301 const char *const fmt;
9c4d58ff 302 read_tree_fn_t fn;
455923e0
ÆAB
303};
304
305static struct ls_tree_cmdmode_to_fmt ls_tree_cmdmode_format[] = {
306 {
307 .mode = MODE_DEFAULT,
308 .fmt = "%(objectmode) %(objecttype) %(objectname)%x09%(path)",
9c4d58ff 309 .fn = show_tree_default,
455923e0
ÆAB
310 },
311 {
312 .mode = MODE_LONG,
313 .fmt = "%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)",
9c4d58ff 314 .fn = show_tree_long,
455923e0
ÆAB
315 },
316 {
317 .mode = MODE_NAME_ONLY, /* And MODE_NAME_STATUS */
318 .fmt = "%(path)",
9c4d58ff 319 .fn = show_tree_name_only,
455923e0 320 },
cab851c2
TL
321 {
322 .mode = MODE_OBJECT_ONLY,
323 .fmt = "%(objectname)",
9c4d58ff
ÆAB
324 .fn = show_tree_object
325 },
326 {
327 /* fallback */
328 .fn = show_tree_default,
cab851c2 329 },
455923e0
ÆAB
330};
331
a633fca0 332int cmd_ls_tree(int argc, const char **argv, const char *prefix)
6af1f019 333{
a9b5f5bf 334 struct object_id oid;
521698b1 335 struct tree *tree;
f0096c06 336 int i, full_tree = 0;
9c4d58ff 337 read_tree_fn_t fn = NULL;
61fdbcf9 338 const struct option ls_tree_options[] = {
373f9221 339 OPT_BIT('d', NULL, &ls_options, N_("only show trees"),
61fdbcf9 340 LS_TREE_ONLY),
373f9221 341 OPT_BIT('r', NULL, &ls_options, N_("recurse into subtrees"),
61fdbcf9 342 LS_RECURSIVE),
373f9221 343 OPT_BIT('t', NULL, &ls_options, N_("show trees when recursing"),
61fdbcf9
SB
344 LS_SHOW_TREES),
345 OPT_SET_INT('z', NULL, &line_termination,
373f9221 346 N_("terminate entries with NUL byte"), 0),
315f22c8
TL
347 OPT_CMDMODE('l', "long", &cmdmode, N_("include object size"),
348 MODE_LONG),
349 OPT_CMDMODE(0, "name-only", &cmdmode, N_("list only filenames"),
350 MODE_NAME_ONLY),
351 OPT_CMDMODE(0, "name-status", &cmdmode, N_("list only filenames"),
0f887835 352 MODE_NAME_STATUS),
cab851c2
TL
353 OPT_CMDMODE(0, "object-only", &cmdmode, N_("list only objects"),
354 MODE_OBJECT_ONLY),
61fdbcf9 355 OPT_SET_INT(0, "full-name", &chomp_prefix,
373f9221 356 N_("use full path names"), 0),
d5d09d47
SB
357 OPT_BOOL(0, "full-tree", &full_tree,
358 N_("list entire tree; not just current directory "
359 "(implies --full-name)")),
455923e0
ÆAB
360 OPT_STRING_F(0, "format", &format, N_("format"),
361 N_("format to use for the output"),
362 PARSE_OPT_NONEG),
61fdbcf9
SB
363 OPT__ABBREV(&abbrev),
364 OPT_END()
365 };
9c4d58ff 366 struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
7912c070 367
ef90d6d4 368 git_config(git_default_config, NULL);
a633fca0 369 ls_tree_prefix = prefix;
9725c8dd 370 if (prefix)
a69dd585 371 chomp_prefix = strlen(prefix);
61fdbcf9
SB
372
373 argc = parse_options(argc, argv, prefix, ls_tree_options,
374 ls_tree_usage, 0);
375 if (full_tree) {
376 ls_tree_prefix = prefix = NULL;
377 chomp_prefix = 0;
aa1c48df 378 }
0f887835
ÆAB
379 /*
380 * We wanted to detect conflicts between --name-only and
381 * --name-status, but once we're done with that subsequent
382 * code should only need to check the primary name.
383 */
384 if (cmdmode == MODE_NAME_STATUS)
385 cmdmode = MODE_NAME_ONLY;
386
f5984671
JH
387 /* -d -r should imply -t, but -d by itself should not have to. */
388 if ( (LS_TREE_ONLY|LS_RECURSIVE) ==
389 ((LS_TREE_ONLY|LS_RECURSIVE) & ls_options))
390 ls_options |= LS_SHOW_TREES;
aa1c48df 391
455923e0
ÆAB
392 if (format && cmdmode)
393 usage_msg_opt(
394 _("--format can't be combined with other format-altering options"),
395 ls_tree_usage, ls_tree_options);
61fdbcf9
SB
396 if (argc < 1)
397 usage_with_options(ls_tree_usage, ls_tree_options);
a9b5f5bf 398 if (get_oid(argv[0], &oid))
61fdbcf9 399 die("Not a valid object name %s", argv[0]);
6af1f019 400
0fdc2ae5
NTND
401 /*
402 * show_recursive() rolls its own matching code and is
403 * generally ignorant of 'struct pathspec'. The magic mask
404 * cannot be lifted until it is converted to use
854b0959 405 * match_pathspec() or tree_entry_interesting()
0fdc2ae5 406 */
e1e24edc
BW
407 parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC &
408 ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
0fdc2ae5
NTND
409 PATHSPEC_PREFER_CWD,
410 prefix, argv + 1);
f0096c06 411 for (i = 0; i < pathspec.nr; i++)
170260ae 412 pathspec.items[i].nowildcard_len = pathspec.items[i].len;
33e0f62b 413 pathspec.has_wildcard = 0;
a9dbc179 414 tree = parse_tree_indirect(&oid);
521698b1 415 if (!tree)
3c5e8468 416 die("not a tree object");
455923e0
ÆAB
417 /*
418 * The generic show_tree_fmt() is slower than show_tree(), so
419 * take the fast path if possible.
420 */
9c4d58ff
ÆAB
421 while (m2f) {
422 if (!m2f->fmt) {
423 fn = format ? show_tree_fmt : show_tree_default;
424 } else if (format && !strcmp(format, m2f->fmt)) {
455923e0 425 cmdmode = m2f->mode;
9c4d58ff
ÆAB
426 fn = m2f->fn;
427 } else if (!format && cmdmode == m2f->mode) {
428 fn = m2f->fn;
429 } else {
430 m2f++;
431 continue;
455923e0 432 }
9c4d58ff 433 break;
455923e0
ÆAB
434 }
435
436 return !!read_tree(the_repository, tree, &pathspec, fn, NULL);
7912c070 437}