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