pull.con commit fsck-cache: fix SIGSEGV on bad tag object (92d4c85)
   1#include "pull.h"
   2
   3#include "cache.h"
   4#include "commit.h"
   5#include "tree.h"
   6
   7int get_tree = 0;
   8int get_history = 0;
   9int get_all = 0;
  10
  11static int make_sure_we_have_it(unsigned char *sha1)
  12{
  13        if (has_sha1_file(sha1))
  14                return 0;
  15        return fetch(sha1);     
  16}
  17
  18static int process_tree(unsigned char *sha1)
  19{
  20        struct tree *tree = lookup_tree(sha1);
  21        struct tree_entry_list *entries;
  22
  23        if (parse_tree(tree))
  24                return -1;
  25
  26        for (entries = tree->entries; entries; entries = entries->next) {
  27                if (make_sure_we_have_it(entries->item.tree->object.sha1))
  28                        return -1;
  29                if (entries->directory) {
  30                        if (process_tree(entries->item.tree->object.sha1))
  31                                return -1;
  32                }
  33        }
  34        return 0;
  35}
  36
  37static int process_commit(unsigned char *sha1)
  38{
  39        struct commit *obj = lookup_commit(sha1);
  40
  41        if (make_sure_we_have_it(sha1))
  42                return -1;
  43
  44        if (parse_commit(obj))
  45                return -1;
  46
  47        if (get_tree) {
  48                if (make_sure_we_have_it(obj->tree->object.sha1))
  49                        return -1;
  50                if (process_tree(obj->tree->object.sha1))
  51                        return -1;
  52                if (!get_all)
  53                        get_tree = 0;
  54        }
  55        if (get_history) {
  56                struct commit_list *parents = obj->parents;
  57                for (; parents; parents = parents->next) {
  58                        if (has_sha1_file(parents->item->object.sha1))
  59                                continue;
  60                        if (make_sure_we_have_it(parents->item->object.sha1)) {
  61                                /* The server might not have it, and
  62                                 * we don't mind. 
  63                                 */
  64                                continue;
  65                        }
  66                        if (process_commit(parents->item->object.sha1))
  67                                return -1;
  68                }
  69        }
  70        return 0;
  71}
  72
  73int pull(char *target)
  74{
  75        int retval;
  76        unsigned char sha1[20];
  77        retval = get_sha1_hex(target, sha1);
  78        if (retval)
  79                return retval;
  80        retval = make_sure_we_have_it(sha1);
  81        if (retval)
  82                return retval;
  83        return process_commit(sha1);
  84}