ls-tree.con commit Remove "merge-tree.c" (2fbdd13)
   1/*
   2 * GIT - The information manager from hell
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "cache.h"
   7
   8int line_termination = '\n';
   9int recursive = 0;
  10
  11struct path_prefix {
  12        struct path_prefix *prev;
  13        const char *name;
  14};
  15
  16static void print_path_prefix(struct path_prefix *prefix)
  17{
  18        if (prefix) {
  19                if (prefix->prev)
  20                        print_path_prefix(prefix->prev);
  21                fputs(prefix->name, stdout);
  22                putchar('/');
  23        }
  24}
  25
  26static 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;
  33
  34        if (strcmp(type, "tree"))
  35                die("expected a 'tree' node");
  36
  37        while (size) {
  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;
  44                unsigned int mode;
  45
  46                if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
  47                        die("corrupt 'tree' file");
  48                buffer = sha1 + 20;
  49                size -= namelen + 20;
  50
  51                /* XXX: We do some ugly mode heuristics here.
  52                 * It seems not worth it to read each file just to get this
  53                 * and the file size. -- pasky@ucw.cz
  54                 * ... that is, when we are not recursive -- junkio@cox.net
  55                 */
  56                eltbuf = (recursive ? read_sha1_file(sha1, elttype, &eltsize) :
  57                          NULL);
  58                if (! eltbuf) {
  59                        if (recursive)
  60                                error("cannot read %s", sha1_to_hex(sha1));
  61                        type = S_ISDIR(mode) ? "tree" : "blob";
  62                }
  63                else
  64                        type = elttype;
  65
  66                printf("%03o\t%s\t%s\t", mode, type, sha1_to_hex(sha1));
  67                print_path_prefix(prefix);
  68                fputs(path, stdout);
  69                putchar(line_termination);
  70
  71                if (eltbuf && !strcmp(type, "tree")) {
  72                        this_prefix.name = path;
  73                        list_recursive(eltbuf, elttype, eltsize, &this_prefix);
  74                }
  75                free(eltbuf);
  76        }
  77}
  78
  79static int list(unsigned char *sha1)
  80{
  81        void *buffer;
  82        unsigned long size;
  83        char type[20];
  84
  85        buffer = read_sha1_file(sha1, type, &size);
  86        if (!buffer)
  87                die("unable to read sha1 file");
  88        list_recursive(buffer, type, size, NULL);
  89        return 0;
  90}
  91
  92static void _usage(void)
  93{
  94        usage("ls-tree [-r] [-z] <key>");
  95}
  96
  97int main(int argc, char **argv)
  98{
  99        unsigned char sha1[20];
 100
 101        while (1 < argc && argv[1][0] == '-') {
 102                switch (argv[1][1]) {
 103                case 'z':
 104                        line_termination = 0;
 105                        break;
 106                case 'r':
 107                        recursive = 1;
 108                        break;
 109                default:
 110                        _usage();
 111                }
 112                argc--; argv++;
 113        }
 114
 115        if (argc != 2)
 116                _usage();
 117        if (get_sha1_hex(argv[1], sha1) < 0)
 118                _usage();
 119        sha1_file_directory = getenv(DB_ENVIRONMENT);
 120        if (!sha1_file_directory)
 121                sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
 122        if (list(sha1) < 0)
 123                die("list failed");
 124        return 0;
 125}