blob: b8d0d88ba85d7c9770f64288971963250dc3391c [file] [log] [blame]
Petr Baudis7912c072005-04-13 02:02:34 -07001/*
2 * GIT - The information manager from hell
3 *
4 * Copyright (C) Linus Torvalds, 2005
5 */
6#include "cache.h"
Junio C Hamano6af1f012005-05-28 00:05:38 -07007#include "blob.h"
8#include "tree.h"
Junio C Hamano22ddf712005-10-14 21:56:46 -07009#include "quote.h"
Peter Eriksenaae01bd2006-05-23 14:15:30 +020010#include "builtin.h"
Petr Baudis7912c072005-04-13 02:02:34 -070011
Linus Torvaldse99d59f2005-05-20 11:46:10 -070012static int line_termination = '\n';
Junio C Hamano6af1f012005-05-28 00:05:38 -070013#define LS_RECURSIVE 1
14#define LS_TREE_ONLY 2
Linus Torvalds0f8f45c2005-12-01 10:35:51 -080015#define LS_SHOW_TREES 4
Junio C Hamanoc639a552005-12-01 14:54:00 -080016#define LS_NAME_ONLY 8
Eric Wongcb85bfe2006-03-07 05:52:02 -080017static int abbrev = 0;
Linus Torvaldse2466372005-11-27 22:48:08 -080018static int ls_options = 0;
Peter Eriksenaae01bd2006-05-23 14:15:30 +020019static const char **pathspec;
Junio C Hamanoa69dd582005-12-23 13:39:30 -080020static int chomp_prefix = 0;
21static const char *prefix;
Junio C Hamanoaa1c48d2005-04-15 08:37:05 -070022
Petr Baudis4d1f1192005-07-29 11:01:26 +020023static const char ls_tree_usage[] =
Eric Wongcb85bfe2006-03-07 05:52:02 -080024 "git-ls-tree [-d] [-r] [-t] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=<n>]] <tree-ish> [path...]";
Linus Torvalds0f8f45c2005-12-01 10:35:51 -080025
26static int show_recursive(const char *base, int baselen, const char *pathname)
27{
28 const char **s;
29
30 if (ls_options & LS_RECURSIVE)
31 return 1;
32
33 s = pathspec;
34 if (!s)
35 return 0;
36
37 for (;;) {
38 const char *spec = *s++;
39 int len, speclen;
40
41 if (!spec)
42 return 0;
43 if (strncmp(base, spec, baselen))
44 continue;
45 len = strlen(pathname);
46 spec += baselen;
47 speclen = strlen(spec);
48 if (speclen <= len)
49 continue;
50 if (memcmp(pathname, spec, len))
51 continue;
52 return 1;
53 }
54}
Junio C Hamanoaa1c48d2005-04-15 08:37:05 -070055
Linus Torvalds097dc3d2006-05-28 15:13:53 -070056static int show_tree(const unsigned char *sha1, const char *base, int baselen,
Junio C Hamanoa69dd582005-12-23 13:39:30 -080057 const char *pathname, unsigned mode, int stage)
Petr Baudis7912c072005-04-13 02:02:34 -070058{
Linus Torvalds0f8f45c2005-12-01 10:35:51 -080059 int retval = 0;
Peter Eriksen8e440252006-04-02 14:44:09 +020060 const char *type = blob_type;
Petr Baudis7912c072005-04-13 02:02:34 -070061
Linus Torvalds3c5e8462005-11-26 09:38:20 -080062 if (S_ISDIR(mode)) {
Linus Torvalds0f8f45c2005-12-01 10:35:51 -080063 if (show_recursive(base, baselen, pathname)) {
64 retval = READ_TREE_RECURSIVE;
65 if (!(ls_options & LS_SHOW_TREES))
66 return retval;
Linus Torvaldse2466372005-11-27 22:48:08 -080067 }
Peter Eriksen8e440252006-04-02 14:44:09 +020068 type = tree_type;
Linus Torvalds3c5e8462005-11-26 09:38:20 -080069 }
Junio C Hamanof5984672005-12-01 13:15:20 -080070 else if (ls_options & LS_TREE_ONLY)
71 return 0;
Linus Torvalds3c5e8462005-11-26 09:38:20 -080072
Junio C Hamanoa69dd582005-12-23 13:39:30 -080073 if (chomp_prefix &&
74 (baselen < chomp_prefix || memcmp(prefix, base, chomp_prefix)))
75 return 0;
76
Junio C Hamanoc639a552005-12-01 14:54:00 -080077 if (!(ls_options & LS_NAME_ONLY))
Eric Wongcb85bfe2006-03-07 05:52:02 -080078 printf("%06o %s %s\t", mode, type,
79 abbrev ? find_unique_abbrev(sha1,abbrev)
80 : sha1_to_hex(sha1));
Junio C Hamanoa69dd582005-12-23 13:39:30 -080081 write_name_quoted(base + chomp_prefix, baselen - chomp_prefix,
82 pathname,
83 line_termination, stdout);
Junio C Hamano32b59042005-11-28 02:30:04 -080084 putchar(line_termination);
Linus Torvalds0f8f45c2005-12-01 10:35:51 -080085 return retval;
Linus Torvalds3c5e8462005-11-26 09:38:20 -080086}
87
Peter Eriksenaae01bd2006-05-23 14:15:30 +020088int cmd_ls_tree(int argc, const char **argv, char **envp)
Linus Torvalds3c5e8462005-11-26 09:38:20 -080089{
Linus Torvalds3c5e8462005-11-26 09:38:20 -080090 unsigned char sha1[20];
Daniel Barkalow521698b2006-01-26 01:13:36 -050091 struct tree *tree;
Linus Torvalds3c5e8462005-11-26 09:38:20 -080092
93 prefix = setup_git_directory();
Junio C Hamano84a9b582006-03-23 23:41:18 -080094 git_config(git_default_config);
Junio C Hamanoa69dd582005-12-23 13:39:30 -080095 if (prefix && *prefix)
96 chomp_prefix = strlen(prefix);
Junio C Hamanoaa1c48d2005-04-15 08:37:05 -070097 while (1 < argc && argv[1][0] == '-') {
98 switch (argv[1][1]) {
99 case 'z':
100 line_termination = 0;
101 break;
102 case 'r':
Junio C Hamano6af1f012005-05-28 00:05:38 -0700103 ls_options |= LS_RECURSIVE;
104 break;
105 case 'd':
106 ls_options |= LS_TREE_ONLY;
Junio C Hamanoaa1c48d2005-04-15 08:37:05 -0700107 break;
Linus Torvalds0f8f45c2005-12-01 10:35:51 -0800108 case 't':
109 ls_options |= LS_SHOW_TREES;
110 break;
Junio C Hamanoc639a552005-12-01 14:54:00 -0800111 case '-':
112 if (!strcmp(argv[1]+2, "name-only") ||
113 !strcmp(argv[1]+2, "name-status")) {
114 ls_options |= LS_NAME_ONLY;
115 break;
116 }
Junio C Hamanoa69dd582005-12-23 13:39:30 -0800117 if (!strcmp(argv[1]+2, "full-name")) {
118 chomp_prefix = 0;
119 break;
120 }
Eric Wongcb85bfe2006-03-07 05:52:02 -0800121 if (!strncmp(argv[1]+2, "abbrev=",7)) {
122 abbrev = strtoul(argv[1]+9, NULL, 10);
123 if (abbrev && abbrev < MINIMUM_ABBREV)
124 abbrev = MINIMUM_ABBREV;
125 else if (abbrev > 40)
126 abbrev = 40;
127 break;
128 }
129 if (!strcmp(argv[1]+2, "abbrev")) {
130 abbrev = DEFAULT_ABBREV;
131 break;
132 }
Junio C Hamanoc639a552005-12-01 14:54:00 -0800133 /* otherwise fallthru */
Junio C Hamanoaa1c48d2005-04-15 08:37:05 -0700134 default:
Junio C Hamano0f2303f2005-04-16 13:57:39 -0700135 usage(ls_tree_usage);
Junio C Hamanoaa1c48d2005-04-15 08:37:05 -0700136 }
137 argc--; argv++;
138 }
Junio C Hamanof5984672005-12-01 13:15:20 -0800139 /* -d -r should imply -t, but -d by itself should not have to. */
140 if ( (LS_TREE_ONLY|LS_RECURSIVE) ==
141 ((LS_TREE_ONLY|LS_RECURSIVE) & ls_options))
142 ls_options |= LS_SHOW_TREES;
Junio C Hamanoaa1c48d2005-04-15 08:37:05 -0700143
Jason McMullan6d3a5072005-05-26 10:52:50 -0700144 if (argc < 2)
Junio C Hamano0f2303f2005-04-16 13:57:39 -0700145 usage(ls_tree_usage);
Dmitry V. Levin31fff302006-05-09 01:43:38 +0400146 if (get_sha1(argv[1], sha1))
147 die("Not a valid object name %s", argv[1]);
Junio C Hamano6af1f012005-05-28 00:05:38 -0700148
Linus Torvaldse2466372005-11-27 22:48:08 -0800149 pathspec = get_pathspec(prefix, argv + 2);
Daniel Barkalow521698b2006-01-26 01:13:36 -0500150 tree = parse_tree_indirect(sha1);
151 if (!tree)
Linus Torvalds3c5e8462005-11-26 09:38:20 -0800152 die("not a tree object");
Daniel Barkalow521698b2006-01-26 01:13:36 -0500153 read_tree_recursive(tree, "", 0, 0, pathspec, show_tree);
Linus Torvalds3c5e8462005-11-26 09:38:20 -0800154
Petr Baudis7912c072005-04-13 02:02:34 -0700155 return 0;
156}