update-index.c 20.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/*
 * GIT - The information manager from hell
 *
 * Copyright (C) Linus Torvalds, 2005
 */
6
#include "cache.h"
7
#include "quote.h"
J
Junio C Hamano 已提交
8
#include "cache-tree.h"
J
Junio C Hamano 已提交
9
#include "tree-walk.h"
10
#include "builtin.h"
11
#include "refs.h"
12
#include "resolve-undo.h"
13

14 15 16 17
/*
 * Default to not allowing changes to the list of files. The
 * tool doesn't actually care, but this makes it harder to add
 * files to the revision control by mistake by doing something
18
 * like "git update-index *" and suddenly having all the object
19 20
 * files be revision controlled.
 */
J
Junio C Hamano 已提交
21 22 23 24
static int allow_add;
static int allow_remove;
static int allow_replace;
static int info_only;
25
static int force_remove;
J
Junio C Hamano 已提交
26
static int verbose;
27
static int mark_valid_only;
28
static int mark_skip_worktree_only;
29 30
#define MARK_FLAG 1
#define UNMARK_FLAG 2
J
Junio C Hamano 已提交
31

32
__attribute__((format (printf, 1, 2)))
J
Junio C Hamano 已提交
33 34 35 36 37 38 39 40 41 42 43 44 45
static void report(const char *fmt, ...)
{
	va_list vp;

	if (!verbose)
		return;

	va_start(vp, fmt);
	vprintf(fmt, vp);
	putchar('\n');
	va_end(vp);
}

46
static int mark_ce_flags(const char *path, int flag, int mark)
J
Junio C Hamano 已提交
47 48 49 50
{
	int namelen = strlen(path);
	int pos = cache_name_pos(path, namelen);
	if (0 <= pos) {
51 52 53 54
		if (mark)
			active_cache[pos]->ce_flags |= flag;
		else
			active_cache[pos]->ce_flags &= ~flag;
J
Junio C Hamano 已提交
55
		cache_tree_invalidate_path(active_cache_tree, path);
J
Junio C Hamano 已提交
56 57 58 59 60 61
		active_cache_changed = 1;
		return 0;
	}
	return -1;
}

62
static int remove_one_path(const char *path)
63
{
64 65 66 67 68 69
	if (!allow_remove)
		return error("%s: does not exist and --remove not passed", path);
	if (remove_file_from_cache(path))
		return error("%s: cannot remove from the index", path);
	return 0;
}
J
Junio C Hamano 已提交
70

71 72 73 74 75 76 77 78 79 80 81 82 83
/*
 * Handle a path that couldn't be lstat'ed. It's either:
 *  - missing file (ENOENT or ENOTDIR). That's ok if we're
 *    supposed to be removing it and the removal actually
 *    succeeds.
 *  - permission error. That's never ok.
 */
static int process_lstat_error(const char *path, int err)
{
	if (err == ENOENT || err == ENOTDIR)
		return remove_one_path(path);
	return error("lstat(\"%s\"): %s", path, strerror(errno));
}
J
Junio C Hamano 已提交
84

85 86
static int add_one_path(struct cache_entry *old, const char *path, int len, struct stat *st)
{
87 88
	int option, size;
	struct cache_entry *ce;
J
Junio C Hamano 已提交
89

90 91 92 93 94 95
	/* Was the old index entry already up-to-date? */
	if (old && !ce_stage(old) && !ce_match_stat(old, st, 0))
		return 0;

	size = cache_entry_size(len);
	ce = xcalloc(1, size);
96
	memcpy(ce->name, path, len);
97
	ce->ce_flags = len;
98 99
	fill_stat_cache_info(ce, st);
	ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
100

101
	if (index_path(ce->sha1, path, st, !info_only))
102
		return -1;
103 104
	option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
	option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
105
	if (add_cache_entry(ce, option))
106
		return error("%s: cannot add to the index - missing --add option?", path);
107
	return 0;
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
/*
 * Handle a path that was a directory. Four cases:
 *
 *  - it's already a gitlink in the index, and we keep it that
 *    way, and update it if we can (if we cannot find the HEAD,
 *    we're going to keep it unchanged in the index!)
 *
 *  - it's a *file* in the index, in which case it should be
 *    removed as a file if removal is allowed, since it doesn't
 *    exist as such any more. If removal isn't allowed, it's
 *    an error.
 *
 *    (NOTE! This is old and arguably fairly strange behaviour.
 *    We might want to make this an error unconditionally, and
 *    use "--force-remove" if you actually want to force removal).
 *
 *  - it used to exist as a subdirectory (ie multiple files with
 *    this particular prefix) in the index, in which case it's wrong
 *    to try to update it as a directory.
 *
 *  - it doesn't exist at all in the index, but it is a valid
 *    git directory, and it should be *added* as a gitlink.
 */
static int process_directory(const char *path, int len, struct stat *st)
{
	unsigned char sha1[20];
	int pos = cache_name_pos(path, len);

	/* Exact match: file or existing gitlink */
	if (pos >= 0) {
		struct cache_entry *ce = active_cache[pos];
141
		if (S_ISGITLINK(ce->ce_mode)) {
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178

			/* Do nothing to the index if there is no HEAD! */
			if (resolve_gitlink_ref(path, "HEAD", sha1) < 0)
				return 0;

			return add_one_path(ce, path, len, st);
		}
		/* Should this be an unconditional error? */
		return remove_one_path(path);
	}

	/* Inexact match: is there perhaps a subdirectory match? */
	pos = -pos-1;
	while (pos < active_nr) {
		struct cache_entry *ce = active_cache[pos++];

		if (strncmp(ce->name, path, len))
			break;
		if (ce->name[len] > '/')
			break;
		if (ce->name[len] < '/')
			continue;

		/* Subdirectory match - error out */
		return error("%s: is a directory - add individual files instead", path);
	}

	/* No match - should we add it as a gitlink? */
	if (!resolve_gitlink_ref(path, "HEAD", sha1))
		return add_one_path(NULL, path, len, st);

	/* Error out. */
	return error("%s: is a directory - add files inside instead", path);
}

static int process_path(const char *path)
{
179
	int pos, len;
180
	struct stat st;
181
	struct cache_entry *ce;
182

183
	len = strlen(path);
184
	if (has_symlink_leading_path(path, len))
185 186
		return error("'%s' is beyond a symbolic link", path);

187 188 189 190 191 192 193 194 195 196 197 198 199
	pos = cache_name_pos(path, len);
	ce = pos < 0 ? NULL : active_cache[pos];
	if (ce && ce_skip_worktree(ce)) {
		/*
		 * working directory version is assumed "good"
		 * so updating it does not make sense.
		 * On the other hand, removing it from index should work
		 */
		if (allow_remove && remove_file_from_cache(path))
			return error("%s: cannot remove from the index", path);
		return 0;
	}

200 201 202 203 204 205 206 207 208 209
	/*
	 * First things first: get the stat information, to decide
	 * what to do about the pathname!
	 */
	if (lstat(path, &st) < 0)
		return process_lstat_error(path, errno);

	if (S_ISDIR(st.st_mode))
		return process_directory(path, len, &st);

210 211 212 213 214 215 216
	/*
	 * Process a regular file
	 */
	if (ce && S_ISGITLINK(ce->ce_mode))
		return error("%s is already a gitlink, not replacing", path);

	return add_one_path(ce, path, len, &st);
217 218
}

219 220
static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
			 const char *path, int stage)
221
{
222
	int size, len, option;
223 224
	struct cache_entry *ce;

225
	if (!verify_path(path))
226
		return error("Invalid path '%s'", path);
227

228
	len = strlen(path);
229
	size = cache_entry_size(len);
230
	ce = xcalloc(1, size);
231

232
	hashcpy(ce->sha1, sha1);
233 234
	memcpy(ce->name, path, len);
	ce->ce_flags = create_ce_flags(len, stage);
235
	ce->ce_mode = create_ce_mode(mode);
J
Junio C Hamano 已提交
236
	if (assume_unchanged)
237
		ce->ce_flags |= CE_VALID;
238 239
	option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
	option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
J
Junio C Hamano 已提交
240 241
	if (add_cache_entry(ce, option))
		return error("%s: cannot add to the index - missing --add option?",
242 243
			     path);
	report("add '%s'", path);
J
Junio C Hamano 已提交
244
	return 0;
245 246
}

247
static void chmod_path(int flip, const char *path)
J
Junio C Hamano 已提交
248 249 250 251
{
	int pos;
	struct cache_entry *ce;
	unsigned int mode;
252

J
Junio C Hamano 已提交
253 254
	pos = cache_name_pos(path, strlen(path));
	if (pos < 0)
255
		goto fail;
J
Junio C Hamano 已提交
256
	ce = active_cache[pos];
257
	mode = ce->ce_mode;
J
Junio C Hamano 已提交
258
	if (!S_ISREG(mode))
259
		goto fail;
J
Junio C Hamano 已提交
260 261
	switch (flip) {
	case '+':
262
		ce->ce_mode |= 0111; break;
J
Junio C Hamano 已提交
263
	case '-':
264
		ce->ce_mode &= ~0111; break;
J
Junio C Hamano 已提交
265
	default:
266
		goto fail;
J
Junio C Hamano 已提交
267
	}
J
Junio C Hamano 已提交
268
	cache_tree_invalidate_path(active_cache_tree, path);
J
Junio C Hamano 已提交
269
	active_cache_changed = 1;
270 271 272
	report("chmod %cx '%s'", flip, path);
	return;
 fail:
273
	die("git update-index: cannot chmod %cx '%s'", flip, path);
J
Junio C Hamano 已提交
274 275
}

J
Junio C Hamano 已提交
276 277 278 279 280
static void update_one(const char *path, const char *prefix, int prefix_length)
{
	const char *p = prefix_path(prefix, prefix_length, path);
	if (!verify_path(p)) {
		fprintf(stderr, "Ignoring path %s\n", path);
281
		goto free_return;
J
Junio C Hamano 已提交
282
	}
J
Junio C Hamano 已提交
283
	if (mark_valid_only) {
284
		if (mark_ce_flags(p, CE_VALID, mark_valid_only == MARK_FLAG))
J
Junio C Hamano 已提交
285
			die("Unable to mark file %s", path);
286
		goto free_return;
J
Junio C Hamano 已提交
287
	}
288 289
	if (mark_skip_worktree_only) {
		if (mark_ce_flags(p, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG))
J
Junio C Hamano 已提交
290
			die("Unable to mark file %s", path);
291
		goto free_return;
J
Junio C Hamano 已提交
292 293
	}

J
Junio C Hamano 已提交
294 295
	if (force_remove) {
		if (remove_file_from_cache(p))
296
			die("git update-index: unable to remove %s", path);
J
Junio C Hamano 已提交
297
		report("remove '%s'", path);
298
		goto free_return;
J
Junio C Hamano 已提交
299
	}
300 301
	if (process_path(p))
		die("Unable to process path %s", path);
J
Junio C Hamano 已提交
302
	report("add '%s'", path);
303
 free_return:
304
	if (p < path || p > path + strlen(path))
305
		free((char *)p);
J
Junio C Hamano 已提交
306 307
}

308 309
static void read_index_info(int line_termination)
{
310 311
	struct strbuf buf = STRBUF_INIT;
	struct strbuf uq = STRBUF_INIT;
312 313

	while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
314
		char *ptr, *tab;
315
		char *path_name;
316 317
		unsigned char sha1[20];
		unsigned int mode;
318
		unsigned long ul;
319 320 321 322 323
		int stage;

		/* This reads lines formatted in one of three formats:
		 *
		 * (1) mode         SP sha1          TAB path
324
		 * The first format is what "git apply --index-info"
325 326 327 328 329
		 * reports, and used to reconstruct a partial tree
		 * that is used for phony merge base tree when falling
		 * back on 3-way merge.
		 *
		 * (2) mode SP type SP sha1          TAB path
330
		 * The second format is to stuff "git ls-tree" output
331
		 * into the index file.
332
		 *
333 334
		 * (3) mode         SP sha1 SP stage TAB path
		 * This format is to put higher order stages into the
335
		 * index file and matches "git ls-files --stage" output.
336
		 */
337 338 339 340
		errno = 0;
		ul = strtoul(buf.buf, &ptr, 8);
		if (ptr == buf.buf || *ptr != ' '
		    || errno || (unsigned int) ul != ul)
341
			goto bad_line;
342
		mode = ul;
343

344 345 346
		tab = strchr(ptr, '\t');
		if (!tab || tab - ptr < 41)
			goto bad_line;
347

348
		if (tab[-2] == ' ' && '0' <= tab[-1] && tab[-1] <= '3') {
349 350 351 352 353 354 355 356 357
			stage = tab[-1] - '0';
			ptr = tab + 1; /* point at the head of path */
			tab = tab - 2; /* point at tail of sha1 */
		}
		else {
			stage = 0;
			ptr = tab + 1; /* point at the head of path */
		}

358 359
		if (get_sha1_hex(tab - 40, sha1) || tab[-41] != ' ')
			goto bad_line;
360

361 362 363 364
		path_name = ptr;
		if (line_termination && path_name[0] == '"') {
			strbuf_reset(&uq);
			if (unquote_c_style(&uq, path_name, NULL)) {
365
				die("git update-index: bad quoting of path name");
366 367 368
			}
			path_name = uq.buf;
		}
369 370 371

		if (!verify_path(path_name)) {
			fprintf(stderr, "Ignoring path %s\n", path_name);
372 373 374 375 376
			continue;
		}

		if (!mode) {
			/* mode == 0 means there is no such path -- remove */
377
			if (remove_file_from_cache(path_name))
378
				die("git update-index: unable to remove %s",
379 380 381 382 383 384 385 386
				    ptr);
		}
		else {
			/* mode ' ' sha1 '\t' name
			 * ptr[-1] points at tab,
			 * ptr[-41] is at the beginning of sha1
			 */
			ptr[-42] = ptr[-1] = 0;
387
			if (add_cacheinfo(mode, sha1, path_name, stage))
388
				die("git update-index: unable to update %s",
389
				    path_name);
390 391 392 393 394 395
		}
		continue;

	bad_line:
		die("malformed index info %s", buf.buf);
	}
396
	strbuf_release(&buf);
397
	strbuf_release(&uq);
398 399
}

P
Petr Baudis 已提交
400
static const char update_index_usage[] =
401
"git update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--skip-worktree|--no-skip-worktree] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] [<file>...]";
P
Petr Baudis 已提交
402

J
Junio C Hamano 已提交
403 404 405 406 407 408 409 410 411 412 413 414 415
static unsigned char head_sha1[20];
static unsigned char merge_head_sha1[20];

static struct cache_entry *read_one_ent(const char *which,
					unsigned char *ent, const char *path,
					int namelen, int stage)
{
	unsigned mode;
	unsigned char sha1[20];
	int size;
	struct cache_entry *ce;

	if (get_tree_entry(ent, path, sha1, &mode)) {
J
Junio C Hamano 已提交
416 417
		if (which)
			error("%s: not in %s branch.", path, which);
J
Junio C Hamano 已提交
418 419 420
		return NULL;
	}
	if (mode == S_IFDIR) {
J
Junio C Hamano 已提交
421 422
		if (which)
			error("%s: not a blob in %s branch.", path, which);
J
Junio C Hamano 已提交
423 424 425 426 427
		return NULL;
	}
	size = cache_entry_size(namelen);
	ce = xcalloc(1, size);

428
	hashcpy(ce->sha1, sha1);
J
Junio C Hamano 已提交
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
	memcpy(ce->name, path, namelen);
	ce->ce_flags = create_ce_flags(namelen, stage);
	ce->ce_mode = create_ce_mode(mode);
	return ce;
}

static int unresolve_one(const char *path)
{
	int namelen = strlen(path);
	int pos;
	int ret = 0;
	struct cache_entry *ce_2 = NULL, *ce_3 = NULL;

	/* See if there is such entry in the index. */
	pos = cache_name_pos(path, namelen);
444 445 446 447 448 449 450 451 452 453 454 455
	if (0 <= pos) {
		/* already merged */
		pos = unmerge_cache_entry_at(pos);
		if (pos < active_nr) {
			struct cache_entry *ce = active_cache[pos];
			if (ce_stage(ce) &&
			    ce_namelen(ce) == namelen &&
			    !memcmp(ce->name, path, namelen))
				return 0;
		}
		/* no resolve-undo information; fall back */
	} else {
J
Junio C Hamano 已提交
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
		/* If there isn't, either it is unmerged, or
		 * resolved as "removed" by mistake.  We do not
		 * want to do anything in the former case.
		 */
		pos = -pos-1;
		if (pos < active_nr) {
			struct cache_entry *ce = active_cache[pos];
			if (ce_namelen(ce) == namelen &&
			    !memcmp(ce->name, path, namelen)) {
				fprintf(stderr,
					"%s: skipping still unmerged path.\n",
					path);
				goto free_return;
			}
		}
	}

	/* Grab blobs from given path from HEAD and MERGE_HEAD,
	 * stuff HEAD version in stage #2,
	 * stuff MERGE_HEAD version in stage #3.
	 */
	ce_2 = read_one_ent("our", head_sha1, path, namelen, 2);
	ce_3 = read_one_ent("their", merge_head_sha1, path, namelen, 3);

	if (!ce_2 || !ce_3) {
		ret = -1;
		goto free_return;
	}
484
	if (!hashcmp(ce_2->sha1, ce_3->sha1) &&
J
Junio C Hamano 已提交
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
	    ce_2->ce_mode == ce_3->ce_mode) {
		fprintf(stderr, "%s: identical in both, skipping.\n",
			path);
		goto free_return;
	}

	remove_file_from_cache(path);
	if (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {
		error("%s: cannot add our version to the index.", path);
		ret = -1;
		goto free_return;
	}
	if (!add_cache_entry(ce_3, ADD_CACHE_OK_TO_ADD))
		return 0;
	error("%s: cannot add their version to the index.", path);
	ret = -1;
 free_return:
	free(ce_2);
	free(ce_3);
	return ret;
}

static void read_head_pointers(void)
{
509
	if (read_ref("HEAD", head_sha1))
510
		die("No HEAD -- no initial commit yet?");
511
	if (read_ref("MERGE_HEAD", merge_head_sha1)) {
J
Junio C Hamano 已提交
512 513 514 515 516
		fprintf(stderr, "Not in the middle of a merge.\n");
		exit(0);
	}
}

517 518
static int do_unresolve(int ac, const char **av,
			const char *prefix, int prefix_length)
J
Junio C Hamano 已提交
519 520 521 522 523 524 525 526 527 528 529
{
	int i;
	int err = 0;

	/* Read HEAD and MERGE_HEAD; if MERGE_HEAD does not exist, we
	 * are not doing a merge, so exit with success status.
	 */
	read_head_pointers();

	for (i = 1; i < ac; i++) {
		const char *arg = av[i];
530 531
		const char *p = prefix_path(prefix, prefix_length, arg);
		err |= unresolve_one(p);
532
		if (p < arg || p > arg + strlen(arg))
533
			free((char *)p);
J
Junio C Hamano 已提交
534 535 536 537
	}
	return err;
}

J
Junio C Hamano 已提交
538 539 540 541 542 543 544 545
static int do_reupdate(int ac, const char **av,
		       const char *prefix, int prefix_length)
{
	/* Read HEAD and run update-index on paths that are
	 * merged and already different between index and HEAD.
	 */
	int pos;
	int has_head = 1;
546
	const char **pathspec = get_pathspec(prefix, av + 1);
J
Junio C Hamano 已提交
547

548
	if (read_ref("HEAD", head_sha1))
J
Junio C Hamano 已提交
549 550 551 552 553 554 555 556 557
		/* If there is no HEAD, that means it is an initial
		 * commit.  Update everything in the index.
		 */
		has_head = 0;
 redo:
	for (pos = 0; pos < active_nr; pos++) {
		struct cache_entry *ce = active_cache[pos];
		struct cache_entry *old = NULL;
		int save_nr;
558 559

		if (ce_stage(ce) || !ce_path_match(ce, pathspec))
J
Junio C Hamano 已提交
560 561 562 563 564
			continue;
		if (has_head)
			old = read_one_ent(NULL, head_sha1,
					   ce->name, ce_namelen(ce), 0);
		if (old && ce->ce_mode == old->ce_mode &&
565
		    !hashcmp(ce->sha1, old->sha1)) {
J
Junio C Hamano 已提交
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
			free(old);
			continue; /* unchanged */
		}
		/* Be careful.  The working tree may not have the
		 * path anymore, in which case, under 'allow_remove',
		 * or worse yet 'allow_replace', active_nr may decrease.
		 */
		save_nr = active_nr;
		update_one(ce->name + prefix_length, prefix, prefix_length);
		if (save_nr != active_nr)
			goto redo;
	}
	return 0;
}

581
int cmd_update_index(int argc, const char **argv, const char *prefix)
582
{
J
Junio C Hamano 已提交
583
	int i, newfd, entries, has_errors = 0, line_termination = '\n';
584
	int allow_options = 1;
J
Junio C Hamano 已提交
585 586
	int read_from_stdin = 0;
	int prefix_length = prefix ? strlen(prefix) : 0;
587
	char set_executable_bit = 0;
L
Linus Torvalds 已提交
588
	unsigned int refresh_flags = 0;
589
	int lock_error = 0;
590
	struct lock_file *lock_file;
591

592
	git_config(git_default_config, NULL);
J
Junio C Hamano 已提交
593

594
	/* We can't free this memory, it becomes part of a linked list parsed atexit() */
595
	lock_file = xcalloc(1, sizeof(struct lock_file));
596

597
	newfd = hold_locked_index(lock_file, 0);
598 599
	if (newfd < 0)
		lock_error = errno;
600

601
	entries = read_cache();
602
	if (entries < 0)
603
		die("cache corrupted");
604 605

	for (i = 1 ; i < argc; i++) {
J
Junio C Hamano 已提交
606
		const char *path = argv[i];
607
		const char *p;
608 609 610 611 612 613

		if (allow_options && *path == '-') {
			if (!strcmp(path, "--")) {
				allow_options = 0;
				continue;
			}
614
			if (!strcmp(path, "-q")) {
L
Linus Torvalds 已提交
615
				refresh_flags |= REFRESH_QUIET;
616 617
				continue;
			}
618 619 620 621
			if (!strcmp(path, "--ignore-submodules")) {
				refresh_flags |= REFRESH_IGNORE_SUBMODULES;
				continue;
			}
622 623 624 625
			if (!strcmp(path, "--add")) {
				allow_add = 1;
				continue;
			}
626 627 628 629
			if (!strcmp(path, "--replace")) {
				allow_replace = 1;
				continue;
			}
630 631 632 633
			if (!strcmp(path, "--remove")) {
				allow_remove = 1;
				continue;
			}
634
			if (!strcmp(path, "--unmerged")) {
L
Linus Torvalds 已提交
635
				refresh_flags |= REFRESH_UNMERGED;
636 637
				continue;
			}
638
			if (!strcmp(path, "--refresh")) {
639
				setup_work_tree();
L
Linus Torvalds 已提交
640
				has_errors |= refresh_cache(refresh_flags);
J
Junio C Hamano 已提交
641 642 643
				continue;
			}
			if (!strcmp(path, "--really-refresh")) {
644
				setup_work_tree();
L
Linus Torvalds 已提交
645
				has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags);
646 647
				continue;
			}
648
			if (!strcmp(path, "--cacheinfo")) {
649 650 651
				unsigned char sha1[20];
				unsigned int mode;

652
				if (i+3 >= argc)
653
					die("git update-index: --cacheinfo <mode> <sha1> <path>");
654

655
				if (strtoul_ui(argv[i+1], 8, &mode) ||
656 657
				    get_sha1_hex(argv[i+2], sha1) ||
				    add_cacheinfo(mode, sha1, argv[i+3], 0))
658
					die("git update-index: --cacheinfo"
659
					    " cannot add %s", argv[i+3]);
660 661 662
				i += 3;
				continue;
			}
J
Junio C Hamano 已提交
663 664 665
			if (!strcmp(path, "--chmod=-x") ||
			    !strcmp(path, "--chmod=+x")) {
				if (argc <= i+1)
666
					die("git update-index: %s <path>", path);
667
				set_executable_bit = path[8];
J
Junio C Hamano 已提交
668 669
				continue;
			}
J
Junio C Hamano 已提交
670
			if (!strcmp(path, "--assume-unchanged")) {
671
				mark_valid_only = MARK_FLAG;
J
Junio C Hamano 已提交
672 673 674
				continue;
			}
			if (!strcmp(path, "--no-assume-unchanged")) {
675
				mark_valid_only = UNMARK_FLAG;
J
Junio C Hamano 已提交
676 677
				continue;
			}
678 679 680 681 682 683
			if (!strcmp(path, "--no-skip-worktree")) {
				mark_skip_worktree_only = UNMARK_FLAG;
				continue;
			}
			if (!strcmp(path, "--skip-worktree")) {
				mark_skip_worktree_only = MARK_FLAG;
J
Junio C Hamano 已提交
684 685
				continue;
			}
686 687 688 689
			if (!strcmp(path, "--info-only")) {
				info_only = 1;
				continue;
			}
690
			if (!strcmp(path, "--force-remove")) {
691
				force_remove = 1;
692 693
				continue;
			}
J
Junio C Hamano 已提交
694 695 696 697 698 699 700 701 702 703
			if (!strcmp(path, "-z")) {
				line_termination = 0;
				continue;
			}
			if (!strcmp(path, "--stdin")) {
				if (i != argc - 1)
					die("--stdin must be at the end");
				read_from_stdin = 1;
				break;
			}
704
			if (!strcmp(path, "--index-info")) {
705 706
				if (i != argc - 1)
					die("--index-info must be at the end");
707 708
				allow_add = allow_replace = allow_remove = 1;
				read_index_info(line_termination);
709
				break;
710
			}
J
Junio C Hamano 已提交
711
			if (!strcmp(path, "--unresolve")) {
712 713
				has_errors = do_unresolve(argc - i, argv + i,
							  prefix, prefix_length);
J
Junio C Hamano 已提交
714 715 716 717
				if (has_errors)
					active_cache_changed = 0;
				goto finish;
			}
J
Junio C Hamano 已提交
718
			if (!strcmp(path, "--again") || !strcmp(path, "-g")) {
719
				setup_work_tree();
J
Junio C Hamano 已提交
720 721 722 723 724 725
				has_errors = do_reupdate(argc - i, argv + i,
							 prefix, prefix_length);
				if (has_errors)
					active_cache_changed = 0;
				goto finish;
			}
726
			if (!strcmp(path, "--ignore-missing")) {
L
Linus Torvalds 已提交
727
				refresh_flags |= REFRESH_IGNORE_MISSING;
728 729
				continue;
			}
J
Junio C Hamano 已提交
730 731 732 733
			if (!strcmp(path, "--verbose")) {
				verbose = 1;
				continue;
			}
734 735 736 737
			if (!strcmp(path, "--clear-resolve-undo")) {
				resolve_undo_clear();
				continue;
			}
P
Petr Baudis 已提交
738 739
			if (!strcmp(path, "-h") || !strcmp(path, "--help"))
				usage(update_index_usage);
740
			die("unknown option %s", path);
741
		}
742
		setup_work_tree();
743 744
		p = prefix_path(prefix, prefix_length, path);
		update_one(p, NULL, 0);
745
		if (set_executable_bit)
746 747
			chmod_path(set_executable_bit, p);
		if (p < path || p > path + strlen(path))
748
			free((char *)p);
J
Junio C Hamano 已提交
749 750
	}
	if (read_from_stdin) {
751
		struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT;
752

753
		setup_work_tree();
754
		while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
755
			const char *p;
756 757 758 759 760 761 762
			if (line_termination && buf.buf[0] == '"') {
				strbuf_reset(&nbuf);
				if (unquote_c_style(&nbuf, buf.buf, NULL))
					die("line is badly quoted");
				strbuf_swap(&buf, &nbuf);
			}
			p = prefix_path(prefix, prefix_length, buf.buf);
763 764
			update_one(p, NULL, 0);
			if (set_executable_bit)
765
				chmod_path(set_executable_bit, p);
766 767
			if (p < buf.buf || p > buf.buf + buf.len)
				free((char *)p);
768
		}
769
		strbuf_release(&nbuf);
770
		strbuf_release(&buf);
771
	}
J
Junio C Hamano 已提交
772 773

 finish:
774
	if (active_cache_changed) {
775 776 777
		if (newfd < 0) {
			if (refresh_flags & REFRESH_QUIET)
				exit(128);
778
			unable_to_lock_index_die(get_index_file(), lock_error);
779
		}
780
		if (write_cache(newfd, active_cache, active_nr) ||
B
Brandon Casey 已提交
781
		    commit_locked_index(lock_file))
782
			die("Unable to write new index file");
783
	}
784

785 786
	rollback_lock_file(lock_file);

787
	return has_errors ? 1 : 0;
788
}