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