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 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
	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
	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);
}

D
David Rientjes 已提交
114
static void pack_objects(int fd, struct ref *refs)
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
{
	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
	 */
}
130

J
Junio C Hamano 已提交
131 132 133 134 135 136 137 138 139 140
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);
	}
}

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

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

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

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

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

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

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

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

201 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
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 已提交
232
static int send_pack(int in, int out, int nr_refspec, char **refspec)
233
{
234
	struct ref *ref;
235
	int new_refs;
236
	int ret = 0;
237 238
	int ask_for_status_report = 0;
	int expect_status_report = 0;
239

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

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

J
Junio C Hamano 已提交
248 249 250 251 252 253
	/* 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 已提交
254 255 256 257 258 259

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

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

		/* This part determines what can overwrite what.
		 * The rules are:
		 *
277 278
		 * (0) you can always use --force or +A:B notation to
		 *     selectively force individual ref pairs.
279 280 281 282 283 284 285 286 287 288 289
		 *
		 * (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.
		 */

290 291 292
		if (!force_update &&
		    !is_zero_sha1(ref->old_sha1) &&
		    !ref->force) {
293 294
			if (!has_sha1_file(ref->old_sha1) ||
			    !ref_newer(ref->peer_ref->new_sha1,
J
Junio C Hamano 已提交
295
				       ref->old_sha1)) {
296 297 298 299 300 301 302 303 304 305 306 307
				/* 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 已提交
308
				      ref->peer_ref->name);
309
				ret = -2;
J
Junio C Hamano 已提交
310 311
				continue;
			}
312
		}
J
Junio C Hamano 已提交
313 314 315
		memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20);
		if (is_zero_sha1(ref->new_sha1)) {
			error("cannot happen anymore");
316
			ret = -3;
317 318 319
			continue;
		}
		new_refs++;
320 321
		strcpy(old_hex, sha1_to_hex(ref->old_sha1));
		new_hex = sha1_to_hex(ref->new_sha1);
322 323 324 325 326 327 328 329 330 331 332

		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 已提交
333 334 335 336
		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);
337
	}
J
Junio C Hamano 已提交
338

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

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

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

J
Junio C Hamano 已提交
354

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

363
	setup_git_directory();
364 365
	git_config(git_default_config);

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

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