pull.con commit diff-tree: fix up comparison of "interesting" sub-trees (cb6c8ed)
   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;
  10int get_verbosely = 0;
  11static unsigned char current_commit_sha1[20];
  12
  13static const char commitS[] = "commit";
  14static const char treeS[] = "tree";
  15static const char blobS[] = "blob";
  16
  17void pull_say(const char *fmt, const char *hex) {
  18        if (get_verbosely)
  19                fprintf(stderr, fmt, hex);
  20}
  21
  22static void report_missing(const char *what, const unsigned char *missing)
  23{
  24        char missing_hex[41];
  25
  26        strcpy(missing_hex, sha1_to_hex(missing));;
  27        fprintf(stderr,
  28                "Cannot obtain needed %s %s\nwhile processing commit %s.\n",
  29                what, missing_hex, sha1_to_hex(current_commit_sha1));
  30}
  31
  32static int make_sure_we_have_it(const char *what, unsigned char *sha1)
  33{
  34        int status;
  35        if (has_sha1_file(sha1))
  36                return 0;
  37        status = fetch(sha1);
  38        if (status && what)
  39                report_missing(what, sha1);
  40        return status;
  41}
  42
  43static int process_tree(unsigned char *sha1)
  44{
  45        struct tree *tree = lookup_tree(sha1);
  46        struct tree_entry_list *entries;
  47
  48        if (parse_tree(tree))
  49                return -1;
  50
  51        for (entries = tree->entries; entries; entries = entries->next) {
  52                const char *what = entries->directory ? treeS : blobS;
  53                if (make_sure_we_have_it(what, entries->item.tree->object.sha1))
  54                        return -1;
  55                if (entries->directory) {
  56                        if (process_tree(entries->item.tree->object.sha1))
  57                                return -1;
  58                }
  59        }
  60        return 0;
  61}
  62
  63static int process_commit(unsigned char *sha1)
  64{
  65        struct commit *obj = lookup_commit(sha1);
  66
  67        if (make_sure_we_have_it(commitS, sha1))
  68                return -1;
  69
  70        if (parse_commit(obj))
  71                return -1;
  72
  73        if (get_tree) {
  74                if (make_sure_we_have_it(treeS, obj->tree->object.sha1))
  75                        return -1;
  76                if (process_tree(obj->tree->object.sha1))
  77                        return -1;
  78                if (!get_all)
  79                        get_tree = 0;
  80        }
  81        if (get_history) {
  82                struct commit_list *parents = obj->parents;
  83                for (; parents; parents = parents->next) {
  84                        if (has_sha1_file(parents->item->object.sha1))
  85                                continue;
  86                        if (make_sure_we_have_it(NULL,
  87                                                 parents->item->object.sha1)) {
  88                                /* The server might not have it, and
  89                                 * we don't mind. 
  90                                 */
  91                                continue;
  92                        }
  93                        if (process_commit(parents->item->object.sha1))
  94                                return -1;
  95                        memcpy(current_commit_sha1, sha1, 20);
  96                }
  97        }
  98        return 0;
  99}
 100
 101int pull(char *target)
 102{
 103        int retval;
 104        unsigned char sha1[20];
 105        retval = get_sha1_hex(target, sha1);
 106        if (retval)
 107                return retval;
 108        retval = make_sure_we_have_it(commitS, sha1);
 109        if (retval)
 110                return retval;
 111        memcpy(current_commit_sha1, sha1, 20);
 112        return process_commit(sha1);
 113}