builtin-upload-tar.con commit gitweb: Adding a `blame' interface. (e34ef62)
   1/*
   2 * Copyright (c) 2006 Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "pkt-line.h"
   6#include "exec_cmd.h"
   7#include "builtin.h"
   8
   9static const char upload_tar_usage[] = "git-upload-tar <repo>";
  10
  11static int nak(const char *reason)
  12{
  13        packet_write(1, "NACK %s\n", reason);
  14        packet_flush(1);
  15        return 1;
  16}
  17
  18int cmd_upload_tar(int argc, const char **argv, char **envp)
  19{
  20        int len;
  21        const char *dir = argv[1];
  22        char buf[8192];
  23        unsigned char sha1[20];
  24        char *base = NULL;
  25        char hex[41];
  26        int ac;
  27        const char *av[4];
  28
  29        if (argc != 2)
  30                usage(upload_tar_usage);
  31        if (strlen(dir) < sizeof(buf)-1)
  32                strcpy(buf, dir); /* enter-repo smudges its argument */
  33        else
  34                packet_write(1, "NACK insanely long repository name %s\n", dir);
  35        if (!enter_repo(buf, 0)) {
  36                packet_write(1, "NACK not a git archive %s\n", dir);
  37                packet_flush(1);
  38                return 1;
  39        }
  40
  41        len = packet_read_line(0, buf, sizeof(buf));
  42        if (len < 5 || strncmp("want ", buf, 5))
  43                return nak("expected want");
  44        if (buf[len-1] == '\n')
  45                buf[--len] = 0;
  46        if (get_sha1(buf + 5, sha1))
  47                return nak("expected sha1");
  48        strcpy(hex, sha1_to_hex(sha1));
  49
  50        len = packet_read_line(0, buf, sizeof(buf));
  51        if (len) {
  52                if (len < 5 || strncmp("base ", buf, 5))
  53                        return nak("expected (optional) base");
  54                if (buf[len-1] == '\n')
  55                        buf[--len] = 0;
  56                base = strdup(buf + 5);
  57                len = packet_read_line(0, buf, sizeof(buf));
  58        }
  59        if (len)
  60                return nak("expected flush");
  61
  62        packet_write(1, "ACK\n");
  63        packet_flush(1);
  64
  65        ac = 0;
  66        av[ac++] = "tar-tree";
  67        av[ac++] = hex;
  68        if (base)
  69                av[ac++] = base;
  70        av[ac++] = NULL;
  71        execv_git_cmd(av);
  72        /* should it return that is an error */
  73        return 1;
  74}