git add: rephrase the "removal will cease to be ignored" warning
[git.git] / builtin / add.c
blob20f459a0a389f8c265212295445d093555b7b13a
1 /*
2 * "git add" builtin command
4 * Copyright (C) 2006 Linus Torvalds
5 */
6 #include "cache.h"
7 #include "builtin.h"
8 #include "dir.h"
9 #include "pathspec.h"
10 #include "exec_cmd.h"
11 #include "cache-tree.h"
12 #include "run-command.h"
13 #include "parse-options.h"
14 #include "diff.h"
15 #include "diffcore.h"
16 #include "revision.h"
17 #include "bulk-checkin.h"
19 static const char * const builtin_add_usage[] = {
20 N_("git add [options] [--] <pathspec>..."),
21 NULL
23 static int patch_interactive, add_interactive, edit_interactive;
24 static int take_worktree_changes;
26 struct update_callback_data {
27 int flags;
28 int add_errors;
30 /* only needed for 2.0 transition preparation */
31 int warn_add_would_remove;
34 static int fix_unmerged_status(struct diff_filepair *p,
35 struct update_callback_data *data)
37 if (p->status != DIFF_STATUS_UNMERGED)
38 return p->status;
39 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
41 * This is not an explicit add request, and the
42 * path is missing from the working tree (deleted)
44 return DIFF_STATUS_DELETED;
45 else
47 * Either an explicit add request, or path exists
48 * in the working tree. An attempt to explicitly
49 * add a path that does not exist in the working tree
50 * will be caught as an error by the caller immediately.
52 return DIFF_STATUS_MODIFIED;
55 static const char *add_would_remove_warning = N_(
56 "You ran 'git add' with neither '-A (--all)' or '--no-all', whose\n"
57 "behaviour will change in Git 2.0 with respect to paths you removed from\n"
58 "your working tree. Paths like '%s' that are\n"
59 "removed are ignored with this version of Git.\n"
60 "\n"
61 "* 'git add --no-all <pathspec>', which is the current default, ignores\n"
62 " paths you removed from your working tree.\n"
63 "\n"
64 "* 'git add --all <pathspec>' will let you also record the removals.\n"
65 "\n"
66 "Run 'git status' to check the paths you removed from your working tree.\n");
68 static void warn_add_would_remove(const char *path)
70 warning(_(add_would_remove_warning), path);
73 static void update_callback(struct diff_queue_struct *q,
74 struct diff_options *opt, void *cbdata)
76 int i;
77 struct update_callback_data *data = cbdata;
79 for (i = 0; i < q->nr; i++) {
80 struct diff_filepair *p = q->queue[i];
81 const char *path = p->one->path;
82 switch (fix_unmerged_status(p, data)) {
83 default:
84 die(_("unexpected diff status %c"), p->status);
85 case DIFF_STATUS_MODIFIED:
86 case DIFF_STATUS_TYPE_CHANGED:
87 if (add_file_to_index(&the_index, path, data->flags)) {
88 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
89 die(_("updating files failed"));
90 data->add_errors++;
92 break;
93 case DIFF_STATUS_DELETED:
94 if (data->warn_add_would_remove) {
95 warn_add_would_remove(path);
96 data->warn_add_would_remove = 0;
98 if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
99 break;
100 if (!(data->flags & ADD_CACHE_PRETEND))
101 remove_file_from_index(&the_index, path);
102 if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
103 printf(_("remove '%s'\n"), path);
104 break;
109 static void update_files_in_cache(const char *prefix, const char **pathspec,
110 struct update_callback_data *data)
112 struct rev_info rev;
113 init_revisions(&rev, prefix);
114 setup_revisions(0, NULL, &rev, NULL);
115 init_pathspec(&rev.prune_data, pathspec);
116 rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
117 rev.diffopt.format_callback = update_callback;
118 rev.diffopt.format_callback_data = data;
119 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
120 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
123 int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
125 struct update_callback_data data;
127 memset(&data, 0, sizeof(data));
128 data.flags = flags;
129 update_files_in_cache(prefix, pathspec, &data);
130 return !!data.add_errors;
133 static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
135 char *seen;
136 int i, specs;
137 struct dir_entry **src, **dst;
139 for (specs = 0; pathspec[specs]; specs++)
140 /* nothing */;
141 seen = xcalloc(specs, 1);
143 src = dst = dir->entries;
144 i = dir->nr;
145 while (--i >= 0) {
146 struct dir_entry *entry = *src++;
147 if (match_pathspec(pathspec, entry->name, entry->len,
148 prefix, seen))
149 *dst++ = entry;
151 dir->nr = dst - dir->entries;
152 add_pathspec_matches_against_index(pathspec, seen, specs);
153 return seen;
157 * Checks the index to see whether any path in pathspec refers to
158 * something inside a submodule. If so, dies with an error message.
160 static void treat_gitlinks(const char **pathspec)
162 int i;
164 if (!pathspec || !*pathspec)
165 return;
167 for (i = 0; pathspec[i]; i++)
168 pathspec[i] = check_path_for_gitlink(pathspec[i]);
171 static void refresh(int verbose, const char **pathspec)
173 char *seen;
174 int i, specs;
176 for (specs = 0; pathspec[specs]; specs++)
177 /* nothing */;
178 seen = xcalloc(specs, 1);
179 refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
180 pathspec, seen, _("Unstaged changes after refreshing the index:"));
181 for (i = 0; i < specs; i++) {
182 if (!seen[i])
183 die(_("pathspec '%s' did not match any files"), pathspec[i]);
185 free(seen);
189 * Normalizes argv relative to prefix, via get_pathspec(), and then
190 * runs die_if_path_beyond_symlink() on each path in the normalized
191 * list.
193 static const char **validate_pathspec(const char **argv, const char *prefix)
195 const char **pathspec = get_pathspec(prefix, argv);
197 if (pathspec) {
198 const char **p;
199 for (p = pathspec; *p; p++) {
200 die_if_path_beyond_symlink(*p, prefix);
204 return pathspec;
207 int run_add_interactive(const char *revision, const char *patch_mode,
208 const char **pathspec)
210 int status, ac, pc = 0;
211 const char **args;
213 if (pathspec)
214 while (pathspec[pc])
215 pc++;
217 args = xcalloc(sizeof(const char *), (pc + 5));
218 ac = 0;
219 args[ac++] = "add--interactive";
220 if (patch_mode)
221 args[ac++] = patch_mode;
222 if (revision)
223 args[ac++] = revision;
224 args[ac++] = "--";
225 if (pc) {
226 memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
227 ac += pc;
229 args[ac] = NULL;
231 status = run_command_v_opt(args, RUN_GIT_CMD);
232 free(args);
233 return status;
236 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
238 const char **pathspec = NULL;
240 if (argc) {
241 pathspec = validate_pathspec(argv, prefix);
242 if (!pathspec)
243 return -1;
246 return run_add_interactive(NULL,
247 patch ? "--patch" : NULL,
248 pathspec);
251 static int edit_patch(int argc, const char **argv, const char *prefix)
253 char *file = git_pathdup("ADD_EDIT.patch");
254 const char *apply_argv[] = { "apply", "--recount", "--cached",
255 NULL, NULL };
256 struct child_process child;
257 struct rev_info rev;
258 int out;
259 struct stat st;
261 apply_argv[3] = file;
263 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
265 if (read_cache() < 0)
266 die (_("Could not read the index"));
268 init_revisions(&rev, prefix);
269 rev.diffopt.context = 7;
271 argc = setup_revisions(argc, argv, &rev, NULL);
272 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
273 DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
274 out = open(file, O_CREAT | O_WRONLY, 0666);
275 if (out < 0)
276 die (_("Could not open '%s' for writing."), file);
277 rev.diffopt.file = xfdopen(out, "w");
278 rev.diffopt.close_file = 1;
279 if (run_diff_files(&rev, 0))
280 die (_("Could not write patch"));
282 launch_editor(file, NULL, NULL);
284 if (stat(file, &st))
285 die_errno(_("Could not stat '%s'"), file);
286 if (!st.st_size)
287 die(_("Empty patch. Aborted."));
289 memset(&child, 0, sizeof(child));
290 child.git_cmd = 1;
291 child.argv = apply_argv;
292 if (run_command(&child))
293 die (_("Could not apply '%s'"), file);
295 unlink(file);
296 free(file);
297 return 0;
300 static struct lock_file lock_file;
302 static const char ignore_error[] =
303 N_("The following paths are ignored by one of your .gitignore files:\n");
305 static int verbose, show_only, ignored_too, refresh_only;
306 static int ignore_add_errors, intent_to_add, ignore_missing;
308 #define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
309 static int addremove = ADDREMOVE_DEFAULT;
310 static int addremove_explicit = -1; /* unspecified */
312 static struct option builtin_add_options[] = {
313 OPT__DRY_RUN(&show_only, N_("dry run")),
314 OPT__VERBOSE(&verbose, N_("be verbose")),
315 OPT_GROUP(""),
316 OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
317 OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
318 OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
319 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
320 OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
321 OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
322 OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
323 OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
324 OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
325 OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
326 OPT_END(),
329 static int add_config(const char *var, const char *value, void *cb)
331 if (!strcmp(var, "add.ignoreerrors") ||
332 !strcmp(var, "add.ignore-errors")) {
333 ignore_add_errors = git_config_bool(var, value);
334 return 0;
336 return git_default_config(var, value, cb);
339 static int add_files(struct dir_struct *dir, int flags)
341 int i, exit_status = 0;
343 if (dir->ignored_nr) {
344 fprintf(stderr, _(ignore_error));
345 for (i = 0; i < dir->ignored_nr; i++)
346 fprintf(stderr, "%s\n", dir->ignored[i]->name);
347 fprintf(stderr, _("Use -f if you really want to add them.\n"));
348 die(_("no files added"));
351 for (i = 0; i < dir->nr; i++)
352 if (add_file_to_cache(dir->entries[i]->name, flags)) {
353 if (!ignore_add_errors)
354 die(_("adding files failed"));
355 exit_status = 1;
357 return exit_status;
360 static void warn_pathless_add(const char *option_name, const char *short_name) {
362 * To be consistent with "git add -p" and most Git
363 * commands, we should default to being tree-wide, but
364 * this is not the original behavior and can't be
365 * changed until users trained themselves not to type
366 * "git add -u" or "git add -A". For now, we warn and
367 * keep the old behavior. Later, this warning can be
368 * turned into a die(...), and eventually we may
369 * reallow the command with a new behavior.
371 warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
372 "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
373 "To add content for the whole tree, run:\n"
374 "\n"
375 " git add %s :/\n"
376 " (or git add %s :/)\n"
377 "\n"
378 "To restrict the command to the current directory, run:\n"
379 "\n"
380 " git add %s .\n"
381 " (or git add %s .)\n"
382 "\n"
383 "With the current Git version, the command is restricted to the current directory."),
384 option_name, short_name,
385 option_name, short_name,
386 option_name, short_name);
389 int cmd_add(int argc, const char **argv, const char *prefix)
391 int exit_status = 0;
392 int newfd;
393 const char **pathspec;
394 struct dir_struct dir;
395 int flags;
396 int add_new_files;
397 int require_pathspec;
398 char *seen = NULL;
399 const char *option_with_implicit_dot = NULL;
400 const char *short_option_with_implicit_dot = NULL;
401 struct update_callback_data update_data;
403 git_config(add_config, NULL);
405 argc = parse_options(argc, argv, prefix, builtin_add_options,
406 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
407 if (patch_interactive)
408 add_interactive = 1;
409 if (add_interactive)
410 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
412 if (edit_interactive)
413 return(edit_patch(argc, argv, prefix));
414 argc--;
415 argv++;
417 if (0 <= addremove_explicit)
418 addremove = addremove_explicit;
419 else if (take_worktree_changes && ADDREMOVE_DEFAULT)
420 addremove = 0; /* "-u" was given but not "-A" */
422 if (addremove && take_worktree_changes)
423 die(_("-A and -u are mutually incompatible"));
426 * Warn when "git add pathspec..." was given without "-u" or "-A"
427 * and pathspec... covers a removed path.
429 memset(&update_data, 0, sizeof(update_data));
430 if (!take_worktree_changes && addremove_explicit < 0)
431 update_data.warn_add_would_remove = 1;
433 if (!take_worktree_changes && addremove_explicit < 0 && argc)
435 * Turn "git add pathspec..." to "git add -A pathspec..."
436 * in Git 2.0 but not yet
438 ; /* addremove = 1; */
440 if (!show_only && ignore_missing)
441 die(_("Option --ignore-missing can only be used together with --dry-run"));
442 if (addremove) {
443 option_with_implicit_dot = "--all";
444 short_option_with_implicit_dot = "-A";
446 if (take_worktree_changes) {
447 option_with_implicit_dot = "--update";
448 short_option_with_implicit_dot = "-u";
450 if (option_with_implicit_dot && !argc) {
451 static const char *here[2] = { ".", NULL };
452 if (prefix)
453 warn_pathless_add(option_with_implicit_dot,
454 short_option_with_implicit_dot);
455 argc = 1;
456 argv = here;
459 add_new_files = !take_worktree_changes && !refresh_only;
460 require_pathspec = !take_worktree_changes;
462 newfd = hold_locked_index(&lock_file, 1);
464 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
465 (show_only ? ADD_CACHE_PRETEND : 0) |
466 (intent_to_add ? ADD_CACHE_INTENT : 0) |
467 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
468 (!(addremove || take_worktree_changes)
469 ? ADD_CACHE_IGNORE_REMOVAL : 0));
471 if (require_pathspec && argc == 0) {
472 fprintf(stderr, _("Nothing specified, nothing added.\n"));
473 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
474 return 0;
476 pathspec = validate_pathspec(argv, prefix);
478 if (read_cache() < 0)
479 die(_("index file corrupt"));
480 treat_gitlinks(pathspec);
482 if (add_new_files) {
483 int baselen;
485 /* Set up the default git porcelain excludes */
486 memset(&dir, 0, sizeof(dir));
487 if (!ignored_too) {
488 dir.flags |= DIR_COLLECT_IGNORED;
489 setup_standard_excludes(&dir);
492 /* This picks up the paths that are not tracked */
493 baselen = fill_directory(&dir, pathspec);
494 if (pathspec)
495 seen = prune_directory(&dir, pathspec, baselen);
498 if (refresh_only) {
499 refresh(verbose, pathspec);
500 goto finish;
503 if (pathspec) {
504 int i;
505 struct path_exclude_check check;
507 path_exclude_check_init(&check, &dir);
508 if (!seen)
509 seen = find_pathspecs_matching_against_index(pathspec);
510 for (i = 0; pathspec[i]; i++) {
511 if (!seen[i] && pathspec[i][0]
512 && !file_exists(pathspec[i])) {
513 if (ignore_missing) {
514 int dtype = DT_UNKNOWN;
515 if (is_path_excluded(&check, pathspec[i], -1, &dtype))
516 dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
517 } else
518 die(_("pathspec '%s' did not match any files"),
519 pathspec[i]);
522 free(seen);
523 path_exclude_check_clear(&check);
526 plug_bulk_checkin();
528 update_data.flags = flags;
529 update_files_in_cache(prefix, pathspec, &update_data);
531 exit_status |= !!update_data.add_errors;
532 if (add_new_files)
533 exit_status |= add_files(&dir, flags);
535 unplug_bulk_checkin();
537 finish:
538 if (active_cache_changed) {
539 if (write_cache(newfd, active_cache, active_nr) ||
540 commit_locked_index(&lock_file))
541 die(_("Unable to write new index file"));
544 return exit_status;