2 * GIT - The information manager from hell
4 * Copyright (C) Linus Torvalds, 2005
11 static int line_termination
= '\n';
12 #define LS_RECURSIVE 1
13 #define LS_TREE_ONLY 2
14 static int ls_options
= 0;
16 static struct tree_entry_list root_entry
;
18 static void prepare_root(unsigned char *sha1
)
20 unsigned char rsha
[20];
23 struct tree
*root_tree
;
25 buf
= read_object_with_reference(sha1
, "tree", &size
, rsha
);
28 die("Could not read %s", sha1_to_hex(sha1
));
30 root_tree
= lookup_tree(rsha
);
32 die("Could not read %s", sha1_to_hex(sha1
));
34 /* Prepare a fake entry */
35 root_entry
.directory
= 1;
36 root_entry
.executable
= root_entry
.symlink
= 0;
37 root_entry
.mode
= S_IFDIR
;
39 root_entry
.item
.tree
= root_tree
;
40 root_entry
.parent
= NULL
;
43 static int prepare_children(struct tree_entry_list
*elem
)
47 if (!elem
->item
.tree
->object
.parsed
) {
48 struct tree_entry_list
*e
;
49 if (parse_tree(elem
->item
.tree
))
51 /* Set up the parent link */
52 for (e
= elem
->item
.tree
->entries
; e
; e
= e
->next
)
58 static struct tree_entry_list
*find_entry(const char *path
, char *pathbuf
)
60 const char *next
, *slash
;
62 struct tree_entry_list
*elem
= &root_entry
, *oldelem
= NULL
;
66 /* Find tree element, descending from root, that
67 * corresponds to the named path, lazily expanding
68 * the tree if possible.
72 /* The fact we still have path means that the caller
73 * wants us to make sure that elem at this point is a
74 * directory, and possibly descend into it. Even what
75 * is left is just trailing slashes, we loop back to
76 * here, and this call to prepare_children() will
77 * catch elem not being a tree. Nice.
79 if (prepare_children(elem
))
82 slash
= strchr(path
, '/');
93 pathbuf
+= sprintf(pathbuf
, "%s/", oldelem
->name
);
96 /* (len == 0) if the original path was "drivers/char/"
97 * and we have run already two rounds, having elem
98 * pointing at the drivers/char directory.
100 elem
= elem
->item
.tree
->entries
;
102 if ((strlen(elem
->name
) == len
) &&
103 !strncmp(elem
->name
, path
, len
)) {
120 static const char *entry_type(struct tree_entry_list
*e
)
122 return (e
->directory
? "tree" : "blob");
125 static const char *entry_hex(struct tree_entry_list
*e
)
127 return sha1_to_hex(e
->directory
128 ? e
->item
.tree
->object
.sha1
129 : e
->item
.blob
->object
.sha1
);
132 /* forward declaration for mutually recursive routines */
133 static int show_entry(struct tree_entry_list
*, int, char *pathbuf
);
135 static int show_children(struct tree_entry_list
*e
, int level
, char *pathbuf
)
137 int oldlen
= strlen(pathbuf
);
139 if (e
!= &root_entry
)
140 sprintf(pathbuf
+ oldlen
, "%s/", e
->name
);
142 if (prepare_children(e
))
143 die("internal error: ls-tree show_children called with non tree");
144 e
= e
->item
.tree
->entries
;
146 show_entry(e
, level
, pathbuf
);
150 pathbuf
[oldlen
] = '\0';
155 static int show_entry(struct tree_entry_list
*e
, int level
, char *pathbuf
)
159 if (e
!= &root_entry
) {
160 int pathlen
= strlen(pathbuf
);
161 printf("%06o %s %s ",
162 e
->mode
, entry_type(e
), entry_hex(e
));
163 write_name_quoted(pathbuf
, pathlen
, e
->name
,
164 line_termination
, stdout
);
165 putchar(line_termination
);
169 /* If this is a directory, we have the following cases:
170 * (1) This is the top-level request (explicit path from the
171 * command line, or "root" if there is no command line).
172 * a. Without any flag. We show direct children. We do not
174 * b. With -r. We do recurse into children.
175 * c. With -d. We do not recurse into children.
176 * (2) We came here because our caller is either (1-a) or
178 * a. Without any flag. We do not show our children (which
179 * are grandchildren for the original request).
180 * b. With -r. We continue to recurse into our children.
181 * c. With -d. We should not have come here to begin with.
183 if (level
== 0 && !(ls_options
& LS_TREE_ONLY
))
184 /* case (1)-a and (1)-b */
185 err
= err
| show_children(e
, level
+1, pathbuf
);
186 else if (level
&& ls_options
& LS_RECURSIVE
)
188 err
= err
| show_children(e
, level
+1, pathbuf
);
193 static int list_one(const char *path
)
196 char pathbuf
[MAXPATHLEN
+ 1];
197 struct tree_entry_list
*e
= find_entry(path
, pathbuf
);
199 /* traditionally ls-tree does not complain about
200 * missing path. We may change this later to match
201 * what "/bin/ls -a" does, which is to complain.
205 err
= err
| show_entry(e
, 0, pathbuf
);
209 static int list(char **path
)
213 for (i
= 0; path
[i
]; i
++)
214 err
= err
| list_one(path
[i
]);
218 static const char ls_tree_usage
[] =
219 "git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]";
221 int main(int argc
, char **argv
)
223 static char *path0
[] = { "", NULL
};
225 unsigned char sha1
[20];
227 while (1 < argc
&& argv
[1][0] == '-') {
228 switch (argv
[1][1]) {
230 line_termination
= 0;
233 ls_options
|= LS_RECURSIVE
;
236 ls_options
|= LS_TREE_ONLY
;
239 usage(ls_tree_usage
);
245 usage(ls_tree_usage
);
246 if (get_sha1(argv
[1], sha1
) < 0)
247 usage(ls_tree_usage
);
249 path
= (argc
== 2) ? path0
: (argv
+ 2);