send-pack.c 10.3 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 13 14 15
static int verbose;
static int send_all;
static int force_update;
static int use_thin_pack;
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",
N
Nicolas Pitre 已提交
32
		"--all-progress",
33 34 35
		"--stdout",
		NULL
	};
36
	execv_git_cmd(args);
37 38 39 40 41
	die("git-pack-objects exec failed (%s)", strerror(errno));
}

static void exec_rev_list(struct ref *refs)
{
42 43
	static const char *args[4];
	int i = 0;
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
	args[i++] = "--stdin";
52

53
	args[i] = NULL;
54
	execv_git_cmd(args);
55 56 57
	die("git-rev-list exec failed (%s)", strerror(errno));
}

58 59 60
/*
 * Run "rev-list --stdin | pack-objects" pipe.
 */
61 62 63 64 65 66 67 68 69
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) {
70 71 72
		/* The child becomes pack-objects; reads from pipe
		 * and writes to the original fd
		 */
73 74 75 76 77 78 79 80 81 82
		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");
83 84

	/* We become rev-list --stdin; output goes to pipe. */
85 86 87 88 89 90 91
	dup2(pipe_fd[1], 1);
	close(pipe_fd[0]);
	close(pipe_fd[1]);
	close(fd);
	exec_rev_list(refs);
}

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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
/*
 * Create "rev-list --stdin | pack-objects" pipe and feed
 * the refs into the pipeline.
 */
static void rev_list_generate(int fd, struct ref *refs)
{
	int pipe_fd[2];
	pid_t rev_list_generate_pid;

	if (pipe(pipe_fd) < 0)
		die("rev-list-generate setup: pipe failed");
	rev_list_generate_pid = fork();
	if (!rev_list_generate_pid) {
		/* The child becomes the "rev-list | pack-objects"
		 * pipeline.  It takes input from us, and its output
		 * goes to fd.
		 */
		dup2(pipe_fd[0], 0);
		dup2(fd, 1);
		close(pipe_fd[0]);
		close(pipe_fd[1]);
		close(fd);
		rev_list(fd, refs);
		die("rev-list setup failed");
	}
	if (rev_list_generate_pid < 0)
		die("rev-list-generate fork failed");

	/* We feed the rev parameters to them.  We do not write into
	 * fd nor read from the pipe.
	 */
	close(pipe_fd[0]);
	close(fd);
	while (refs) {
		char buf[42];

		if (!is_null_sha1(refs->old_sha1) &&
		    has_sha1_file(refs->old_sha1)) {
			memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
			buf[0] = '^';
			buf[41] = '\n';
			write(pipe_fd[1], buf, 42);
		}
		if (!is_null_sha1(refs->new_sha1)) {
			memcpy(buf, sha1_to_hex(refs->new_sha1), 40);
			buf[40] = '\n';
			write(pipe_fd[1], buf, 41);
		}
		refs = refs->next;
	}
	close(pipe_fd[1]);
	// waitpid(rev_list_generate_pid);
	exit(0);
}

/*
 * Make a pack stream and spit it out into file descriptor fd
 */
D
David Rientjes 已提交
150
static void pack_objects(int fd, struct ref *refs)
151 152 153 154 155
{
	pid_t rev_list_pid;

	rev_list_pid = fork();
	if (!rev_list_pid) {
156
		rev_list_generate(fd, refs);
157 158 159 160 161 162 163 164 165
		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
	 */
}
166

J
Junio C Hamano 已提交
167 168 169 170 171 172 173 174 175 176
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);
	}
}

177 178
static int ref_newer(const unsigned char *new_sha1,
		     const unsigned char *old_sha1)
179
{
180 181
	struct object *o;
	struct commit *old, *new;
J
Junio C Hamano 已提交
182 183
	struct commit_list *list, *used;
	int found = 0;
184

185 186 187
	/* Both new and old must be commit-ish and new is descendant of
	 * old.  Otherwise we require --force.
	 */
188
	o = deref_tag(parse_object(old_sha1), NULL, 0);
189
	if (!o || o->type != OBJ_COMMIT)
190
		return 0;
191 192
	old = (struct commit *) o;

193
	o = deref_tag(parse_object(new_sha1), NULL, 0);
194
	if (!o || o->type != OBJ_COMMIT)
195
		return 0;
196 197
	new = (struct commit *) o;

198 199
	if (parse_commit(new) < 0)
		return 0;
J
Junio C Hamano 已提交
200 201

	used = list = NULL;
202
	commit_list_insert(new, &list);
L
Linus Torvalds 已提交
203 204
	while (list) {
		new = pop_most_recent_commit(&list, 1);
J
Junio C Hamano 已提交
205 206 207 208 209
		commit_list_insert(new, &used);
		if (new == old) {
			found = 1;
			break;
		}
210
	}
J
Junio C Hamano 已提交
211 212 213
	unmark_and_free(list, 1);
	unmark_and_free(used, 1);
	return found;
214 215
}

J
Junio C Hamano 已提交
216 217
static struct ref *local_refs, **local_tail;
static struct ref *remote_refs, **remote_tail;
218

219
static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
220 221
{
	struct ref *ref;
J
Junio C Hamano 已提交
222 223
	int len = strlen(refname) + 1;
	ref = xcalloc(1, sizeof(*ref) + len);
224
	hashcpy(ref->new_sha1, sha1);
225
	memcpy(ref->name, refname, len);
J
Junio C Hamano 已提交
226 227
	*local_tail = ref;
	local_tail = &ref->next;
228 229 230
	return 0;
}

J
Junio C Hamano 已提交
231 232 233
static void get_local_heads(void)
{
	local_tail = &local_refs;
234
	for_each_ref(one_local_ref, NULL);
J
Junio C Hamano 已提交
235 236
}

237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
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 已提交
268
static int send_pack(int in, int out, int nr_refspec, char **refspec)
269
{
270
	struct ref *ref;
271
	int new_refs;
272
	int ret = 0;
273
	int ask_for_status_report = 0;
274
	int allow_deleting_refs = 0;
275
	int expect_status_report = 0;
276

J
Junio C Hamano 已提交
277
	/* No funny business with the matcher */
L
Linus Torvalds 已提交
278
	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
J
Junio C Hamano 已提交
279
	get_local_heads();
280

281 282 283
	/* Does the other end support the reporting? */
	if (server_supports("report-status"))
		ask_for_status_report = 1;
284 285
	if (server_supports("delete-refs"))
		allow_deleting_refs = 1;
286

J
Junio C Hamano 已提交
287 288 289 290 291 292
	/* 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 已提交
293 294 295 296 297 298

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

299
	/*
J
Junio C Hamano 已提交
300
	 * Finally, tell the other end!
301
	 */
J
Junio C Hamano 已提交
302 303 304
	new_refs = 0;
	for (ref = remote_refs; ref; ref = ref->next) {
		char old_hex[60], *new_hex;
305 306
		int delete_ref;

J
Junio C Hamano 已提交
307
		if (!ref->peer_ref)
308
			continue;
309 310 311 312 313 314 315 316 317

		delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
		if (delete_ref && !allow_deleting_refs) {
			error("remote does not support deleting refs");
			ret = -2;
			continue;
		}
		if (!delete_ref &&
		    !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
318 319
			if (verbose)
				fprintf(stderr, "'%s': up-to-date\n", ref->name);
320 321 322 323 324 325
			continue;
		}

		/* This part determines what can overwrite what.
		 * The rules are:
		 *
326 327
		 * (0) you can always use --force or +A:B notation to
		 *     selectively force individual ref pairs.
328 329 330 331 332 333 334 335 336
		 *
		 * (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.
337 338 339
		 *
		 * (4) regardless of all of the above, removing :B is
		 *     always allowed.
340 341
		 */

342
		if (!force_update &&
343
		    !delete_ref &&
344 345
		    !is_zero_sha1(ref->old_sha1) &&
		    !ref->force) {
346 347
			if (!has_sha1_file(ref->old_sha1) ||
			    !ref_newer(ref->peer_ref->new_sha1,
J
Junio C Hamano 已提交
348
				       ref->old_sha1)) {
349 350 351 352 353 354 355 356 357 358 359 360
				/* 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 已提交
361
				      ref->peer_ref->name);
362
				ret = -2;
J
Junio C Hamano 已提交
363 364
				continue;
			}
365
		}
366
		hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
367 368
		if (!delete_ref)
			new_refs++;
369 370
		strcpy(old_hex, sha1_to_hex(ref->old_sha1));
		new_hex = sha1_to_hex(ref->new_sha1);
371 372 373 374 375 376 377 378 379 380 381

		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);
382 383 384 385 386 387 388 389 390 391
		if (delete_ref)
			fprintf(stderr, "deleting '%s'\n", ref->name);
		else {
			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);
		}
392
	}
J
Junio C Hamano 已提交
393

394
	packet_flush(out);
395
	if (new_refs)
J
Junio C Hamano 已提交
396
		pack_objects(out, remote_refs);
397
	close(out);
398 399 400 401 402 403 404 405

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

	if (!new_refs && ret == 0)
		fprintf(stderr, "Everything up-to-date\n");
406
	return ret;
407 408
}

J
Junio C Hamano 已提交
409

410 411 412 413 414
int main(int argc, char **argv)
{
	int i, nr_heads = 0;
	char *dest = NULL;
	char **heads = NULL;
415 416
	int fd[2], ret;
	pid_t pid;
417

418
	setup_git_directory();
419 420
	git_config(git_default_config);

421
	argv++;
422 423
	for (i = 1; i < argc; i++, argv++) {
		char *arg = *argv;
424 425 426 427 428 429

		if (*arg == '-') {
			if (!strncmp(arg, "--exec=", 7)) {
				exec = arg + 7;
				continue;
			}
430 431 432 433
			if (!strcmp(arg, "--all")) {
				send_all = 1;
				continue;
			}
434 435 436 437
			if (!strcmp(arg, "--force")) {
				force_update = 1;
				continue;
			}
438 439 440 441
			if (!strcmp(arg, "--verbose")) {
				verbose = 1;
				continue;
			}
442 443 444 445
			if (!strcmp(arg, "--thin")) {
				use_thin_pack = 1;
				continue;
			}
446 447
			usage(send_pack_usage);
		}
448 449 450 451
		if (!dest) {
			dest = arg;
			continue;
		}
452
		heads = argv;
453
		nr_heads = argc - i;
454 455 456 457
		break;
	}
	if (!dest)
		usage(send_pack_usage);
458 459
	if (heads && send_all)
		usage(send_pack_usage);
460
	pid = git_connect(fd, dest, exec);
461
	if (pid < 0)
462
		return 1;
463
	ret = send_pack(fd[0], fd[1], nr_heads, heads);
464 465
	close(fd[0]);
	close(fd[1]);
466 467
	ret |= finish_connect(pid);
	return !!ret;
468
}