]>
Commit | Line | Data |
---|---|---|
7912c070 PB |
1 | /* |
2 | * GIT - The information manager from hell | |
3 | * | |
4 | * Copyright (C) Linus Torvalds, 2005 | |
5 | */ | |
6 | #include "cache.h" | |
7 | ||
aa1c48df JH |
8 | int line_termination = '\n'; |
9 | int recursive = 0; | |
10 | ||
11 | struct path_prefix { | |
12 | struct path_prefix *prev; | |
13 | const char *name; | |
14 | }; | |
15 | ||
16 | static void print_path_prefix(struct path_prefix *prefix) | |
7912c070 | 17 | { |
aa1c48df JH |
18 | if (prefix) { |
19 | if (prefix->prev) | |
20 | print_path_prefix(prefix->prev); | |
21 | fputs(prefix->name, stdout); | |
22 | putchar('/'); | |
23 | } | |
24 | } | |
25 | ||
26 | static void list_recursive(void *buffer, | |
27 | unsigned char *type, | |
28 | unsigned long size, | |
29 | struct path_prefix *prefix) | |
30 | { | |
31 | struct path_prefix this_prefix; | |
32 | this_prefix.prev = prefix; | |
7912c070 | 33 | |
7912c070 | 34 | if (strcmp(type, "tree")) |
2de381f9 | 35 | die("expected a 'tree' node"); |
aa1c48df | 36 | |
7912c070 | 37 | while (size) { |
aa1c48df JH |
38 | int namelen = strlen(buffer)+1; |
39 | void *eltbuf; | |
40 | char elttype[20]; | |
41 | unsigned long eltsize; | |
42 | unsigned char *sha1 = buffer + namelen; | |
43 | char *path = strchr(buffer, ' ') + 1; | |
7912c070 | 44 | unsigned int mode; |
7912c070 | 45 | |
aa1c48df | 46 | if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1) |
2de381f9 | 47 | die("corrupt 'tree' file"); |
7912c070 | 48 | buffer = sha1 + 20; |
aa1c48df JH |
49 | size -= namelen + 20; |
50 | ||
0f2303f7 JH |
51 | printf("%06o\t%s\t%s\t", mode, |
52 | S_ISDIR(mode) ? "tree" : "blob", | |
53 | sha1_to_hex(sha1)); | |
aa1c48df JH |
54 | print_path_prefix(prefix); |
55 | fputs(path, stdout); | |
56 | putchar(line_termination); | |
57 | ||
0f2303f7 JH |
58 | if (! recursive || ! S_ISDIR(mode)) |
59 | continue; | |
60 | ||
61 | if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) { | |
62 | error("cannot read %s", sha1_to_hex(sha1)); | |
63 | continue; | |
aa1c48df | 64 | } |
0f2303f7 JH |
65 | this_prefix.name = path; |
66 | list_recursive(eltbuf, elttype, eltsize, &this_prefix); | |
aa1c48df | 67 | free(eltbuf); |
7912c070 | 68 | } |
aa1c48df JH |
69 | } |
70 | ||
71 | static int list(unsigned char *sha1) | |
72 | { | |
73 | void *buffer; | |
74 | unsigned long size; | |
75 | char type[20]; | |
76 | ||
77 | buffer = read_sha1_file(sha1, type, &size); | |
78 | if (!buffer) | |
79 | die("unable to read sha1 file"); | |
80 | list_recursive(buffer, type, size, NULL); | |
7912c070 PB |
81 | return 0; |
82 | } | |
83 | ||
0f2303f7 | 84 | static const char *ls_tree_usage = "ls-tree [-r] [-z] <key>"; |
aa1c48df | 85 | |
7912c070 PB |
86 | int main(int argc, char **argv) |
87 | { | |
88 | unsigned char sha1[20]; | |
89 | ||
aa1c48df JH |
90 | while (1 < argc && argv[1][0] == '-') { |
91 | switch (argv[1][1]) { | |
92 | case 'z': | |
93 | line_termination = 0; | |
94 | break; | |
95 | case 'r': | |
96 | recursive = 1; | |
97 | break; | |
98 | default: | |
0f2303f7 | 99 | usage(ls_tree_usage); |
aa1c48df JH |
100 | } |
101 | argc--; argv++; | |
102 | } | |
103 | ||
7912c070 | 104 | if (argc != 2) |
0f2303f7 | 105 | usage(ls_tree_usage); |
7912c070 | 106 | if (get_sha1_hex(argv[1], sha1) < 0) |
0f2303f7 | 107 | usage(ls_tree_usage); |
7912c070 PB |
108 | sha1_file_directory = getenv(DB_ENVIRONMENT); |
109 | if (!sha1_file_directory) | |
110 | sha1_file_directory = DEFAULT_DB_ENVIRONMENT; | |
111 | if (list(sha1) < 0) | |
2de381f9 | 112 | die("list failed"); |
7912c070 PB |
113 | return 0; |
114 | } |