adaf9979e643d579488ac71c884a98fa39482ebb
   1#include "cache.h"
   2#include "tag.h"
   3#include "commit.h"
   4#include "tree.h"
   5#include "blob.h"
   6#include "diff.h"
   7#include "tree-walk.h"
   8#include "revision.h"
   9#include "list-objects.h"
  10
  11static void process_blob(struct rev_info *revs,
  12                         struct blob *blob,
  13                         struct object_array *p,
  14                         struct name_path *path,
  15                         const char *name)
  16{
  17        struct object *obj = &blob->object;
  18
  19        if (!revs->blob_objects)
  20                return;
  21        if (obj->flags & (UNINTERESTING | SEEN))
  22                return;
  23        obj->flags |= SEEN;
  24        name = xstrdup(name);
  25        add_object(obj, p, path, name);
  26}
  27
  28static void process_tree(struct rev_info *revs,
  29                         struct tree *tree,
  30                         struct object_array *p,
  31                         struct name_path *path,
  32                         const char *name)
  33{
  34        struct object *obj = &tree->object;
  35        struct tree_desc desc;
  36        struct name_entry entry;
  37        struct name_path me;
  38
  39        if (!revs->tree_objects)
  40                return;
  41        if (obj->flags & (UNINTERESTING | SEEN))
  42                return;
  43        if (parse_tree(tree) < 0)
  44                die("bad tree object %s", sha1_to_hex(obj->sha1));
  45        obj->flags |= SEEN;
  46        name = xstrdup(name);
  47        add_object(obj, p, path, name);
  48        me.up = path;
  49        me.elem = name;
  50        me.elem_len = strlen(name);
  51
  52        desc.buf = tree->buffer;
  53        desc.size = tree->size;
  54
  55        while (tree_entry(&desc, &entry)) {
  56                if (S_ISDIR(entry.mode))
  57                        process_tree(revs,
  58                                     lookup_tree(entry.sha1),
  59                                     p, &me, entry.path);
  60                else
  61                        process_blob(revs,
  62                                     lookup_blob(entry.sha1),
  63                                     p, &me, entry.path);
  64        }
  65        free(tree->buffer);
  66        tree->buffer = NULL;
  67}
  68
  69void traverse_commit_list(struct rev_info *revs,
  70                          void (*show_commit)(struct commit *),
  71                          void (*show_object)(struct object_array_entry *))
  72{
  73        int i;
  74        struct commit *commit;
  75        struct object_array objects = { 0, 0, NULL };
  76
  77        while ((commit = get_revision(revs)) != NULL) {
  78                process_tree(revs, commit->tree, &objects, NULL, "");
  79                show_commit(commit);
  80        }
  81        for (i = 0; i < revs->pending.nr; i++) {
  82                struct object_array_entry *pending = revs->pending.objects + i;
  83                struct object *obj = pending->item;
  84                const char *name = pending->name;
  85                if (obj->flags & (UNINTERESTING | SEEN))
  86                        continue;
  87                if (obj->type == OBJ_TAG) {
  88                        obj->flags |= SEEN;
  89                        add_object_array(obj, name, &objects);
  90                        continue;
  91                }
  92                if (obj->type == OBJ_TREE) {
  93                        process_tree(revs, (struct tree *)obj, &objects,
  94                                     NULL, name);
  95                        continue;
  96                }
  97                if (obj->type == OBJ_BLOB) {
  98                        process_blob(revs, (struct blob *)obj, &objects,
  99                                     NULL, name);
 100                        continue;
 101                }
 102                die("unknown pending object %s (%s)",
 103                    sha1_to_hex(obj->sha1), name);
 104        }
 105        for (i = 0; i < objects.nr; i++)
 106                show_object(&objects.objects[i]);
 107}