send-pack.c 9.1 KB
Newer Older
1
#include "cache.h"
2
#include "commit.h"
3
#include "tag.h"
4
#include "refs.h"
5
#include "pkt-line.h"
6
#include "exec_cmd.h"
7

8
static const char send_pack_usage[] =
9 10
"git-send-pack [--all] [--exec=git-receive-pack] <remote> [<head>...]\n"
"  --all and explicit <head> specification are mutually exclusive.";
11
static const char *exec = "git-receive-pack";
12
static int verbose = 0;
13
static int send_all = 0;
14
static int force_update = 0;
15
static int use_thin_pack = 0;
16

17 18 19 20 21 22 23 24 25 26 27
static int is_zero_sha1(const unsigned char *sha1)
{
	int i;

	for (i = 0; i < 20; i++) {
		if (*sha1++)
			return 0;
	}
	return 1;
}

28 29
static void exec_pack_objects(void)
{
J
Junio C Hamano 已提交
30
	static const char *args[] = {
31
		"pack-objects",
32 33 34
		"--stdout",
		NULL
	};
35
	execv_git_cmd(args);
36 37 38 39 40
	die("git-pack-objects exec failed (%s)", strerror(errno));
}

static void exec_rev_list(struct ref *refs)
{
41
	struct ref *ref;
J
Junio C Hamano 已提交
42
	static const char *args[1000];
43
	int i = 0, j;
44

45
	args[i++] = "rev-list";	/* 0 */
46 47 48 49
	if (use_thin_pack)	/* 1 */
		args[i++] = "--objects-edge";
	else
		args[i++] = "--objects";
50 51 52 53

	/* First send the ones we care about most */
	for (ref = refs; ref; ref = ref->next) {
		if (900 < i)
54
			die("git-rev-list environment overflow");
55 56
		if (!is_zero_sha1(ref->new_sha1)) {
			char *buf = malloc(100);
57
			args[i++] = buf;
58
			snprintf(buf, 50, "%s", sha1_to_hex(ref->new_sha1));
59
			buf += 50;
60 61 62 63 64 65
			if (!is_zero_sha1(ref->old_sha1) &&
			    has_sha1_file(ref->old_sha1)) {
				args[i++] = buf;
				snprintf(buf, 50, "^%s",
					 sha1_to_hex(ref->old_sha1));
			}
66
		}
67 68 69 70 71 72 73 74 75 76 77 78
	}

	/* Then a handful of the remainder
	 * NEEDSWORK: we would be better off if used the newer ones first.
	 */
	for (ref = refs, j = i + 16;
	     i < 900 && i < j && ref;
	     ref = ref->next) {
		if (is_zero_sha1(ref->new_sha1) &&
		    !is_zero_sha1(ref->old_sha1) &&
		    has_sha1_file(ref->old_sha1)) {
			char *buf = malloc(42);
79
			args[i++] = buf;
80
			snprintf(buf, 42, "^%s", sha1_to_hex(ref->old_sha1));
81
		}
82 83
	}
	args[i] = NULL;
84
	execv_git_cmd(args);
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	die("git-rev-list exec failed (%s)", strerror(errno));
}

static void rev_list(int fd, struct ref *refs)
{
	int pipe_fd[2];
	pid_t pack_objects_pid;

	if (pipe(pipe_fd) < 0)
		die("rev-list setup: pipe failed");
	pack_objects_pid = fork();
	if (!pack_objects_pid) {
		dup2(pipe_fd[0], 0);
		dup2(fd, 1);
		close(pipe_fd[0]);
		close(pipe_fd[1]);
		close(fd);
		exec_pack_objects();
		die("pack-objects setup failed");
	}
	if (pack_objects_pid < 0)
		die("pack-objects fork failed");
	dup2(pipe_fd[1], 1);
	close(pipe_fd[0]);
	close(pipe_fd[1]);
	close(fd);
	exec_rev_list(refs);
}

static int pack_objects(int fd, struct ref *refs)
{
	pid_t rev_list_pid;

	rev_list_pid = fork();
	if (!rev_list_pid) {
		rev_list(fd, refs);
		die("rev-list setup failed");
	}
	if (rev_list_pid < 0)
		die("rev-list fork failed");
	/*
	 * We don't wait for the rev-list pipeline in the parent:
	 * we end up waiting for the other end instead
	 */
L
Linus Torvalds 已提交
129
	return 0;
130
}
131

J
Junio C Hamano 已提交
132 133 134 135 136 137 138 139 140 141
static void unmark_and_free(struct commit_list *list, unsigned int mark)
{
	while (list) {
		struct commit_list *temp = list;
		temp->item->object.flags &= ~mark;
		list = temp->next;
		free(temp);
	}
}

142 143
static int ref_newer(const unsigned char *new_sha1,
		     const unsigned char *old_sha1)
144
{
145 146
	struct object *o;
	struct commit *old, *new;
J
Junio C Hamano 已提交
147 148
	struct commit_list *list, *used;
	int found = 0;
149

150 151 152
	/* Both new and old must be commit-ish and new is descendant of
	 * old.  Otherwise we require --force.
	 */
153
	o = deref_tag(parse_object(old_sha1), NULL, 0);
154
	if (!o || o->type != commit_type)
155
		return 0;
156 157
	old = (struct commit *) o;

158
	o = deref_tag(parse_object(new_sha1), NULL, 0);
159
	if (!o || o->type != commit_type)
160
		return 0;
161 162
	new = (struct commit *) o;

163 164
	if (parse_commit(new) < 0)
		return 0;
J
Junio C Hamano 已提交
165 166

	used = list = NULL;
167
	commit_list_insert(new, &list);
L
Linus Torvalds 已提交
168 169
	while (list) {
		new = pop_most_recent_commit(&list, 1);
J
Junio C Hamano 已提交
170 171 172 173 174
		commit_list_insert(new, &used);
		if (new == old) {
			found = 1;
			break;
		}
175
	}
J
Junio C Hamano 已提交
176 177 178
	unmark_and_free(list, 1);
	unmark_and_free(used, 1);
	return found;
179 180
}

J
Junio C Hamano 已提交
181 182
static struct ref *local_refs, **local_tail;
static struct ref *remote_refs, **remote_tail;
183

J
Junio C Hamano 已提交
184
static int one_local_ref(const char *refname, const unsigned char *sha1)
185 186
{
	struct ref *ref;
J
Junio C Hamano 已提交
187 188
	int len = strlen(refname) + 1;
	ref = xcalloc(1, sizeof(*ref) + len);
189 190
	memcpy(ref->new_sha1, sha1, 20);
	memcpy(ref->name, refname, len);
J
Junio C Hamano 已提交
191 192
	*local_tail = ref;
	local_tail = &ref->next;
193 194 195
	return 0;
}

J
Junio C Hamano 已提交
196 197 198 199 200 201
static void get_local_heads(void)
{
	local_tail = &local_refs;
	for_each_ref(one_local_ref);
}

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
static int receive_status(int in)
{
	char line[1000];
	int ret = 0;
	int len = packet_read_line(in, line, sizeof(line));
	if (len < 10 || memcmp(line, "unpack ", 7)) {
		fprintf(stderr, "did not receive status back\n");
		return -1;
	}
	if (memcmp(line, "unpack ok\n", 10)) {
		fputs(line, stderr);
		ret = -1;
	}
	while (1) {
		len = packet_read_line(in, line, sizeof(line));
		if (!len)
			break;
		if (len < 3 ||
		    (memcmp(line, "ok", 2) && memcmp(line, "ng", 2))) {
			fprintf(stderr, "protocol error: %s\n", line);
			ret = -1;
			break;
		}
		if (!memcmp(line, "ok", 2))
			continue;
		fputs(line, stderr);
		ret = -1;
	}
	return ret;
}

J
Junio C Hamano 已提交
233
static int send_pack(int in, int out, int nr_refspec, char **refspec)
234
{
235
	struct ref *ref;
236
	int new_refs;
237
	int ret = 0;
238 239
	int ask_for_status_report = 0;
	int expect_status_report = 0;
240

J
Junio C Hamano 已提交
241
	/* No funny business with the matcher */
242
	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, 1);
J
Junio C Hamano 已提交
243
	get_local_heads();
244

245 246 247 248
	/* Does the other end support the reporting? */
	if (server_supports("report-status"))
		ask_for_status_report = 1;

J
Junio C Hamano 已提交
249 250 251 252 253 254
	/* match them up */
	if (!remote_tail)
		remote_tail = &remote_refs;
	if (match_refs(local_refs, remote_refs, &remote_tail,
		       nr_refspec, refspec, send_all))
		return -1;
D
Daniel Barkalow 已提交
255 256 257 258 259 260

	if (!remote_refs) {
		fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
		return 0;
	}

261
	/*
J
Junio C Hamano 已提交
262
	 * Finally, tell the other end!
263
	 */
J
Junio C Hamano 已提交
264 265 266 267
	new_refs = 0;
	for (ref = remote_refs; ref; ref = ref->next) {
		char old_hex[60], *new_hex;
		if (!ref->peer_ref)
268
			continue;
269
		if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) {
270 271
			if (verbose)
				fprintf(stderr, "'%s': up-to-date\n", ref->name);
272 273 274 275 276 277
			continue;
		}

		/* This part determines what can overwrite what.
		 * The rules are:
		 *
278 279
		 * (0) you can always use --force or +A:B notation to
		 *     selectively force individual ref pairs.
280 281 282 283 284 285 286 287 288 289 290
		 *
		 * (1) if the old thing does not exist, it is OK.
		 *
		 * (2) if you do not have the old thing, you are not allowed
		 *     to overwrite it; you would not know what you are losing
		 *     otherwise.
		 *
		 * (3) if both new and old are commit-ish, and new is a
		 *     descendant of old, it is OK.
		 */

291 292 293
		if (!force_update &&
		    !is_zero_sha1(ref->old_sha1) &&
		    !ref->force) {
294 295
			if (!has_sha1_file(ref->old_sha1) ||
			    !ref_newer(ref->peer_ref->new_sha1,
J
Junio C Hamano 已提交
296
				       ref->old_sha1)) {
297 298 299 300 301 302 303 304 305 306 307 308
				/* We do not have the remote ref, or
				 * we know that the remote ref is not
				 * an ancestor of what we are trying to
				 * push.  Either way this can be losing
				 * commits at the remote end and likely
				 * we were not up to date to begin with.
				 */
				error("remote '%s' is not a strict "
				      "subset of local ref '%s'. "
				      "maybe you are not up-to-date and "
				      "need to pull first?",
				      ref->name,
J
Junio C Hamano 已提交
309
				      ref->peer_ref->name);
310
				ret = -2;
J
Junio C Hamano 已提交
311 312
				continue;
			}
313
		}
J
Junio C Hamano 已提交
314 315 316
		memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20);
		if (is_zero_sha1(ref->new_sha1)) {
			error("cannot happen anymore");
317
			ret = -3;
318 319 320
			continue;
		}
		new_refs++;
321 322
		strcpy(old_hex, sha1_to_hex(ref->old_sha1));
		new_hex = sha1_to_hex(ref->new_sha1);
323 324 325 326 327 328 329 330 331 332 333

		if (ask_for_status_report) {
			packet_write(out, "%s %s %s%c%s",
				     old_hex, new_hex, ref->name, 0,
				     "report-status");
			ask_for_status_report = 0;
			expect_status_report = 1;
		}
		else
			packet_write(out, "%s %s %s",
				     old_hex, new_hex, ref->name);
J
Junio C Hamano 已提交
334 335 336 337
		fprintf(stderr, "updating '%s'", ref->name);
		if (strcmp(ref->name, ref->peer_ref->name))
			fprintf(stderr, " using '%s'", ref->peer_ref->name);
		fprintf(stderr, "\n  from %s\n  to   %s\n", old_hex, new_hex);
338
	}
J
Junio C Hamano 已提交
339

340
	packet_flush(out);
341
	if (new_refs)
J
Junio C Hamano 已提交
342
		pack_objects(out, remote_refs);
343
	close(out);
344 345 346 347 348 349 350 351

	if (expect_status_report) {
		if (receive_status(in))
			ret = -4;
	}

	if (!new_refs && ret == 0)
		fprintf(stderr, "Everything up-to-date\n");
352
	return ret;
353 354
}

J
Junio C Hamano 已提交
355

356 357 358 359 360
int main(int argc, char **argv)
{
	int i, nr_heads = 0;
	char *dest = NULL;
	char **heads = NULL;
361 362
	int fd[2], ret;
	pid_t pid;
363

364
	setup_git_directory();
365
	argv++;
366 367
	for (i = 1; i < argc; i++, argv++) {
		char *arg = *argv;
368 369 370 371 372 373

		if (*arg == '-') {
			if (!strncmp(arg, "--exec=", 7)) {
				exec = arg + 7;
				continue;
			}
374 375 376 377
			if (!strcmp(arg, "--all")) {
				send_all = 1;
				continue;
			}
378 379 380 381
			if (!strcmp(arg, "--force")) {
				force_update = 1;
				continue;
			}
382 383 384 385
			if (!strcmp(arg, "--verbose")) {
				verbose = 1;
				continue;
			}
386 387 388 389
			if (!strcmp(arg, "--thin")) {
				use_thin_pack = 1;
				continue;
			}
390 391
			usage(send_pack_usage);
		}
392 393 394 395
		if (!dest) {
			dest = arg;
			continue;
		}
396
		heads = argv;
397
		nr_heads = argc - i;
398 399 400 401
		break;
	}
	if (!dest)
		usage(send_pack_usage);
402 403
	if (heads && send_all)
		usage(send_pack_usage);
404
	pid = git_connect(fd, dest, exec);
405
	if (pid < 0)
406
		return 1;
407
	ret = send_pack(fd[0], fd[1], nr_heads, heads);
408 409
	close(fd[0]);
	close(fd[1]);
410
	finish_connect(pid);
411
	return ret;
412
}