]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/add.c
parse-options: add OPT_xxx_F() variants
[thirdparty/git.git] / builtin / add.c
CommitLineData
0d781539
LT
1/*
2 * "git add" builtin command
3 *
4 * Copyright (C) 2006 Linus Torvalds
5 */
0d781539 6#include "cache.h"
b2141fc1 7#include "config.h"
0d781539 8#include "builtin.h"
697cc8ef 9#include "lockfile.h"
0d781539 10#include "dir.h"
6f525e71 11#include "pathspec.h"
5cde71d6 12#include "exec_cmd.h"
93872e07 13#include "cache-tree.h"
58680165 14#include "run-command.h"
5c46f754 15#include "parse-options.h"
c59cb03a 16#include "diff.h"
fb7d3f32 17#include "diffcore.h"
c59cb03a 18#include "revision.h"
568508e7 19#include "bulk-checkin.h"
c45a18e8 20#include "argv-array.h"
bdab9721 21#include "submodule.h"
0d781539 22
5c46f754 23static const char * const builtin_add_usage[] = {
9c9b4f2f 24 N_("git add [<options>] [--] <pathspec>..."),
5c46f754
KH
25 NULL
26};
c59cb03a 27static int patch_interactive, add_interactive, edit_interactive;
93c44d49 28static int take_worktree_changes;
9472935d 29static int add_renormalize;
896bdfa2 30
9cba13ca 31struct update_callback_data {
610d55af 32 int flags;
fb7d3f32
LT
33 int add_errors;
34};
35
1e22a991 36static void chmod_pathspec(struct pathspec *pathspec, char flip)
610d55af
TG
37{
38 int i;
39
40 for (i = 0; i < active_nr; i++) {
41 struct cache_entry *ce = active_cache[i];
42
43 if (pathspec && !ce_path_match(ce, pathspec, NULL))
44 continue;
45
1e22a991
RJ
46 if (chmod_cache_entry(ce, flip) < 0)
47 fprintf(stderr, "cannot chmod %cx '%s'\n", flip, ce->name);
610d55af
TG
48 }
49}
50
75973b2c
JH
51static int fix_unmerged_status(struct diff_filepair *p,
52 struct update_callback_data *data)
53{
54 if (p->status != DIFF_STATUS_UNMERGED)
55 return p->status;
56 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
57 /*
58 * This is not an explicit add request, and the
59 * path is missing from the working tree (deleted)
60 */
61 return DIFF_STATUS_DELETED;
62 else
63 /*
64 * Either an explicit add request, or path exists
65 * in the working tree. An attempt to explicitly
66 * add a path that does not exist in the working tree
67 * will be caught as an error by the caller immediately.
68 */
69 return DIFF_STATUS_MODIFIED;
70}
71
fb7d3f32
LT
72static void update_callback(struct diff_queue_struct *q,
73 struct diff_options *opt, void *cbdata)
74{
75 int i;
76 struct update_callback_data *data = cbdata;
77
78 for (i = 0; i < q->nr; i++) {
79 struct diff_filepair *p = q->queue[i];
80 const char *path = p->one->path;
75973b2c 81 switch (fix_unmerged_status(p, data)) {
fb7d3f32 82 default:
990ac4be 83 die(_("unexpected diff status %c"), p->status);
fb7d3f32
LT
84 case DIFF_STATUS_MODIFIED:
85 case DIFF_STATUS_TYPE_CHANGED:
610d55af 86 if (add_file_to_index(&the_index, path, data->flags)) {
fb7d3f32 87 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
990ac4be 88 die(_("updating files failed"));
fb7d3f32
LT
89 data->add_errors++;
90 }
91 break;
92 case DIFF_STATUS_DELETED:
93 if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
94 break;
95 if (!(data->flags & ADD_CACHE_PRETEND))
96 remove_file_from_index(&the_index, path);
97 if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
475c73eb 98 printf(_("remove '%s'\n"), path);
fb7d3f32
LT
99 break;
100 }
101 }
102}
103
610d55af
TG
104int add_files_to_cache(const char *prefix,
105 const struct pathspec *pathspec, int flags)
fb7d3f32 106{
160c4b18 107 struct update_callback_data data;
fb7d3f32 108 struct rev_info rev;
71c7b053 109
160c4b18
JH
110 memset(&data, 0, sizeof(data));
111 data.flags = flags;
112
fb7d3f32
LT
113 init_revisions(&rev, prefix);
114 setup_revisions(0, NULL, &rev, NULL);
3efe8e43
NTND
115 if (pathspec)
116 copy_pathspec(&rev.prune_data, pathspec);
fb7d3f32
LT
117 rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
118 rev.diffopt.format_callback = update_callback;
160c4b18 119 rev.diffopt.format_callback_data = &data;
0d1e0e78 120 rev.diffopt.flags.override_submodule_config = 1;
75973b2c 121 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
fb7d3f32 122 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
fe6a01af 123 clear_pathspec(&rev.prune_data);
fb7d3f32
LT
124 return !!data.add_errors;
125}
126
9472935d
TB
127static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
128{
129 int i, retval = 0;
130
131 for (i = 0; i < active_nr; i++) {
132 struct cache_entry *ce = active_cache[i];
133
134 if (ce_stage(ce))
135 continue; /* do not touch unmerged paths */
136 if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
137 continue; /* do not touch non blobs */
138 if (pathspec && !ce_path_match(ce, pathspec, NULL))
139 continue;
140 retval |= add_file_to_cache(ce->name, flags | HASH_RENORMALIZE);
141 }
142
143 return retval;
144}
145
053a6b18 146static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
0d781539 147{
f2593398 148 char *seen;
84b8b5d1 149 int i;
0d781539
LT
150 struct dir_entry **src, **dst;
151
84b8b5d1 152 seen = xcalloc(pathspec->nr, 1);
f2593398 153
0d781539
LT
154 src = dst = dir->entries;
155 i = dir->nr;
156 while (--i >= 0) {
157 struct dir_entry *entry = *src++;
ebb32893 158 if (dir_path_match(entry, pathspec, prefix, seen))
4d06f8ac 159 *dst++ = entry;
0d781539
LT
160 }
161 dir->nr = dst - dir->entries;
08de9151 162 add_pathspec_matches_against_index(pathspec, &the_index, seen);
81f45e7d 163 return seen;
0d781539
LT
164}
165
9b2d6149 166static void refresh(int verbose, const struct pathspec *pathspec)
d616813d
AJ
167{
168 char *seen;
9b2d6149 169 int i;
d616813d 170
9b2d6149 171 seen = xcalloc(pathspec->nr, 1);
43673fdd 172 refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
ed2a808d 173 pathspec, seen, _("Unstaged changes after refreshing the index:"));
9b2d6149 174 for (i = 0; i < pathspec->nr; i++) {
d616813d 175 if (!seen[i])
9b2d6149
NTND
176 die(_("pathspec '%s' did not match any files"),
177 pathspec->items[i].match);
d616813d 178 }
399f0a8e 179 free(seen);
d616813d
AJ
180}
181
46b5139c 182int run_add_interactive(const char *revision, const char *patch_mode,
480ca644 183 const struct pathspec *pathspec)
58680165 184{
c45a18e8
FR
185 int status, i;
186 struct argv_array argv = ARGV_ARRAY_INIT;
3f061887 187
c45a18e8 188 argv_array_push(&argv, "add--interactive");
46b5139c 189 if (patch_mode)
c45a18e8 190 argv_array_push(&argv, patch_mode);
46b5139c 191 if (revision)
c45a18e8
FR
192 argv_array_push(&argv, revision);
193 argv_array_push(&argv, "--");
480ca644
NTND
194 for (i = 0; i < pathspec->nr; i++)
195 /* pass original pathspec, to be re-parsed */
c45a18e8 196 argv_array_push(&argv, pathspec->items[i].original);
7c0ab445 197
c45a18e8
FR
198 status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
199 argv_array_clear(&argv);
7c0ab445 200 return status;
58680165
KH
201}
202
b4bd4668 203int interactive_add(int argc, const char **argv, const char *prefix, int patch)
46b5139c 204{
5a76aff1 205 struct pathspec pathspec;
46b5139c 206
625c3304 207 parse_pathspec(&pathspec, 0,
5a76aff1 208 PATHSPEC_PREFER_FULL |
480ca644
NTND
209 PATHSPEC_SYMLINK_LEADING_PATH |
210 PATHSPEC_PREFIX_ORIGIN,
5a76aff1 211 prefix, argv);
46b5139c
TR
212
213 return run_add_interactive(NULL,
b4bd4668 214 patch ? "--patch" : NULL,
480ca644 215 &pathspec);
46b5139c
TR
216}
217
2af202be 218static int edit_patch(int argc, const char **argv, const char *prefix)
c59cb03a 219{
d292bfaf 220 char *file = git_pathdup("ADD_EDIT.patch");
c59cb03a 221 const char *apply_argv[] = { "apply", "--recount", "--cached",
66dbfd55 222 NULL, NULL };
d3180279 223 struct child_process child = CHILD_PROCESS_INIT;
c59cb03a
JS
224 struct rev_info rev;
225 int out;
226 struct stat st;
227
66dbfd55
GV
228 apply_argv[3] = file;
229
c59cb03a
JS
230 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
231
232 if (read_cache() < 0)
d521abf8 233 die(_("Could not read the index"));
c59cb03a
JS
234
235 init_revisions(&rev, prefix);
236 rev.diffopt.context = 7;
237
238 argc = setup_revisions(argc, argv, &rev, NULL);
239 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
7f3b8c62 240 rev.diffopt.use_color = 0;
0d1e0e78 241 rev.diffopt.flags.ignore_dirty_submodules = 1;
6ff2b729 242 out = open(file, O_CREAT | O_WRONLY, 0666);
c59cb03a 243 if (out < 0)
d521abf8 244 die(_("Could not open '%s' for writing."), file);
41698375 245 rev.diffopt.file = xfdopen(out, "w");
c59cb03a
JS
246 rev.diffopt.close_file = 1;
247 if (run_diff_files(&rev, 0))
d521abf8 248 die(_("Could not write patch"));
c59cb03a 249
cb64800d
JK
250 if (launch_editor(file, NULL, NULL))
251 die(_("editing patch failed"));
c59cb03a
JS
252
253 if (stat(file, &st))
990ac4be 254 die_errno(_("Could not stat '%s'"), file);
c59cb03a 255 if (!st.st_size)
990ac4be 256 die(_("Empty patch. Aborted."));
c59cb03a 257
c59cb03a
JS
258 child.git_cmd = 1;
259 child.argv = apply_argv;
260 if (run_command(&child))
d521abf8 261 die(_("Could not apply '%s'"), file);
c59cb03a
JS
262
263 unlink(file);
d292bfaf 264 free(file);
c59cb03a
JS
265 return 0;
266}
267
021b6e45 268static struct lock_file lock_file;
0d781539 269
b39c53e6 270static const char ignore_error[] =
439fb829 271N_("The following paths are ignored by one of your .gitignore files:\n");
6a1ad325 272
300c0a22 273static int verbose, show_only, ignored_too, refresh_only;
45c45e30 274static int ignore_add_errors, intent_to_add, ignore_missing;
53213994 275static int warn_on_embedded_repo = 1;
45c45e30 276
fdc97abd 277#define ADDREMOVE_DEFAULT 1
45c45e30
JH
278static int addremove = ADDREMOVE_DEFAULT;
279static int addremove_explicit = -1; /* unspecified */
5c46f754 280
4e55ed32
ET
281static char *chmod_arg;
282
9f60f49b
JH
283static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
284{
285 /* if we are told to ignore, we are not adding removals */
286 *(int *)opt->value = !unset ? 0 : 1;
287 return 0;
288}
289
5c46f754 290static struct option builtin_add_options[] = {
1b56024c
NTND
291 OPT__DRY_RUN(&show_only, N_("dry run")),
292 OPT__VERBOSE(&verbose, N_("be verbose")),
5c46f754 293 OPT_GROUP(""),
300c0a22
JH
294 OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
295 OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
296 OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
1b56024c 297 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
300c0a22 298 OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
9472935d 299 OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
300c0a22 300 OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
45c45e30 301 OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
9f60f49b
JH
302 { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
303 NULL /* takes no arguments */,
304 N_("ignore paths removed in the working tree (same as --no-all)"),
305 PARSE_OPT_NOARG, ignore_removal_cb },
300c0a22
JH
306 OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
307 OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
308 OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
4e55ed32 309 OPT_STRING( 0 , "chmod", &chmod_arg, N_("(+/-)x"), N_("override the executable bit of the listed files")),
53213994
JK
310 OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
311 N_("warn when adding an embedded repository")),
5c46f754
KH
312 OPT_END(),
313};
314
9bd81e42 315static int add_config(const char *var, const char *value, void *cb)
dad25e4a 316{
8c2be75f
JN
317 if (!strcmp(var, "add.ignoreerrors") ||
318 !strcmp(var, "add.ignore-errors")) {
dad25e4a
AR
319 ignore_add_errors = git_config_bool(var, value);
320 return 0;
321 }
9bd81e42 322 return git_default_config(var, value, cb);
dad25e4a
AR
323}
324
53213994
JK
325static const char embedded_advice[] = N_(
326"You've added another git repository inside your current repository.\n"
327"Clones of the outer repository will not contain the contents of\n"
328"the embedded repository and will not know how to obtain it.\n"
329"If you meant to add a submodule, use:\n"
330"\n"
331" git submodule add <url> %s\n"
332"\n"
333"If you added this path by mistake, you can remove it from the\n"
334"index with:\n"
335"\n"
336" git rm --cached %s\n"
337"\n"
338"See \"git help submodule\" for more information."
339);
340
341static void check_embedded_repo(const char *path)
342{
343 struct strbuf name = STRBUF_INIT;
344
345 if (!warn_on_embedded_repo)
346 return;
347 if (!ends_with(path, "/"))
348 return;
349
350 /* Drop trailing slash for aesthetics */
351 strbuf_addstr(&name, path);
352 strbuf_strip_suffix(&name, "/");
353
354 warning(_("adding embedded git repository: %s"), name.buf);
355 if (advice_add_embedded_repo) {
356 advise(embedded_advice, name.buf, name.buf);
357 /* there may be multiple entries; advise only once */
358 advice_add_embedded_repo = 0;
359 }
360
361 strbuf_release(&name);
362}
363
610d55af 364static int add_files(struct dir_struct *dir, int flags)
c972ec04
JH
365{
366 int i, exit_status = 0;
367
368 if (dir->ignored_nr) {
439fb829 369 fprintf(stderr, _(ignore_error));
c972ec04
JH
370 for (i = 0; i < dir->ignored_nr; i++)
371 fprintf(stderr, "%s\n", dir->ignored[i]->name);
439fb829 372 fprintf(stderr, _("Use -f if you really want to add them.\n"));
1d31e5a2 373 exit_status = 1;
c972ec04
JH
374 }
375
53213994
JK
376 for (i = 0; i < dir->nr; i++) {
377 check_embedded_repo(dir->entries[i]->name);
610d55af 378 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
c972ec04 379 if (!ignore_add_errors)
990ac4be 380 die(_("adding files failed"));
c972ec04
JH
381 exit_status = 1;
382 }
53213994 383 }
c972ec04
JH
384 return exit_status;
385}
386
a633fca0 387int cmd_add(int argc, const char **argv, const char *prefix)
0d781539 388{
7ae02a30 389 int exit_status = 0;
5a76aff1 390 struct pathspec pathspec;
0d781539 391 struct dir_struct dir;
610d55af 392 int flags;
c972ec04
JH
393 int add_new_files;
394 int require_pathspec;
81f45e7d 395 char *seen = NULL;
5cde71d6 396
ed342fde
SB
397 git_config(add_config, NULL);
398
37782920 399 argc = parse_options(argc, argv, prefix, builtin_add_options,
c59cb03a 400 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
b63e9950
WC
401 if (patch_interactive)
402 add_interactive = 1;
7c0ab445 403 if (add_interactive)
b4bd4668 404 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
0d781539 405
c59cb03a
JS
406 if (edit_interactive)
407 return(edit_patch(argc, argv, prefix));
408 argc--;
409 argv++;
410
45c45e30
JH
411 if (0 <= addremove_explicit)
412 addremove = addremove_explicit;
413 else if (take_worktree_changes && ADDREMOVE_DEFAULT)
414 addremove = 0; /* "-u" was given but not "-A" */
415
3ba1f114 416 if (addremove && take_worktree_changes)
990ac4be 417 die(_("-A and -u are mutually incompatible"));
45c45e30 418
45c45e30 419 if (!take_worktree_changes && addremove_explicit < 0 && argc)
fdc97abd
JH
420 /* Turn "git add pathspec..." to "git add -A pathspec..." */
421 addremove = 1;
45c45e30 422
108da0db 423 if (!show_only && ignore_missing)
990ac4be 424 die(_("Option --ignore-missing can only be used together with --dry-run"));
808d3d71 425
610d55af
TG
426 if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
427 chmod_arg[1] != 'x' || chmod_arg[2]))
4e55ed32
ET
428 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
429
9472935d 430 add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
29abb339 431 require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
c972ec04 432
b3e83cc7 433 hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
0d781539 434
205ffa94 435 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
01665924 436 (show_only ? ADD_CACHE_PRETEND : 0) |
39425819 437 (intent_to_add ? ADD_CACHE_INTENT : 0) |
1e5f764c
JH
438 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
439 (!(addremove || take_worktree_changes)
808d3d71 440 ? ADD_CACHE_IGNORE_REMOVAL : 0));
205ffa94 441
c972ec04 442 if (require_pathspec && argc == 0) {
990ac4be
ÆAB
443 fprintf(stderr, _("Nothing specified, nothing added.\n"));
444 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
93b0d86a
JH
445 return 0;
446 }
0d781539 447
366bfcb6 448 if (read_cache() < 0)
990ac4be 449 die(_("index file corrupt"));
5a76aff1 450
bdab9721
BW
451 die_in_unpopulated_submodule(&the_index, prefix);
452
5a76aff1
NTND
453 /*
454 * Check the "pathspec '%s' did not match any files" block
455 * below before enabling new magic.
456 */
457 parse_pathspec(&pathspec, 0,
458 PATHSPEC_PREFER_FULL |
c08397e3 459 PATHSPEC_SYMLINK_LEADING_PATH,
5a76aff1 460 prefix, argv);
366bfcb6 461
c08397e3
BW
462 die_path_inside_submodule(&the_index, &pathspec);
463
1d8842d9
LT
464 if (add_new_files) {
465 int baselen;
466
467 /* Set up the default git porcelain excludes */
468 memset(&dir, 0, sizeof(dir));
469 if (!ignored_too) {
470 dir.flags |= DIR_COLLECT_IGNORED;
471 setup_standard_excludes(&dir);
472 }
473
1e5f764c 474 /* This picks up the paths that are not tracked */
0d32c183 475 baselen = fill_directory(&dir, &the_index, &pathspec);
5a76aff1 476 if (pathspec.nr)
053a6b18 477 seen = prune_directory(&dir, &pathspec, baselen);
1d8842d9 478 }
1e5f764c 479
c972ec04 480 if (refresh_only) {
9b2d6149 481 refresh(verbose, &pathspec);
c972ec04 482 goto finish;
6a1ad325
JH
483 }
484
5a76aff1 485 if (pathspec.nr) {
81f45e7d 486 int i;
eb69934b 487
81f45e7d 488 if (!seen)
08de9151 489 seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
5a76aff1
NTND
490
491 /*
492 * file_exists() assumes exact match
493 */
bd30c2e4
NTND
494 GUARD_PATHSPEC(&pathspec,
495 PATHSPEC_FROMTOP |
496 PATHSPEC_LITERAL |
93d93537 497 PATHSPEC_GLOB |
ef79b1f8
NTND
498 PATHSPEC_ICASE |
499 PATHSPEC_EXCLUDE);
5a76aff1 500
84b8b5d1
NTND
501 for (i = 0; i < pathspec.nr; i++) {
502 const char *path = pathspec.items[i].match;
ef79b1f8
NTND
503 if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
504 continue;
64ed07ce 505 if (!seen[i] && path[0] &&
93d93537
NTND
506 ((pathspec.items[i].magic &
507 (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
bd30c2e4 508 !file_exists(path))) {
108da0db 509 if (ignore_missing) {
0188f6b3 510 int dtype = DT_UNKNOWN;
a0bba65b 511 if (is_excluded(&dir, &the_index, path, &dtype))
9e58beca
BW
512 dir_add_ignored(&dir, &the_index,
513 path, pathspec.items[i].len);
108da0db 514 } else
48168851 515 die(_("pathspec '%s' did not match any files"),
84b8b5d1 516 pathspec.items[i].original);
108da0db 517 }
81f45e7d
JH
518 }
519 free(seen);
520 }
521
568508e7
JH
522 plug_bulk_checkin();
523
9472935d
TB
524 if (add_renormalize)
525 exit_status |= renormalize_tracked_files(&pathspec, flags);
526 else
527 exit_status |= add_files_to_cache(prefix, &pathspec, flags);
c972ec04
JH
528
529 if (add_new_files)
610d55af 530 exit_status |= add_files(&dir, flags);
0d781539 531
610d55af
TG
532 if (chmod_arg && pathspec.nr)
533 chmod_pathspec(&pathspec, chmod_arg[0]);
568508e7
JH
534 unplug_bulk_checkin();
535
d521abf8 536finish:
0d781539 537 if (active_cache_changed) {
03b86647 538 if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
990ac4be 539 die(_("Unable to write new index file"));
0d781539
LT
540 }
541
0e5bba53
JK
542 UNLEAK(pathspec);
543 UNLEAK(dir);
7ae02a30 544 return exit_status;
0d781539 545}