5 static const char receive_pack_usage[] = "git-receive-pack [--unpack=executable] <git-dir> [heads]";
7 static const char *unpacker = "git-unpack-objects";
9 static int path_match(const char *path, int nr, char **match)
12 int pathlen = strlen(path);
14 for (i = 0; i < nr; i++) {
18 if (!len || len > pathlen)
20 if (memcmp(path + pathlen - len, s, len))
22 if (pathlen > len && path[pathlen - len - 1] != '/')
30 static void show_ref(const char *path, unsigned char *sha1)
32 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
35 static int read_ref(const char *path, unsigned char *sha1)
38 int fd = open(path, O_RDONLY);
42 if (read(fd, buffer, sizeof(buffer)) >= 40)
43 ret = get_sha1_hex(buffer, sha1);
49 static void write_head_info(const char *base, int nr, char **match)
51 DIR *dir = opendir(base);
55 int baselen = strlen(base);
56 char *path = xmalloc(baselen + 257);
57 memcpy(path, base, baselen);
59 while ((de = readdir(dir)) != NULL) {
64 if (de->d_name[0] == '.')
66 namelen = strlen(de->d_name);
69 memcpy(path + baselen, de->d_name, namelen+1);
70 if (lstat(path, &st) < 0)
72 if (S_ISDIR(st.st_mode)) {
73 path[baselen + namelen] = '/';
74 path[baselen + namelen + 1] = 0;
75 write_head_info(path, nr, match);
78 if (read_ref(path, sha1) < 0)
80 if (nr && !path_match(path, nr, match))
94 struct line *commands = NULL;
97 * This gets called after(if) we've successfully
98 * unpacked the data payload.
100 static void execute_commands(void)
102 struct line *line = commands;
105 fprintf(stderr, "%s", line->data);
110 static void read_head_info(void)
112 struct line **p = &commands;
114 static char line[1000];
115 int len = packet_read_line(0, line, sizeof(line));
119 n = xmalloc(sizeof(struct line) + len);
121 memcpy(n->data, line + 4, len - 3);
127 static void unpack(void)
132 die("unpack fork failed");
134 setenv("GIT_DIR", ".", 1);
135 execlp(unpacker, unpacker, NULL);
136 die("unpack execute failed");
141 int retval = waitpid(pid, &status, 0);
146 die("waitpid failed (%s)", strerror(retval));
149 die("waitpid is confused");
150 if (WIFSIGNALED(status))
151 die("%s died of signal %d", unpacker, WTERMSIG(status));
152 if (!WIFEXITED(status))
153 die("%s died out of really strange complications", unpacker);
154 code = WEXITSTATUS(status);
156 die("%s exited with error code %d", unpacker, code);
161 int main(int argc, char **argv)
164 const char *dir = NULL;
168 for (i = 1; i < argc; i++) {
169 const char *arg = *argv++;
172 if (!strncmp(arg, "--unpack=", 9)) {
176 /* Do flag handling here */
177 usage(receive_pack_usage);
181 nr_heads = argc - i - 1;
185 usage(receive_pack_usage);
187 /* chdir to the directory. If that fails, try appending ".git" */
188 if (chdir(dir) < 0) {
189 static char path[PATH_MAX];
190 snprintf(path, sizeof(path), "%s.git", dir);
192 die("unable to cd to %s", dir);
195 /* If we have a ".git" directory, chdir to it */
198 if (access("objects", X_OK) < 0 || access("refs/heads", X_OK) < 0)
199 die("%s doesn't appear to be a git directory", dir);
200 write_head_info("refs/", nr_heads, heads);