]> git.ipfire.org Git - thirdparty/git.git/blob - builtin/add.c
Merge branch 'fc/doc-stop-using-manversion' into fc/doc-use-datestamp-in-commit
[thirdparty/git.git] / builtin / add.c
1 /*
2 * "git add" builtin command
3 *
4 * Copyright (C) 2006 Linus Torvalds
5 */
6 #define USE_THE_INDEX_VARIABLE
7 #include "cache.h"
8 #include "config.h"
9 #include "builtin.h"
10 #include "lockfile.h"
11 #include "dir.h"
12 #include "gettext.h"
13 #include "pathspec.h"
14 #include "exec-cmd.h"
15 #include "cache-tree.h"
16 #include "run-command.h"
17 #include "parse-options.h"
18 #include "diff.h"
19 #include "diffcore.h"
20 #include "revision.h"
21 #include "bulk-checkin.h"
22 #include "strvec.h"
23 #include "submodule.h"
24 #include "add-interactive.h"
25
26 static const char * const builtin_add_usage[] = {
27 N_("git add [<options>] [--] <pathspec>..."),
28 NULL
29 };
30 static int patch_interactive, add_interactive, edit_interactive;
31 static int take_worktree_changes;
32 static int add_renormalize;
33 static int pathspec_file_nul;
34 static int include_sparse;
35 static const char *pathspec_from_file;
36
37 struct update_callback_data {
38 int flags;
39 int add_errors;
40 };
41
42 static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only)
43 {
44 int i, ret = 0;
45
46 for (i = 0; i < the_index.cache_nr; i++) {
47 struct cache_entry *ce = the_index.cache[i];
48 int err;
49
50 if (!include_sparse &&
51 (ce_skip_worktree(ce) ||
52 !path_in_sparse_checkout(ce->name, &the_index)))
53 continue;
54
55 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
56 continue;
57
58 if (!show_only)
59 err = chmod_index_entry(&the_index, ce, flip);
60 else
61 err = S_ISREG(ce->ce_mode) ? 0 : -1;
62
63 if (err < 0)
64 ret = error(_("cannot chmod %cx '%s'"), flip, ce->name);
65 }
66
67 return ret;
68 }
69
70 static int fix_unmerged_status(struct diff_filepair *p,
71 struct update_callback_data *data)
72 {
73 if (p->status != DIFF_STATUS_UNMERGED)
74 return p->status;
75 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
76 /*
77 * This is not an explicit add request, and the
78 * path is missing from the working tree (deleted)
79 */
80 return DIFF_STATUS_DELETED;
81 else
82 /*
83 * Either an explicit add request, or path exists
84 * in the working tree. An attempt to explicitly
85 * add a path that does not exist in the working tree
86 * will be caught as an error by the caller immediately.
87 */
88 return DIFF_STATUS_MODIFIED;
89 }
90
91 static void update_callback(struct diff_queue_struct *q,
92 struct diff_options *opt UNUSED, void *cbdata)
93 {
94 int i;
95 struct update_callback_data *data = cbdata;
96
97 for (i = 0; i < q->nr; i++) {
98 struct diff_filepair *p = q->queue[i];
99 const char *path = p->one->path;
100
101 if (!include_sparse && !path_in_sparse_checkout(path, &the_index))
102 continue;
103
104 switch (fix_unmerged_status(p, data)) {
105 default:
106 die(_("unexpected diff status %c"), p->status);
107 case DIFF_STATUS_MODIFIED:
108 case DIFF_STATUS_TYPE_CHANGED:
109 if (add_file_to_index(&the_index, path, data->flags)) {
110 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
111 die(_("updating files failed"));
112 data->add_errors++;
113 }
114 break;
115 case DIFF_STATUS_DELETED:
116 if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
117 break;
118 if (!(data->flags & ADD_CACHE_PRETEND))
119 remove_file_from_index(&the_index, path);
120 if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
121 printf(_("remove '%s'\n"), path);
122 break;
123 }
124 }
125 }
126
127 int add_files_to_cache(const char *prefix,
128 const struct pathspec *pathspec, int flags)
129 {
130 struct update_callback_data data;
131 struct rev_info rev;
132
133 memset(&data, 0, sizeof(data));
134 data.flags = flags;
135
136 repo_init_revisions(the_repository, &rev, prefix);
137 setup_revisions(0, NULL, &rev, NULL);
138 if (pathspec)
139 copy_pathspec(&rev.prune_data, pathspec);
140 rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
141 rev.diffopt.format_callback = update_callback;
142 rev.diffopt.format_callback_data = &data;
143 rev.diffopt.flags.override_submodule_config = 1;
144 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
145
146 /*
147 * Use an ODB transaction to optimize adding multiple objects.
148 * This function is invoked from commands other than 'add', which
149 * may not have their own transaction active.
150 */
151 begin_odb_transaction();
152 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
153 end_odb_transaction();
154
155 release_revisions(&rev);
156 return !!data.add_errors;
157 }
158
159 static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
160 {
161 int i, retval = 0;
162
163 for (i = 0; i < the_index.cache_nr; i++) {
164 struct cache_entry *ce = the_index.cache[i];
165
166 if (!include_sparse &&
167 (ce_skip_worktree(ce) ||
168 !path_in_sparse_checkout(ce->name, &the_index)))
169 continue;
170 if (ce_stage(ce))
171 continue; /* do not touch unmerged paths */
172 if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
173 continue; /* do not touch non blobs */
174 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
175 continue;
176 retval |= add_file_to_index(&the_index, ce->name,
177 flags | ADD_CACHE_RENORMALIZE);
178 }
179
180 return retval;
181 }
182
183 static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
184 {
185 char *seen;
186 int i;
187 struct dir_entry **src, **dst;
188
189 seen = xcalloc(pathspec->nr, 1);
190
191 src = dst = dir->entries;
192 i = dir->nr;
193 while (--i >= 0) {
194 struct dir_entry *entry = *src++;
195 if (dir_path_match(&the_index, entry, pathspec, prefix, seen))
196 *dst++ = entry;
197 }
198 dir->nr = dst - dir->entries;
199 add_pathspec_matches_against_index(pathspec, &the_index, seen,
200 PS_IGNORE_SKIP_WORKTREE);
201 return seen;
202 }
203
204 static int refresh(int verbose, const struct pathspec *pathspec)
205 {
206 char *seen;
207 int i, ret = 0;
208 char *skip_worktree_seen = NULL;
209 struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
210 int flags = REFRESH_IGNORE_SKIP_WORKTREE |
211 (verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
212
213 seen = xcalloc(pathspec->nr, 1);
214 refresh_index(&the_index, flags, pathspec, seen,
215 _("Unstaged changes after refreshing the index:"));
216 for (i = 0; i < pathspec->nr; i++) {
217 if (!seen[i]) {
218 const char *path = pathspec->items[i].original;
219
220 if (matches_skip_worktree(pathspec, i, &skip_worktree_seen) ||
221 !path_in_sparse_checkout(path, &the_index)) {
222 string_list_append(&only_match_skip_worktree,
223 pathspec->items[i].original);
224 } else {
225 die(_("pathspec '%s' did not match any files"),
226 pathspec->items[i].original);
227 }
228 }
229 }
230
231 if (only_match_skip_worktree.nr) {
232 advise_on_updating_sparse_paths(&only_match_skip_worktree);
233 ret = 1;
234 }
235
236 free(seen);
237 free(skip_worktree_seen);
238 string_list_clear(&only_match_skip_worktree, 0);
239 return ret;
240 }
241
242 int interactive_add(const char **argv, const char *prefix, int patch)
243 {
244 struct pathspec pathspec;
245 int unused;
246
247 if (!git_config_get_bool("add.interactive.usebuiltin", &unused))
248 warning(_("the add.interactive.useBuiltin setting has been removed!\n"
249 "See its entry in 'git help config' for details."));
250
251 parse_pathspec(&pathspec, 0,
252 PATHSPEC_PREFER_FULL |
253 PATHSPEC_SYMLINK_LEADING_PATH |
254 PATHSPEC_PREFIX_ORIGIN,
255 prefix, argv);
256
257 if (patch)
258 return !!run_add_p(the_repository, ADD_P_ADD, NULL, &pathspec);
259 else
260 return !!run_add_i(the_repository, &pathspec);
261 }
262
263 static int edit_patch(int argc, const char **argv, const char *prefix)
264 {
265 char *file = git_pathdup("ADD_EDIT.patch");
266 struct child_process child = CHILD_PROCESS_INIT;
267 struct rev_info rev;
268 int out;
269 struct stat st;
270
271 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
272
273 if (repo_read_index(the_repository) < 0)
274 die(_("Could not read the index"));
275
276 repo_init_revisions(the_repository, &rev, prefix);
277 rev.diffopt.context = 7;
278
279 argc = setup_revisions(argc, argv, &rev, NULL);
280 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
281 rev.diffopt.use_color = 0;
282 rev.diffopt.flags.ignore_dirty_submodules = 1;
283 out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
284 rev.diffopt.file = xfdopen(out, "w");
285 rev.diffopt.close_file = 1;
286 if (run_diff_files(&rev, 0))
287 die(_("Could not write patch"));
288
289 if (launch_editor(file, NULL, NULL))
290 die(_("editing patch failed"));
291
292 if (stat(file, &st))
293 die_errno(_("Could not stat '%s'"), file);
294 if (!st.st_size)
295 die(_("Empty patch. Aborted."));
296
297 child.git_cmd = 1;
298 strvec_pushl(&child.args, "apply", "--recount", "--cached", file,
299 NULL);
300 if (run_command(&child))
301 die(_("Could not apply '%s'"), file);
302
303 unlink(file);
304 free(file);
305 release_revisions(&rev);
306 return 0;
307 }
308
309 static const char ignore_error[] =
310 N_("The following paths are ignored by one of your .gitignore files:\n");
311
312 static int verbose, show_only, ignored_too, refresh_only;
313 static int ignore_add_errors, intent_to_add, ignore_missing;
314 static int warn_on_embedded_repo = 1;
315
316 #define ADDREMOVE_DEFAULT 1
317 static int addremove = ADDREMOVE_DEFAULT;
318 static int addremove_explicit = -1; /* unspecified */
319
320 static char *chmod_arg;
321
322 static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
323 {
324 /* if we are told to ignore, we are not adding removals */
325 *(int *)opt->value = !unset ? 0 : 1;
326 return 0;
327 }
328
329 static struct option builtin_add_options[] = {
330 OPT__DRY_RUN(&show_only, N_("dry run")),
331 OPT__VERBOSE(&verbose, N_("be verbose")),
332 OPT_GROUP(""),
333 OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
334 OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
335 OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
336 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
337 OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
338 OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
339 OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
340 OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
341 OPT_CALLBACK_F(0, "ignore-removal", &addremove_explicit,
342 NULL /* takes no arguments */,
343 N_("ignore paths removed in the working tree (same as --no-all)"),
344 PARSE_OPT_NOARG, ignore_removal_cb),
345 OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
346 OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
347 OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
348 OPT_BOOL(0, "sparse", &include_sparse, N_("allow updating entries outside of the sparse-checkout cone")),
349 OPT_STRING(0, "chmod", &chmod_arg, "(+|-)x",
350 N_("override the executable bit of the listed files")),
351 OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
352 N_("warn when adding an embedded repository")),
353 OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
354 OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
355 OPT_END(),
356 };
357
358 static int add_config(const char *var, const char *value, void *cb)
359 {
360 if (!strcmp(var, "add.ignoreerrors") ||
361 !strcmp(var, "add.ignore-errors")) {
362 ignore_add_errors = git_config_bool(var, value);
363 return 0;
364 }
365
366 return git_default_config(var, value, cb);
367 }
368
369 static const char embedded_advice[] = N_(
370 "You've added another git repository inside your current repository.\n"
371 "Clones of the outer repository will not contain the contents of\n"
372 "the embedded repository and will not know how to obtain it.\n"
373 "If you meant to add a submodule, use:\n"
374 "\n"
375 " git submodule add <url> %s\n"
376 "\n"
377 "If you added this path by mistake, you can remove it from the\n"
378 "index with:\n"
379 "\n"
380 " git rm --cached %s\n"
381 "\n"
382 "See \"git help submodule\" for more information."
383 );
384
385 static void check_embedded_repo(const char *path)
386 {
387 struct strbuf name = STRBUF_INIT;
388 static int adviced_on_embedded_repo = 0;
389
390 if (!warn_on_embedded_repo)
391 return;
392 if (!ends_with(path, "/"))
393 return;
394
395 /* Drop trailing slash for aesthetics */
396 strbuf_addstr(&name, path);
397 strbuf_strip_suffix(&name, "/");
398
399 warning(_("adding embedded git repository: %s"), name.buf);
400 if (!adviced_on_embedded_repo &&
401 advice_enabled(ADVICE_ADD_EMBEDDED_REPO)) {
402 advise(embedded_advice, name.buf, name.buf);
403 adviced_on_embedded_repo = 1;
404 }
405
406 strbuf_release(&name);
407 }
408
409 static int add_files(struct dir_struct *dir, int flags)
410 {
411 int i, exit_status = 0;
412 struct string_list matched_sparse_paths = STRING_LIST_INIT_NODUP;
413
414 if (dir->ignored_nr) {
415 fprintf(stderr, _(ignore_error));
416 for (i = 0; i < dir->ignored_nr; i++)
417 fprintf(stderr, "%s\n", dir->ignored[i]->name);
418 if (advice_enabled(ADVICE_ADD_IGNORED_FILE))
419 advise(_("Use -f if you really want to add them.\n"
420 "Turn this message off by running\n"
421 "\"git config advice.addIgnoredFile false\""));
422 exit_status = 1;
423 }
424
425 for (i = 0; i < dir->nr; i++) {
426 if (!include_sparse &&
427 !path_in_sparse_checkout(dir->entries[i]->name, &the_index)) {
428 string_list_append(&matched_sparse_paths,
429 dir->entries[i]->name);
430 continue;
431 }
432 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
433 if (!ignore_add_errors)
434 die(_("adding files failed"));
435 exit_status = 1;
436 } else {
437 check_embedded_repo(dir->entries[i]->name);
438 }
439 }
440
441 if (matched_sparse_paths.nr) {
442 advise_on_updating_sparse_paths(&matched_sparse_paths);
443 exit_status = 1;
444 }
445
446 string_list_clear(&matched_sparse_paths, 0);
447
448 return exit_status;
449 }
450
451 int cmd_add(int argc, const char **argv, const char *prefix)
452 {
453 int exit_status = 0;
454 struct pathspec pathspec;
455 struct dir_struct dir = DIR_INIT;
456 int flags;
457 int add_new_files;
458 int require_pathspec;
459 char *seen = NULL;
460 struct lock_file lock_file = LOCK_INIT;
461
462 git_config(add_config, NULL);
463
464 argc = parse_options(argc, argv, prefix, builtin_add_options,
465 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
466 if (patch_interactive)
467 add_interactive = 1;
468 if (add_interactive) {
469 if (show_only)
470 die(_("options '%s' and '%s' cannot be used together"), "--dry-run", "--interactive/--patch");
471 if (pathspec_from_file)
472 die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch");
473 exit(interactive_add(argv + 1, prefix, patch_interactive));
474 }
475
476 if (edit_interactive) {
477 if (pathspec_from_file)
478 die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--edit");
479 return(edit_patch(argc, argv, prefix));
480 }
481 argc--;
482 argv++;
483
484 if (0 <= addremove_explicit)
485 addremove = addremove_explicit;
486 else if (take_worktree_changes && ADDREMOVE_DEFAULT)
487 addremove = 0; /* "-u" was given but not "-A" */
488
489 if (addremove && take_worktree_changes)
490 die(_("options '%s' and '%s' cannot be used together"), "-A", "-u");
491
492 if (!show_only && ignore_missing)
493 die(_("the option '%s' requires '%s'"), "--ignore-missing", "--dry-run");
494
495 if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
496 chmod_arg[1] != 'x' || chmod_arg[2]))
497 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
498
499 add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
500 require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
501
502 prepare_repo_settings(the_repository);
503 the_repository->settings.command_requires_full_index = 0;
504
505 repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
506
507 /*
508 * Check the "pathspec '%s' did not match any files" block
509 * below before enabling new magic.
510 */
511 parse_pathspec(&pathspec, PATHSPEC_ATTR,
512 PATHSPEC_PREFER_FULL |
513 PATHSPEC_SYMLINK_LEADING_PATH,
514 prefix, argv);
515
516 if (pathspec_from_file) {
517 if (pathspec.nr)
518 die(_("'%s' and pathspec arguments cannot be used together"), "--pathspec-from-file");
519
520 parse_pathspec_file(&pathspec, PATHSPEC_ATTR,
521 PATHSPEC_PREFER_FULL |
522 PATHSPEC_SYMLINK_LEADING_PATH,
523 prefix, pathspec_from_file, pathspec_file_nul);
524 } else if (pathspec_file_nul) {
525 die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file");
526 }
527
528 if (require_pathspec && pathspec.nr == 0) {
529 fprintf(stderr, _("Nothing specified, nothing added.\n"));
530 if (advice_enabled(ADVICE_ADD_EMPTY_PATHSPEC))
531 advise( _("Maybe you wanted to say 'git add .'?\n"
532 "Turn this message off by running\n"
533 "\"git config advice.addEmptyPathspec false\""));
534 return 0;
535 }
536
537 if (!take_worktree_changes && addremove_explicit < 0 && pathspec.nr)
538 /* Turn "git add pathspec..." to "git add -A pathspec..." */
539 addremove = 1;
540
541 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
542 (show_only ? ADD_CACHE_PRETEND : 0) |
543 (intent_to_add ? ADD_CACHE_INTENT : 0) |
544 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
545 (!(addremove || take_worktree_changes)
546 ? ADD_CACHE_IGNORE_REMOVAL : 0));
547
548 if (repo_read_index_preload(the_repository, &pathspec, 0) < 0)
549 die(_("index file corrupt"));
550
551 die_in_unpopulated_submodule(&the_index, prefix);
552 die_path_inside_submodule(&the_index, &pathspec);
553
554 if (add_new_files) {
555 int baselen;
556
557 /* Set up the default git porcelain excludes */
558 if (!ignored_too) {
559 dir.flags |= DIR_COLLECT_IGNORED;
560 setup_standard_excludes(&dir);
561 }
562
563 /* This picks up the paths that are not tracked */
564 baselen = fill_directory(&dir, &the_index, &pathspec);
565 if (pathspec.nr)
566 seen = prune_directory(&dir, &pathspec, baselen);
567 }
568
569 if (refresh_only) {
570 exit_status |= refresh(verbose, &pathspec);
571 goto finish;
572 }
573
574 if (pathspec.nr) {
575 int i;
576 char *skip_worktree_seen = NULL;
577 struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
578
579 if (!seen)
580 seen = find_pathspecs_matching_against_index(&pathspec,
581 &the_index, PS_IGNORE_SKIP_WORKTREE);
582
583 /*
584 * file_exists() assumes exact match
585 */
586 GUARD_PATHSPEC(&pathspec,
587 PATHSPEC_FROMTOP |
588 PATHSPEC_LITERAL |
589 PATHSPEC_GLOB |
590 PATHSPEC_ICASE |
591 PATHSPEC_EXCLUDE);
592
593 for (i = 0; i < pathspec.nr; i++) {
594 const char *path = pathspec.items[i].match;
595
596 if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
597 continue;
598 if (seen[i])
599 continue;
600
601 if (!include_sparse &&
602 matches_skip_worktree(&pathspec, i, &skip_worktree_seen)) {
603 string_list_append(&only_match_skip_worktree,
604 pathspec.items[i].original);
605 continue;
606 }
607
608 /* Don't complain at 'git add .' on empty repo */
609 if (!path[0])
610 continue;
611
612 if ((pathspec.items[i].magic & (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
613 !file_exists(path)) {
614 if (ignore_missing) {
615 int dtype = DT_UNKNOWN;
616 if (is_excluded(&dir, &the_index, path, &dtype))
617 dir_add_ignored(&dir, &the_index,
618 path, pathspec.items[i].len);
619 } else
620 die(_("pathspec '%s' did not match any files"),
621 pathspec.items[i].original);
622 }
623 }
624
625
626 if (only_match_skip_worktree.nr) {
627 advise_on_updating_sparse_paths(&only_match_skip_worktree);
628 exit_status = 1;
629 }
630
631 free(seen);
632 free(skip_worktree_seen);
633 string_list_clear(&only_match_skip_worktree, 0);
634 }
635
636 begin_odb_transaction();
637
638 if (add_renormalize)
639 exit_status |= renormalize_tracked_files(&pathspec, flags);
640 else
641 exit_status |= add_files_to_cache(prefix, &pathspec, flags);
642
643 if (add_new_files)
644 exit_status |= add_files(&dir, flags);
645
646 if (chmod_arg && pathspec.nr)
647 exit_status |= chmod_pathspec(&pathspec, chmod_arg[0], show_only);
648 end_odb_transaction();
649
650 finish:
651 if (write_locked_index(&the_index, &lock_file,
652 COMMIT_LOCK | SKIP_IF_UNCHANGED))
653 die(_("Unable to write new index file"));
654
655 dir_clear(&dir);
656 clear_pathspec(&pathspec);
657 return exit_status;
658 }