]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/add.c
pathspec: stop calling ensure_full_index
[thirdparty/git.git] / builtin / add.c
CommitLineData
0d781539
LT
1/*
2 * "git add" builtin command
3 *
4 * Copyright (C) 2006 Linus Torvalds
5 */
f8adbec9 6#define USE_THE_INDEX_COMPATIBILITY_MACROS
0d781539 7#include "cache.h"
b2141fc1 8#include "config.h"
0d781539 9#include "builtin.h"
697cc8ef 10#include "lockfile.h"
0d781539 11#include "dir.h"
6f525e71 12#include "pathspec.h"
d807c4a0 13#include "exec-cmd.h"
93872e07 14#include "cache-tree.h"
58680165 15#include "run-command.h"
5c46f754 16#include "parse-options.h"
c59cb03a 17#include "diff.h"
fb7d3f32 18#include "diffcore.h"
c59cb03a 19#include "revision.h"
568508e7 20#include "bulk-checkin.h"
dbbcd44f 21#include "strvec.h"
bdab9721 22#include "submodule.h"
f83dff60 23#include "add-interactive.h"
0d781539 24
5c46f754 25static const char * const builtin_add_usage[] = {
9c9b4f2f 26 N_("git add [<options>] [--] <pathspec>..."),
5c46f754
KH
27 NULL
28};
c59cb03a 29static int patch_interactive, add_interactive, edit_interactive;
93c44d49 30static int take_worktree_changes;
9472935d 31static int add_renormalize;
bebb5d6d
AM
32static int pathspec_file_nul;
33static const char *pathspec_from_file;
90a6bb98 34static int legacy_stash_p; /* support for the scripted `git stash` */
896bdfa2 35
9cba13ca 36struct update_callback_data {
610d55af 37 int flags;
fb7d3f32
LT
38 int add_errors;
39};
40
9ebd7fe1 41static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only)
610d55af 42{
9ebd7fe1 43 int i, ret = 0;
610d55af
TG
44
45 for (i = 0; i < active_nr; i++) {
46 struct cache_entry *ce = active_cache[i];
c937d70b 47 int err;
610d55af 48
d73dbafc
MT
49 if (ce_skip_worktree(ce))
50 continue;
51
6d2df284 52 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
610d55af
TG
53 continue;
54
c937d70b
MT
55 if (!show_only)
56 err = chmod_cache_entry(ce, flip);
57 else
58 err = S_ISREG(ce->ce_mode) ? 0 : -1;
59
60 if (err < 0)
9ebd7fe1 61 ret = error(_("cannot chmod %cx '%s'"), flip, ce->name);
610d55af 62 }
9ebd7fe1
MT
63
64 return ret;
610d55af
TG
65}
66
75973b2c
JH
67static int fix_unmerged_status(struct diff_filepair *p,
68 struct update_callback_data *data)
69{
70 if (p->status != DIFF_STATUS_UNMERGED)
71 return p->status;
72 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
73 /*
74 * This is not an explicit add request, and the
75 * path is missing from the working tree (deleted)
76 */
77 return DIFF_STATUS_DELETED;
78 else
79 /*
80 * Either an explicit add request, or path exists
81 * in the working tree. An attempt to explicitly
82 * add a path that does not exist in the working tree
83 * will be caught as an error by the caller immediately.
84 */
85 return DIFF_STATUS_MODIFIED;
86}
87
fb7d3f32
LT
88static void update_callback(struct diff_queue_struct *q,
89 struct diff_options *opt, void *cbdata)
90{
91 int i;
92 struct update_callback_data *data = cbdata;
93
94 for (i = 0; i < q->nr; i++) {
95 struct diff_filepair *p = q->queue[i];
96 const char *path = p->one->path;
75973b2c 97 switch (fix_unmerged_status(p, data)) {
fb7d3f32 98 default:
990ac4be 99 die(_("unexpected diff status %c"), p->status);
fb7d3f32
LT
100 case DIFF_STATUS_MODIFIED:
101 case DIFF_STATUS_TYPE_CHANGED:
610d55af 102 if (add_file_to_index(&the_index, path, data->flags)) {
fb7d3f32 103 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
990ac4be 104 die(_("updating files failed"));
fb7d3f32
LT
105 data->add_errors++;
106 }
107 break;
108 case DIFF_STATUS_DELETED:
109 if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
110 break;
111 if (!(data->flags & ADD_CACHE_PRETEND))
112 remove_file_from_index(&the_index, path);
113 if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
475c73eb 114 printf(_("remove '%s'\n"), path);
fb7d3f32
LT
115 break;
116 }
117 }
118}
119
610d55af
TG
120int add_files_to_cache(const char *prefix,
121 const struct pathspec *pathspec, int flags)
fb7d3f32 122{
160c4b18 123 struct update_callback_data data;
fb7d3f32 124 struct rev_info rev;
71c7b053 125
160c4b18
JH
126 memset(&data, 0, sizeof(data));
127 data.flags = flags;
128
2abf3503 129 repo_init_revisions(the_repository, &rev, prefix);
fb7d3f32 130 setup_revisions(0, NULL, &rev, NULL);
3efe8e43
NTND
131 if (pathspec)
132 copy_pathspec(&rev.prune_data, pathspec);
fb7d3f32
LT
133 rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
134 rev.diffopt.format_callback = update_callback;
160c4b18 135 rev.diffopt.format_callback_data = &data;
0d1e0e78 136 rev.diffopt.flags.override_submodule_config = 1;
75973b2c 137 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
fb7d3f32 138 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
fe6a01af 139 clear_pathspec(&rev.prune_data);
fb7d3f32
LT
140 return !!data.add_errors;
141}
142
9472935d
TB
143static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
144{
145 int i, retval = 0;
146
54beed24
DS
147 /* TODO: audit for interaction with sparse-index. */
148 ensure_full_index(&the_index);
9472935d
TB
149 for (i = 0; i < active_nr; i++) {
150 struct cache_entry *ce = active_cache[i];
151
d73dbafc
MT
152 if (ce_skip_worktree(ce))
153 continue;
9472935d
TB
154 if (ce_stage(ce))
155 continue; /* do not touch unmerged paths */
156 if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
157 continue; /* do not touch non blobs */
6d2df284 158 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
9472935d 159 continue;
9e5da3d0 160 retval |= add_file_to_cache(ce->name, flags | ADD_CACHE_RENORMALIZE);
9472935d
TB
161 }
162
163 return retval;
164}
165
053a6b18 166static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
0d781539 167{
f2593398 168 char *seen;
84b8b5d1 169 int i;
0d781539
LT
170 struct dir_entry **src, **dst;
171
84b8b5d1 172 seen = xcalloc(pathspec->nr, 1);
f2593398 173
0d781539
LT
174 src = dst = dir->entries;
175 i = dir->nr;
176 while (--i >= 0) {
177 struct dir_entry *entry = *src++;
6d2df284 178 if (dir_path_match(&the_index, entry, pathspec, prefix, seen))
4d06f8ac 179 *dst++ = entry;
0d781539
LT
180 }
181 dir->nr = dst - dir->entries;
719630eb 182 add_pathspec_matches_against_index(pathspec, &the_index, seen,
a20f7047 183 PS_IGNORE_SKIP_WORKTREE);
81f45e7d 184 return seen;
0d781539
LT
185}
186
a20f7047 187static int refresh(int verbose, const struct pathspec *pathspec)
d616813d
AJ
188{
189 char *seen;
a20f7047
MT
190 int i, ret = 0;
191 char *skip_worktree_seen = NULL;
192 struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
193 int flags = REFRESH_IGNORE_SKIP_WORKTREE |
194 (verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
d616813d 195
9b2d6149 196 seen = xcalloc(pathspec->nr, 1);
a20f7047
MT
197 refresh_index(&the_index, flags, pathspec, seen,
198 _("Unstaged changes after refreshing the index:"));
9b2d6149 199 for (i = 0; i < pathspec->nr; i++) {
a20f7047
MT
200 if (!seen[i]) {
201 if (matches_skip_worktree(pathspec, i, &skip_worktree_seen)) {
202 string_list_append(&only_match_skip_worktree,
203 pathspec->items[i].original);
204 } else {
205 die(_("pathspec '%s' did not match any files"),
206 pathspec->items[i].original);
207 }
208 }
209 }
210
211 if (only_match_skip_worktree.nr) {
212 advise_on_updating_sparse_paths(&only_match_skip_worktree);
213 ret = 1;
d616813d 214 }
a20f7047 215
ec36c42a 216 free(seen);
a20f7047
MT
217 free(skip_worktree_seen);
218 string_list_clear(&only_match_skip_worktree, 0);
219 return ret;
d616813d
AJ
220}
221
46b5139c 222int run_add_interactive(const char *revision, const char *patch_mode,
480ca644 223 const struct pathspec *pathspec)
58680165 224{
c45a18e8 225 int status, i;
22f9b7f3 226 struct strvec argv = STRVEC_INIT;
f83dff60
JS
227 int use_builtin_add_i =
228 git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
229
2df2d81d
JH
230 if (use_builtin_add_i < 0) {
231 int experimental;
232 if (!git_config_get_bool("add.interactive.usebuiltin",
233 &use_builtin_add_i))
234 ; /* ok */
235 else if (!git_config_get_bool("feature.experimental", &experimental) &&
236 experimental)
237 use_builtin_add_i = 1;
238 }
f6aa7ecc
JS
239
240 if (use_builtin_add_i == 1) {
d2a233cb
JS
241 enum add_p_mode mode;
242
f6aa7ecc 243 if (!patch_mode)
f83dff60 244 return !!run_add_i(the_repository, pathspec);
d2a233cb
JS
245
246 if (!strcmp(patch_mode, "--patch"))
247 mode = ADD_P_ADD;
36bae1dc
JS
248 else if (!strcmp(patch_mode, "--patch=stash"))
249 mode = ADD_P_STASH;
250 else if (!strcmp(patch_mode, "--patch=reset"))
251 mode = ADD_P_RESET;
52628f94
JS
252 else if (!strcmp(patch_mode, "--patch=checkout"))
253 mode = ADD_P_CHECKOUT;
cee6cb73
JS
254 else if (!strcmp(patch_mode, "--patch=worktree"))
255 mode = ADD_P_WORKTREE;
d2a233cb 256 else
52628f94 257 die("'%s' not supported", patch_mode);
d2a233cb
JS
258
259 return !!run_add_p(the_repository, mode, revision, pathspec);
f83dff60 260 }
3f061887 261
22f9b7f3 262 strvec_push(&argv, "add--interactive");
46b5139c 263 if (patch_mode)
22f9b7f3 264 strvec_push(&argv, patch_mode);
46b5139c 265 if (revision)
22f9b7f3
JK
266 strvec_push(&argv, revision);
267 strvec_push(&argv, "--");
480ca644
NTND
268 for (i = 0; i < pathspec->nr; i++)
269 /* pass original pathspec, to be re-parsed */
22f9b7f3 270 strvec_push(&argv, pathspec->items[i].original);
7c0ab445 271
d70a9eb6 272 status = run_command_v_opt(argv.v, RUN_GIT_CMD);
22f9b7f3 273 strvec_clear(&argv);
7c0ab445 274 return status;
58680165
KH
275}
276
e885a84f 277int interactive_add(const char **argv, const char *prefix, int patch)
46b5139c 278{
5a76aff1 279 struct pathspec pathspec;
46b5139c 280
625c3304 281 parse_pathspec(&pathspec, 0,
5a76aff1 282 PATHSPEC_PREFER_FULL |
480ca644
NTND
283 PATHSPEC_SYMLINK_LEADING_PATH |
284 PATHSPEC_PREFIX_ORIGIN,
5a76aff1 285 prefix, argv);
46b5139c
TR
286
287 return run_add_interactive(NULL,
b4bd4668 288 patch ? "--patch" : NULL,
480ca644 289 &pathspec);
46b5139c
TR
290}
291
2af202be 292static int edit_patch(int argc, const char **argv, const char *prefix)
c59cb03a 293{
d292bfaf 294 char *file = git_pathdup("ADD_EDIT.patch");
c59cb03a 295 const char *apply_argv[] = { "apply", "--recount", "--cached",
66dbfd55 296 NULL, NULL };
d3180279 297 struct child_process child = CHILD_PROCESS_INIT;
c59cb03a
JS
298 struct rev_info rev;
299 int out;
300 struct stat st;
301
66dbfd55
GV
302 apply_argv[3] = file;
303
c59cb03a
JS
304 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
305
306 if (read_cache() < 0)
d521abf8 307 die(_("Could not read the index"));
c59cb03a 308
2abf3503 309 repo_init_revisions(the_repository, &rev, prefix);
c59cb03a
JS
310 rev.diffopt.context = 7;
311
312 argc = setup_revisions(argc, argv, &rev, NULL);
313 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
7f3b8c62 314 rev.diffopt.use_color = 0;
0d1e0e78 315 rev.diffopt.flags.ignore_dirty_submodules = 1;
fa6f225e 316 out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
c59cb03a 317 if (out < 0)
d521abf8 318 die(_("Could not open '%s' for writing."), file);
41698375 319 rev.diffopt.file = xfdopen(out, "w");
c59cb03a
JS
320 rev.diffopt.close_file = 1;
321 if (run_diff_files(&rev, 0))
d521abf8 322 die(_("Could not write patch"));
c59cb03a 323
cb64800d
JK
324 if (launch_editor(file, NULL, NULL))
325 die(_("editing patch failed"));
c59cb03a
JS
326
327 if (stat(file, &st))
990ac4be 328 die_errno(_("Could not stat '%s'"), file);
c59cb03a 329 if (!st.st_size)
990ac4be 330 die(_("Empty patch. Aborted."));
c59cb03a 331
c59cb03a
JS
332 child.git_cmd = 1;
333 child.argv = apply_argv;
334 if (run_command(&child))
d521abf8 335 die(_("Could not apply '%s'"), file);
c59cb03a
JS
336
337 unlink(file);
d292bfaf 338 free(file);
c59cb03a
JS
339 return 0;
340}
341
b39c53e6 342static const char ignore_error[] =
439fb829 343N_("The following paths are ignored by one of your .gitignore files:\n");
6a1ad325 344
300c0a22 345static int verbose, show_only, ignored_too, refresh_only;
45c45e30 346static int ignore_add_errors, intent_to_add, ignore_missing;
53213994 347static int warn_on_embedded_repo = 1;
45c45e30 348
fdc97abd 349#define ADDREMOVE_DEFAULT 1
45c45e30
JH
350static int addremove = ADDREMOVE_DEFAULT;
351static int addremove_explicit = -1; /* unspecified */
5c46f754 352
4e55ed32
ET
353static char *chmod_arg;
354
9f60f49b
JH
355static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
356{
357 /* if we are told to ignore, we are not adding removals */
358 *(int *)opt->value = !unset ? 0 : 1;
359 return 0;
360}
361
5c46f754 362static struct option builtin_add_options[] = {
1b56024c
NTND
363 OPT__DRY_RUN(&show_only, N_("dry run")),
364 OPT__VERBOSE(&verbose, N_("be verbose")),
5c46f754 365 OPT_GROUP(""),
300c0a22
JH
366 OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
367 OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
368 OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
1224781d 369 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
300c0a22 370 OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
9472935d 371 OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
300c0a22 372 OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
45c45e30 373 OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
203c8533 374 OPT_CALLBACK_F(0, "ignore-removal", &addremove_explicit,
9f60f49b
JH
375 NULL /* takes no arguments */,
376 N_("ignore paths removed in the working tree (same as --no-all)"),
203c8533 377 PARSE_OPT_NOARG, ignore_removal_cb),
300c0a22
JH
378 OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
379 OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
380 OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
5f0df44c
RS
381 OPT_STRING(0, "chmod", &chmod_arg, "(+|-)x",
382 N_("override the executable bit of the listed files")),
53213994
JK
383 OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
384 N_("warn when adding an embedded repository")),
90a6bb98
JS
385 OPT_HIDDEN_BOOL(0, "legacy-stash-p", &legacy_stash_p,
386 N_("backend for `git stash -p`")),
bebb5d6d
AM
387 OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
388 OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
5c46f754
KH
389 OPT_END(),
390};
391
9bd81e42 392static int add_config(const char *var, const char *value, void *cb)
dad25e4a 393{
8c2be75f
JN
394 if (!strcmp(var, "add.ignoreerrors") ||
395 !strcmp(var, "add.ignore-errors")) {
dad25e4a
AR
396 ignore_add_errors = git_config_bool(var, value);
397 return 0;
398 }
f83dff60 399
9bd81e42 400 return git_default_config(var, value, cb);
dad25e4a
AR
401}
402
53213994
JK
403static const char embedded_advice[] = N_(
404"You've added another git repository inside your current repository.\n"
405"Clones of the outer repository will not contain the contents of\n"
406"the embedded repository and will not know how to obtain it.\n"
407"If you meant to add a submodule, use:\n"
408"\n"
409" git submodule add <url> %s\n"
410"\n"
411"If you added this path by mistake, you can remove it from the\n"
412"index with:\n"
413"\n"
414" git rm --cached %s\n"
415"\n"
416"See \"git help submodule\" for more information."
417);
418
419static void check_embedded_repo(const char *path)
420{
421 struct strbuf name = STRBUF_INIT;
422
423 if (!warn_on_embedded_repo)
424 return;
425 if (!ends_with(path, "/"))
426 return;
427
428 /* Drop trailing slash for aesthetics */
429 strbuf_addstr(&name, path);
430 strbuf_strip_suffix(&name, "/");
431
432 warning(_("adding embedded git repository: %s"), name.buf);
433 if (advice_add_embedded_repo) {
434 advise(embedded_advice, name.buf, name.buf);
435 /* there may be multiple entries; advise only once */
436 advice_add_embedded_repo = 0;
437 }
438
439 strbuf_release(&name);
440}
441
610d55af 442static int add_files(struct dir_struct *dir, int flags)
c972ec04
JH
443{
444 int i, exit_status = 0;
445
446 if (dir->ignored_nr) {
439fb829 447 fprintf(stderr, _(ignore_error));
c972ec04
JH
448 for (i = 0; i < dir->ignored_nr; i++)
449 fprintf(stderr, "%s\n", dir->ignored[i]->name);
887a0fd5
HW
450 if (advice_add_ignored_file)
451 advise(_("Use -f if you really want to add them.\n"
452 "Turn this message off by running\n"
453 "\"git config advice.addIgnoredFile false\""));
1d31e5a2 454 exit_status = 1;
c972ec04
JH
455 }
456
53213994 457 for (i = 0; i < dir->nr; i++) {
610d55af 458 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
c972ec04 459 if (!ignore_add_errors)
990ac4be 460 die(_("adding files failed"));
c972ec04 461 exit_status = 1;
f937bc2f
KM
462 } else {
463 check_embedded_repo(dir->entries[i]->name);
c972ec04 464 }
53213994 465 }
c972ec04
JH
466 return exit_status;
467}
468
a633fca0 469int cmd_add(int argc, const char **argv, const char *prefix)
0d781539 470{
7ae02a30 471 int exit_status = 0;
5a76aff1 472 struct pathspec pathspec;
0d781539 473 struct dir_struct dir;
610d55af 474 int flags;
c972ec04
JH
475 int add_new_files;
476 int require_pathspec;
81f45e7d 477 char *seen = NULL;
0fa5a2ed 478 struct lock_file lock_file = LOCK_INIT;
5cde71d6 479
ed342fde
SB
480 git_config(add_config, NULL);
481
37782920 482 argc = parse_options(argc, argv, prefix, builtin_add_options,
c59cb03a 483 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
b63e9950
WC
484 if (patch_interactive)
485 add_interactive = 1;
bebb5d6d 486 if (add_interactive) {
a1989cf7
ØW
487 if (show_only)
488 die(_("--dry-run is incompatible with --interactive/--patch"));
bebb5d6d
AM
489 if (pathspec_from_file)
490 die(_("--pathspec-from-file is incompatible with --interactive/--patch"));
e885a84f 491 exit(interactive_add(argv + 1, prefix, patch_interactive));
bebb5d6d 492 }
90a6bb98
JS
493 if (legacy_stash_p) {
494 struct pathspec pathspec;
495
496 parse_pathspec(&pathspec, 0,
497 PATHSPEC_PREFER_FULL |
498 PATHSPEC_SYMLINK_LEADING_PATH |
499 PATHSPEC_PREFIX_ORIGIN,
500 prefix, argv);
501
502 return run_add_interactive(NULL, "--patch=stash", &pathspec);
503 }
0d781539 504
bebb5d6d
AM
505 if (edit_interactive) {
506 if (pathspec_from_file)
507 die(_("--pathspec-from-file is incompatible with --edit"));
c59cb03a 508 return(edit_patch(argc, argv, prefix));
bebb5d6d 509 }
c59cb03a
JS
510 argc--;
511 argv++;
512
45c45e30
JH
513 if (0 <= addremove_explicit)
514 addremove = addremove_explicit;
515 else if (take_worktree_changes && ADDREMOVE_DEFAULT)
516 addremove = 0; /* "-u" was given but not "-A" */
517
3ba1f114 518 if (addremove && take_worktree_changes)
990ac4be 519 die(_("-A and -u are mutually incompatible"));
45c45e30 520
108da0db 521 if (!show_only && ignore_missing)
990ac4be 522 die(_("Option --ignore-missing can only be used together with --dry-run"));
808d3d71 523
610d55af
TG
524 if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
525 chmod_arg[1] != 'x' || chmod_arg[2]))
4e55ed32
ET
526 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
527
9472935d 528 add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
29abb339 529 require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
c972ec04 530
5e7cbab1
DS
531 prepare_repo_settings(the_repository);
532 the_repository->settings.command_requires_full_index = 0;
533
b3e83cc7 534 hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
0d781539 535
5a76aff1
NTND
536 /*
537 * Check the "pathspec '%s' did not match any files" block
538 * below before enabling new magic.
539 */
84d938b7 540 parse_pathspec(&pathspec, PATHSPEC_ATTR,
5a76aff1 541 PATHSPEC_PREFER_FULL |
c08397e3 542 PATHSPEC_SYMLINK_LEADING_PATH,
5a76aff1 543 prefix, argv);
366bfcb6 544
bebb5d6d
AM
545 if (pathspec_from_file) {
546 if (pathspec.nr)
547 die(_("--pathspec-from-file is incompatible with pathspec arguments"));
548
549 parse_pathspec_file(&pathspec, PATHSPEC_ATTR,
550 PATHSPEC_PREFER_FULL |
551 PATHSPEC_SYMLINK_LEADING_PATH,
552 prefix, pathspec_from_file, pathspec_file_nul);
553 } else if (pathspec_file_nul) {
554 die(_("--pathspec-file-nul requires --pathspec-from-file"));
555 }
556
557 if (require_pathspec && pathspec.nr == 0) {
21bb3083 558 fprintf(stderr, _("Nothing specified, nothing added.\n"));
887a0fd5
HW
559 if (advice_add_empty_pathspec)
560 advise( _("Maybe you wanted to say 'git add .'?\n"
561 "Turn this message off by running\n"
562 "\"git config advice.addEmptyPathspec false\""));
21bb3083
AM
563 return 0;
564 }
565
bebb5d6d 566 if (!take_worktree_changes && addremove_explicit < 0 && pathspec.nr)
21bb3083
AM
567 /* Turn "git add pathspec..." to "git add -A pathspec..." */
568 addremove = 1;
569
570 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
571 (show_only ? ADD_CACHE_PRETEND : 0) |
572 (intent_to_add ? ADD_CACHE_INTENT : 0) |
573 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
574 (!(addremove || take_worktree_changes)
575 ? ADD_CACHE_IGNORE_REMOVAL : 0));
576
d1664e73
BP
577 if (read_cache_preload(&pathspec) < 0)
578 die(_("index file corrupt"));
579
580 die_in_unpopulated_submodule(&the_index, prefix);
c08397e3
BW
581 die_path_inside_submodule(&the_index, &pathspec);
582
eceba532 583 dir_init(&dir);
1d8842d9
LT
584 if (add_new_files) {
585 int baselen;
586
587 /* Set up the default git porcelain excludes */
1d8842d9
LT
588 if (!ignored_too) {
589 dir.flags |= DIR_COLLECT_IGNORED;
590 setup_standard_excludes(&dir);
591 }
592
1e5f764c 593 /* This picks up the paths that are not tracked */
0d32c183 594 baselen = fill_directory(&dir, &the_index, &pathspec);
5a76aff1 595 if (pathspec.nr)
053a6b18 596 seen = prune_directory(&dir, &pathspec, baselen);
1d8842d9 597 }
1e5f764c 598
c972ec04 599 if (refresh_only) {
a20f7047 600 exit_status |= refresh(verbose, &pathspec);
c972ec04 601 goto finish;
6a1ad325
JH
602 }
603
5a76aff1 604 if (pathspec.nr) {
81f45e7d 605 int i;
a20f7047
MT
606 char *skip_worktree_seen = NULL;
607 struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
eb69934b 608
81f45e7d 609 if (!seen)
719630eb 610 seen = find_pathspecs_matching_against_index(&pathspec,
a20f7047 611 &the_index, PS_IGNORE_SKIP_WORKTREE);
5a76aff1
NTND
612
613 /*
614 * file_exists() assumes exact match
615 */
bd30c2e4
NTND
616 GUARD_PATHSPEC(&pathspec,
617 PATHSPEC_FROMTOP |
618 PATHSPEC_LITERAL |
93d93537 619 PATHSPEC_GLOB |
ef79b1f8
NTND
620 PATHSPEC_ICASE |
621 PATHSPEC_EXCLUDE);
5a76aff1 622
84b8b5d1
NTND
623 for (i = 0; i < pathspec.nr; i++) {
624 const char *path = pathspec.items[i].match;
a20f7047 625
ef79b1f8
NTND
626 if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
627 continue;
a20f7047
MT
628 if (seen[i])
629 continue;
630
631 if (matches_skip_worktree(&pathspec, i, &skip_worktree_seen)) {
632 string_list_append(&only_match_skip_worktree,
633 pathspec.items[i].original);
634 continue;
635 }
636
637 /* Don't complain at 'git add .' on empty repo */
638 if (!path[0])
639 continue;
640
641 if ((pathspec.items[i].magic & (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
642 !file_exists(path)) {
108da0db 643 if (ignore_missing) {
0188f6b3 644 int dtype = DT_UNKNOWN;
a0bba65b 645 if (is_excluded(&dir, &the_index, path, &dtype))
9e58beca
BW
646 dir_add_ignored(&dir, &the_index,
647 path, pathspec.items[i].len);
108da0db 648 } else
48168851 649 die(_("pathspec '%s' did not match any files"),
84b8b5d1 650 pathspec.items[i].original);
108da0db 651 }
81f45e7d 652 }
a20f7047
MT
653
654
655 if (only_match_skip_worktree.nr) {
656 advise_on_updating_sparse_paths(&only_match_skip_worktree);
657 exit_status = 1;
658 }
659
81f45e7d 660 free(seen);
a20f7047
MT
661 free(skip_worktree_seen);
662 string_list_clear(&only_match_skip_worktree, 0);
81f45e7d
JH
663 }
664
568508e7
JH
665 plug_bulk_checkin();
666
9472935d
TB
667 if (add_renormalize)
668 exit_status |= renormalize_tracked_files(&pathspec, flags);
669 else
670 exit_status |= add_files_to_cache(prefix, &pathspec, flags);
c972ec04
JH
671
672 if (add_new_files)
610d55af 673 exit_status |= add_files(&dir, flags);
0d781539 674
610d55af 675 if (chmod_arg && pathspec.nr)
9ebd7fe1 676 exit_status |= chmod_pathspec(&pathspec, chmod_arg[0], show_only);
568508e7
JH
677 unplug_bulk_checkin();
678
d521abf8 679finish:
61000814
680 if (write_locked_index(&the_index, &lock_file,
681 COMMIT_LOCK | SKIP_IF_UNCHANGED))
682 die(_("Unable to write new index file"));
0d781539 683
eceba532 684 dir_clear(&dir);
0e5bba53 685 UNLEAK(pathspec);
7ae02a30 686 return exit_status;
0d781539 687}