local-pull.con commit git-send-pack: documentation (9553d20)
   1/*
   2 * Copyright (C) 2005 Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "commit.h"
   6#include "pull.h"
   7
   8static int use_link = 0;
   9static int use_symlink = 0;
  10static int use_filecopy = 1;
  11
  12static char *path; /* "Remote" git repository */
  13
  14void prefetch(unsigned char *sha1)
  15{
  16}
  17
  18int fetch(unsigned char *sha1)
  19{
  20        static int object_name_start = -1;
  21        static char filename[PATH_MAX];
  22        char *hex = sha1_to_hex(sha1);
  23        const char *dest_filename = sha1_file_name(sha1);
  24
  25        if (object_name_start < 0) {
  26                strcpy(filename, path); /* e.g. git.git */
  27                strcat(filename, "/objects/");
  28                object_name_start = strlen(filename);
  29        }
  30        filename[object_name_start+0] = hex[0];
  31        filename[object_name_start+1] = hex[1];
  32        filename[object_name_start+2] = '/';
  33        strcpy(filename + object_name_start + 3, hex + 2);
  34        if (use_link) {
  35                if (!link(filename, dest_filename)) {
  36                        pull_say("link %s\n", hex);
  37                        return 0;
  38                }
  39                /* If we got ENOENT there is no point continuing. */
  40                if (errno == ENOENT) {
  41                        fprintf(stderr, "does not exist %s\n", filename);
  42                        return -1;
  43                }
  44        }
  45        if (use_symlink && !symlink(filename, dest_filename)) {
  46                pull_say("symlink %s\n", hex);
  47                return 0;
  48        }
  49        if (use_filecopy) {
  50                int ifd, ofd, status;
  51                struct stat st;
  52                void *map;
  53                ifd = open(filename, O_RDONLY);
  54                if (ifd < 0 || fstat(ifd, &st) < 0) {
  55                        close(ifd);
  56                        fprintf(stderr, "cannot open %s\n", filename);
  57                        return -1;
  58                }
  59                map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, ifd, 0);
  60                close(ifd);
  61                if (map == MAP_FAILED) {
  62                        fprintf(stderr, "cannot mmap %s\n", filename);
  63                        return -1;
  64                }
  65                ofd = open(dest_filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
  66                status = ((ofd < 0) ||
  67                          (write(ofd, map, st.st_size) != st.st_size));
  68                munmap(map, st.st_size);
  69                close(ofd);
  70                if (status)
  71                        fprintf(stderr, "cannot write %s\n", dest_filename);
  72                else
  73                        pull_say("copy %s\n", hex);
  74                return status;
  75        }
  76        fprintf(stderr, "failed to copy %s with given copy methods.\n", hex);
  77        return -1;
  78}
  79
  80int fetch_ref(char *ref, unsigned char *sha1)
  81{
  82        static int ref_name_start = -1;
  83        static char filename[PATH_MAX];
  84        static char hex[41];
  85        int ifd;
  86
  87        if (ref_name_start < 0) {
  88                sprintf(filename, "%s/refs/", path);
  89                ref_name_start = strlen(filename);
  90        }
  91        strcpy(filename + ref_name_start, ref);
  92        ifd = open(filename, O_RDONLY);
  93        if (ifd < 0) {
  94                close(ifd);
  95                fprintf(stderr, "cannot open %s\n", filename);
  96                return -1;
  97        }
  98        if (read(ifd, hex, 40) != 40 || get_sha1_hex(hex, sha1)) {
  99                close(ifd);
 100                fprintf(stderr, "cannot read from %s\n", filename);
 101                return -1;
 102        }
 103        close(ifd);
 104        pull_say("ref %s\n", sha1_to_hex(sha1));
 105        return 0;
 106}
 107
 108static const char local_pull_usage[] =
 109"git-local-pull [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [-l] [-s] [-n] commit-id path";
 110
 111/* 
 112 * By default we only use file copy.
 113 * If -l is specified, a hard link is attempted.
 114 * If -s is specified, then a symlink is attempted.
 115 * If -n is _not_ specified, then a regular file-to-file copy is done.
 116 */
 117int main(int argc, char **argv)
 118{
 119        char *commit_id;
 120        int arg = 1;
 121
 122        while (arg < argc && argv[arg][0] == '-') {
 123                if (argv[arg][1] == 't')
 124                        get_tree = 1;
 125                else if (argv[arg][1] == 'c')
 126                        get_history = 1;
 127                else if (argv[arg][1] == 'a') {
 128                        get_all = 1;
 129                        get_tree = 1;
 130                        get_history = 1;
 131                }
 132                else if (argv[arg][1] == 'l')
 133                        use_link = 1;
 134                else if (argv[arg][1] == 's')
 135                        use_symlink = 1;
 136                else if (argv[arg][1] == 'n')
 137                        use_filecopy = 0;
 138                else if (argv[arg][1] == 'v')
 139                        get_verbosely = 1;
 140                else if (argv[arg][1] == 'w')
 141                        write_ref = argv[++arg];
 142                else
 143                        usage(local_pull_usage);
 144                arg++;
 145        }
 146        if (argc < arg + 2)
 147                usage(local_pull_usage);
 148        commit_id = argv[arg];
 149        path = argv[arg + 1];
 150
 151        if (pull(commit_id))
 152                return 1;
 153
 154        return 0;
 155}