send-pack.c 9.4 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
 * Make a pack stream and spit it out into file descriptor fd
19
 */
20
static int pack_objects(int fd, struct ref *refs)
21 22
{
	int pipe_fd[2];
23
	pid_t pid;
24 25

	if (pipe(pipe_fd) < 0)
26 27 28 29 30 31 32
		return error("send-pack: pipe failed");
	pid = fork();
	if (!pid) {
		/*
		 * The child becomes pack-objects --revs; we feed
		 * the revision parameters to it via its stdin and
		 * let its stdout go back to the other end.
33
		 */
34 35 36 37 38 39 40 41 42 43
		static const char *args[] = {
			"pack-objects",
			"--all-progress",
			"--revs",
			"--stdout",
			NULL,
			NULL,
		};
		if (use_thin_pack)
			args[4] = "--thin";
44 45 46 47 48
		dup2(pipe_fd[0], 0);
		dup2(fd, 1);
		close(pipe_fd[0]);
		close(pipe_fd[1]);
		close(fd);
49 50
		execv_git_cmd(args);
		die("git-pack-objects exec failed (%s)", strerror(errno));
51 52
	}

53 54 55
	/*
	 * We feed the pack-objects we just spawned with revision
	 * parameters by writing to the pipe.
56 57 58
	 */
	close(pipe_fd[0]);
	close(fd);
59

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
	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]);

79 80 81
	for (;;) {
		int status, code;
		pid_t waiting = waitpid(pid, &status, 0);
82

83 84 85 86 87 88 89 90 91 92 93 94
		if (waiting < 0) {
			if (errno == EINTR)
				continue;
			return error("waitpid failed (%s)", strerror(errno));
		}
		if ((waiting != pid) || WIFSIGNALED(status) ||
		    !WIFEXITED(status))
			return error("pack-objects died with strange error");
		code = WEXITSTATUS(status);
		if (code)
			return -code;
		return 0;
95 96
	}
}
97

J
Junio C Hamano 已提交
98 99 100 101 102 103 104 105 106 107
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);
	}
}

108 109
static int ref_newer(const unsigned char *new_sha1,
		     const unsigned char *old_sha1)
110
{
111 112
	struct object *o;
	struct commit *old, *new;
J
Junio C Hamano 已提交
113 114
	struct commit_list *list, *used;
	int found = 0;
115

116 117 118
	/* Both new and old must be commit-ish and new is descendant of
	 * old.  Otherwise we require --force.
	 */
119
	o = deref_tag(parse_object(old_sha1), NULL, 0);
120
	if (!o || o->type != OBJ_COMMIT)
121
		return 0;
122 123
	old = (struct commit *) o;

124
	o = deref_tag(parse_object(new_sha1), NULL, 0);
125
	if (!o || o->type != OBJ_COMMIT)
126
		return 0;
127 128
	new = (struct commit *) o;

129 130
	if (parse_commit(new) < 0)
		return 0;
J
Junio C Hamano 已提交
131 132

	used = list = NULL;
133
	commit_list_insert(new, &list);
L
Linus Torvalds 已提交
134 135
	while (list) {
		new = pop_most_recent_commit(&list, 1);
J
Junio C Hamano 已提交
136 137 138 139 140
		commit_list_insert(new, &used);
		if (new == old) {
			found = 1;
			break;
		}
141
	}
J
Junio C Hamano 已提交
142 143 144
	unmark_and_free(list, 1);
	unmark_and_free(used, 1);
	return found;
145 146
}

J
Junio C Hamano 已提交
147 148
static struct ref *local_refs, **local_tail;
static struct ref *remote_refs, **remote_tail;
149

150
static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
151 152
{
	struct ref *ref;
J
Junio C Hamano 已提交
153 154
	int len = strlen(refname) + 1;
	ref = xcalloc(1, sizeof(*ref) + len);
155
	hashcpy(ref->new_sha1, sha1);
156
	memcpy(ref->name, refname, len);
J
Junio C Hamano 已提交
157 158
	*local_tail = ref;
	local_tail = &ref->next;
159 160 161
	return 0;
}

J
Junio C Hamano 已提交
162 163 164
static void get_local_heads(void)
{
	local_tail = &local_refs;
165
	for_each_ref(one_local_ref, NULL);
J
Junio C Hamano 已提交
166 167
}

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
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 已提交
199
static int send_pack(int in, int out, int nr_refspec, char **refspec)
200
{
201
	struct ref *ref;
202
	int new_refs;
203
	int ret = 0;
204
	int ask_for_status_report = 0;
205
	int allow_deleting_refs = 0;
206
	int expect_status_report = 0;
207

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

212 213 214
	/* Does the other end support the reporting? */
	if (server_supports("report-status"))
		ask_for_status_report = 1;
215 216
	if (server_supports("delete-refs"))
		allow_deleting_refs = 1;
217

J
Junio C Hamano 已提交
218 219 220 221 222 223
	/* 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 已提交
224 225 226 227 228 229

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

230
	/*
J
Junio C Hamano 已提交
231
	 * Finally, tell the other end!
232
	 */
J
Junio C Hamano 已提交
233 234 235
	new_refs = 0;
	for (ref = remote_refs; ref; ref = ref->next) {
		char old_hex[60], *new_hex;
236 237
		int delete_ref;

J
Junio C Hamano 已提交
238
		if (!ref->peer_ref)
239
			continue;
240 241 242 243 244 245 246 247 248

		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)) {
249 250
			if (verbose)
				fprintf(stderr, "'%s': up-to-date\n", ref->name);
251 252 253 254 255 256
			continue;
		}

		/* This part determines what can overwrite what.
		 * The rules are:
		 *
257 258
		 * (0) you can always use --force or +A:B notation to
		 *     selectively force individual ref pairs.
259 260 261 262 263 264 265 266 267
		 *
		 * (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.
268 269 270
		 *
		 * (4) regardless of all of the above, removing :B is
		 *     always allowed.
271 272
		 */

273
		if (!force_update &&
274
		    !delete_ref &&
J
Junio C Hamano 已提交
275
		    !is_null_sha1(ref->old_sha1) &&
276
		    !ref->force) {
277 278
			if (!has_sha1_file(ref->old_sha1) ||
			    !ref_newer(ref->peer_ref->new_sha1,
J
Junio C Hamano 已提交
279
				       ref->old_sha1)) {
280 281 282 283 284 285 286 287 288 289 290 291
				/* 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 已提交
292
				      ref->peer_ref->name);
293
				ret = -2;
J
Junio C Hamano 已提交
294 295
				continue;
			}
296
		}
297
		hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
298 299
		if (!delete_ref)
			new_refs++;
300 301
		strcpy(old_hex, sha1_to_hex(ref->old_sha1));
		new_hex = sha1_to_hex(ref->new_sha1);
302 303 304 305 306 307 308 309 310 311 312

		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);
313 314 315 316 317 318 319 320 321 322
		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);
		}
323
	}
J
Junio C Hamano 已提交
324

325
	packet_flush(out);
326
	if (new_refs)
327
		ret = pack_objects(out, remote_refs);
328
	close(out);
329 330 331 332 333 334 335 336

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

	if (!new_refs && ret == 0)
		fprintf(stderr, "Everything up-to-date\n");
337
	return ret;
338 339
}

340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
static void verify_remote_names(int nr_heads, char **heads)
{
	int i;

	for (i = 0; i < nr_heads; i++) {
		const char *remote = strchr(heads[i], ':');

		remote = remote ? (remote + 1) : heads[i];
		switch (check_ref_format(remote)) {
		case 0: /* ok */
		case -2: /* ok but a single level -- that is fine for
			  * a match pattern.
			  */
			continue;
		}
		die("remote part of refspec is not a valid name in %s",
		    heads[i]);
	}
}
J
Junio C Hamano 已提交
359

360 361 362 363 364
int main(int argc, char **argv)
{
	int i, nr_heads = 0;
	char *dest = NULL;
	char **heads = NULL;
365 366
	int fd[2], ret;
	pid_t pid;
367

368
	setup_git_directory();
369 370
	git_config(git_default_config);

371
	argv++;
372 373
	for (i = 1; i < argc; i++, argv++) {
		char *arg = *argv;
374 375 376 377 378 379

		if (*arg == '-') {
			if (!strncmp(arg, "--exec=", 7)) {
				exec = arg + 7;
				continue;
			}
380 381 382 383
			if (!strcmp(arg, "--all")) {
				send_all = 1;
				continue;
			}
384 385 386 387
			if (!strcmp(arg, "--force")) {
				force_update = 1;
				continue;
			}
388 389 390 391
			if (!strcmp(arg, "--verbose")) {
				verbose = 1;
				continue;
			}
392 393 394 395
			if (!strcmp(arg, "--thin")) {
				use_thin_pack = 1;
				continue;
			}
396 397
			usage(send_pack_usage);
		}
398 399 400 401
		if (!dest) {
			dest = arg;
			continue;
		}
402
		heads = argv;
403
		nr_heads = argc - i;
404 405 406 407
		break;
	}
	if (!dest)
		usage(send_pack_usage);
408 409
	if (heads && send_all)
		usage(send_pack_usage);
410 411
	verify_remote_names(nr_heads, heads);

412
	pid = git_connect(fd, dest, exec);
413
	if (pid < 0)
414
		return 1;
415
	ret = send_pack(fd[0], fd[1], nr_heads, heads);
416 417
	close(fd[0]);
	close(fd[1]);
418 419
	ret |= finish_connect(pid);
	return !!ret;
420
}