send-pack.c 9.8 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",
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 42
	static const char *args[4];
	int i = 0;
43

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

50
	args[i++] = "--stdin";
51

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

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

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

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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
/*
 * 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 已提交
149
static void pack_objects(int fd, struct ref *refs)
150 151 152 153 154
{
	pid_t rev_list_pid;

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

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

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

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

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

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

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

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

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

J
Junio C Hamano 已提交
230 231 232
static void get_local_heads(void)
{
	local_tail = &local_refs;
233
	for_each_ref(one_local_ref, NULL);
J
Junio C Hamano 已提交
234 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
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 已提交
267
static int send_pack(int in, int out, int nr_refspec, char **refspec)
268
{
269
	struct ref *ref;
270
	int new_refs;
271
	int ret = 0;
272 273
	int ask_for_status_report = 0;
	int expect_status_report = 0;
274

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

279 280 281 282
	/* Does the other end support the reporting? */
	if (server_supports("report-status"))
		ask_for_status_report = 1;

J
Junio C Hamano 已提交
283 284 285 286 287 288
	/* 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 已提交
289 290 291 292 293 294

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

295
	/*
J
Junio C Hamano 已提交
296
	 * Finally, tell the other end!
297
	 */
J
Junio C Hamano 已提交
298 299 300 301
	new_refs = 0;
	for (ref = remote_refs; ref; ref = ref->next) {
		char old_hex[60], *new_hex;
		if (!ref->peer_ref)
302
			continue;
303
		if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
304 305
			if (verbose)
				fprintf(stderr, "'%s': up-to-date\n", ref->name);
306 307 308 309 310 311
			continue;
		}

		/* This part determines what can overwrite what.
		 * The rules are:
		 *
312 313
		 * (0) you can always use --force or +A:B notation to
		 *     selectively force individual ref pairs.
314 315 316 317 318 319 320 321 322 323 324
		 *
		 * (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.
		 */

325 326 327
		if (!force_update &&
		    !is_zero_sha1(ref->old_sha1) &&
		    !ref->force) {
328 329
			if (!has_sha1_file(ref->old_sha1) ||
			    !ref_newer(ref->peer_ref->new_sha1,
J
Junio C Hamano 已提交
330
				       ref->old_sha1)) {
331 332 333 334 335 336 337 338 339 340 341 342
				/* 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 已提交
343
				      ref->peer_ref->name);
344
				ret = -2;
J
Junio C Hamano 已提交
345 346
				continue;
			}
347
		}
348
		hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
J
Junio C Hamano 已提交
349 350
		if (is_zero_sha1(ref->new_sha1)) {
			error("cannot happen anymore");
351
			ret = -3;
352 353 354
			continue;
		}
		new_refs++;
355 356
		strcpy(old_hex, sha1_to_hex(ref->old_sha1));
		new_hex = sha1_to_hex(ref->new_sha1);
357 358 359 360 361 362 363 364 365 366 367

		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 已提交
368 369 370 371
		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);
372
	}
J
Junio C Hamano 已提交
373

374
	packet_flush(out);
375
	if (new_refs)
J
Junio C Hamano 已提交
376
		pack_objects(out, remote_refs);
377
	close(out);
378 379 380 381 382 383 384 385

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

	if (!new_refs && ret == 0)
		fprintf(stderr, "Everything up-to-date\n");
386
	return ret;
387 388
}

J
Junio C Hamano 已提交
389

390 391 392 393 394
int main(int argc, char **argv)
{
	int i, nr_heads = 0;
	char *dest = NULL;
	char **heads = NULL;
395 396
	int fd[2], ret;
	pid_t pid;
397

398
	setup_git_directory();
399 400
	git_config(git_default_config);

401
	argv++;
402 403
	for (i = 1; i < argc; i++, argv++) {
		char *arg = *argv;
404 405 406 407 408 409

		if (*arg == '-') {
			if (!strncmp(arg, "--exec=", 7)) {
				exec = arg + 7;
				continue;
			}
410 411 412 413
			if (!strcmp(arg, "--all")) {
				send_all = 1;
				continue;
			}
414 415 416 417
			if (!strcmp(arg, "--force")) {
				force_update = 1;
				continue;
			}
418 419 420 421
			if (!strcmp(arg, "--verbose")) {
				verbose = 1;
				continue;
			}
422 423 424 425
			if (!strcmp(arg, "--thin")) {
				use_thin_pack = 1;
				continue;
			}
426 427
			usage(send_pack_usage);
		}
428 429 430 431
		if (!dest) {
			dest = arg;
			continue;
		}
432
		heads = argv;
433
		nr_heads = argc - i;
434 435 436 437
		break;
	}
	if (!dest)
		usage(send_pack_usage);
438 439
	if (heads && send_all)
		usage(send_pack_usage);
440
	pid = git_connect(fd, dest, exec);
441
	if (pid < 0)
442
		return 1;
443
	ret = send_pack(fd[0], fd[1], nr_heads, heads);
444 445
	close(fd[0]);
	close(fd[1]);
446 447
	ret |= finish_connect(pid);
	return !!ret;
448
}