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