You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.2 KiB
111 lines
2.2 KiB
/* |
|
* GIT - The information manager from hell |
|
* |
|
* Copyright (C) Linus Torvalds, 2005 |
|
*/ |
|
#include "cache.h" |
|
|
|
static int line_termination = '\n'; |
|
static int recursive = 0; |
|
|
|
struct path_prefix { |
|
struct path_prefix *prev; |
|
const char *name; |
|
}; |
|
|
|
static void print_path_prefix(struct path_prefix *prefix) |
|
{ |
|
if (prefix) { |
|
if (prefix->prev) |
|
print_path_prefix(prefix->prev); |
|
fputs(prefix->name, stdout); |
|
putchar('/'); |
|
} |
|
} |
|
|
|
static void list_recursive(void *buffer, |
|
const char *type, |
|
unsigned long size, |
|
struct path_prefix *prefix) |
|
{ |
|
struct path_prefix this_prefix; |
|
this_prefix.prev = prefix; |
|
|
|
if (strcmp(type, "tree")) |
|
die("expected a 'tree' node"); |
|
|
|
while (size) { |
|
int namelen = strlen(buffer)+1; |
|
void *eltbuf; |
|
char elttype[20]; |
|
unsigned long eltsize; |
|
unsigned char *sha1 = buffer + namelen; |
|
char *path = strchr(buffer, ' ') + 1; |
|
unsigned int mode; |
|
|
|
if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1) |
|
die("corrupt 'tree' file"); |
|
buffer = sha1 + 20; |
|
size -= namelen + 20; |
|
|
|
printf("%06o\t%s\t%s\t", mode, |
|
S_ISDIR(mode) ? "tree" : "blob", |
|
sha1_to_hex(sha1)); |
|
print_path_prefix(prefix); |
|
fputs(path, stdout); |
|
putchar(line_termination); |
|
|
|
if (! recursive || ! S_ISDIR(mode)) |
|
continue; |
|
|
|
if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) { |
|
error("cannot read %s", sha1_to_hex(sha1)); |
|
continue; |
|
} |
|
this_prefix.name = path; |
|
list_recursive(eltbuf, elttype, eltsize, &this_prefix); |
|
free(eltbuf); |
|
} |
|
} |
|
|
|
static int list(unsigned char *sha1) |
|
{ |
|
void *buffer; |
|
unsigned long size; |
|
|
|
buffer = read_object_with_reference(sha1, "tree", &size, NULL); |
|
if (!buffer) |
|
die("unable to read sha1 file"); |
|
list_recursive(buffer, "tree", size, NULL); |
|
free(buffer); |
|
return 0; |
|
} |
|
|
|
static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>"; |
|
|
|
int main(int argc, char **argv) |
|
{ |
|
unsigned char sha1[20]; |
|
|
|
while (1 < argc && argv[1][0] == '-') { |
|
switch (argv[1][1]) { |
|
case 'z': |
|
line_termination = 0; |
|
break; |
|
case 'r': |
|
recursive = 1; |
|
break; |
|
default: |
|
usage(ls_tree_usage); |
|
} |
|
argc--; argv++; |
|
} |
|
|
|
if (argc != 2) |
|
usage(ls_tree_usage); |
|
if (get_sha1(argv[1], sha1) < 0) |
|
usage(ls_tree_usage); |
|
if (list(sha1) < 0) |
|
die("list failed"); |
|
return 0; |
|
}
|
|
|