rpull.con commit git-pull-script: do automatic merges (9831d8f)
   1#include <fcntl.h>
   2#include <unistd.h>
   3#include <string.h>
   4#include <stdlib.h>
   5#include "cache.h"
   6#include "commit.h"
   7#include <errno.h>
   8#include <stdio.h>
   9#include "rsh.h"
  10
  11static int tree = 0;
  12static int commits = 0;
  13static int all = 0;
  14
  15static int fd_in;
  16static int fd_out;
  17
  18static int fetch(unsigned char *sha1)
  19{
  20        if (has_sha1_file(sha1))
  21                return 0;
  22        write(fd_out, sha1, 20);
  23        return write_sha1_from_fd(sha1, fd_in);
  24}
  25
  26static int process_tree(unsigned char *sha1)
  27{
  28        struct tree *tree = lookup_tree(sha1);
  29        struct tree_entry_list *entries;
  30
  31        if (parse_tree(tree))
  32                return -1;
  33
  34        for (entries = tree->entries; entries; entries = entries->next) {
  35                /*
  36                  fprintf(stderr, "Tree %s ", sha1_to_hex(sha1));
  37                  fprintf(stderr, "needs %s\n", 
  38                  sha1_to_hex(entries->item.tree->object.sha1));
  39                */
  40                if (fetch(entries->item.tree->object.sha1)) {
  41                        return error("Missing item %s",
  42                                     sha1_to_hex(entries->item.tree->object.sha1));
  43                }
  44                if (entries->directory) {
  45                        if (process_tree(entries->item.tree->object.sha1))
  46                                return -1;
  47                }
  48        }
  49        return 0;
  50}
  51
  52static int process_commit(unsigned char *sha1)
  53{
  54        struct commit *obj = lookup_commit(sha1);
  55
  56        if (fetch(sha1)) {
  57                return error("Fetching %s", sha1_to_hex(sha1));
  58        }
  59
  60        if (parse_commit(obj))
  61                return -1;
  62
  63        if (tree) {
  64                if (fetch(obj->tree->object.sha1))
  65                        return -1;
  66                if (process_tree(obj->tree->object.sha1))
  67                        return -1;
  68                if (!all)
  69                        tree = 0;
  70        }
  71        if (commits) {
  72                struct commit_list *parents = obj->parents;
  73                for (; parents; parents = parents->next) {
  74                        if (has_sha1_file(parents->item->object.sha1))
  75                                continue;
  76                        if (fetch(parents->item->object.sha1)) {
  77                                /* The server might not have it, and
  78                                 * we don't mind. 
  79                                 */
  80                                error("Missing tree %s; continuing", 
  81                                      sha1_to_hex(parents->item->object.sha1));
  82                                continue;
  83                        }
  84                        if (process_commit(parents->item->object.sha1))
  85                                return -1;
  86                }
  87        }
  88        return 0;
  89}
  90
  91int main(int argc, char **argv)
  92{
  93        char *commit_id;
  94        char *url;
  95        int arg = 1;
  96        unsigned char sha1[20];
  97
  98        while (arg < argc && argv[arg][0] == '-') {
  99                if (argv[arg][1] == 't') {
 100                        tree = 1;
 101                } else if (argv[arg][1] == 'c') {
 102                        commits = 1;
 103                } else if (argv[arg][1] == 'a') {
 104                        all = 1;
 105                        tree = 1;
 106                        commits = 1;
 107                }
 108                arg++;
 109        }
 110        if (argc < arg + 2) {
 111                usage("rpull [-c] [-t] [-a] commit-id url");
 112                return 1;
 113        }
 114        commit_id = argv[arg];
 115        url = argv[arg + 1];
 116
 117        if (setup_connection(&fd_in, &fd_out, "rpush", url, arg, argv + 1))
 118                return 1;
 119
 120        get_sha1_hex(commit_id, sha1);
 121
 122        if (fetch(sha1))
 123                return 1;
 124        if (process_commit(sha1))
 125                return 1;
 126
 127        return 0;
 128}