add -u: only show pathless 'add -u' warning when changes exist outside cwd
[git] / builtin / add.c
1 /*
2  * "git add" builtin command
3  *
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"
18
19 static const char * const builtin_add_usage[] = {
20         N_("git add [options] [--] <pathspec>..."),
21         NULL
22 };
23 static int patch_interactive, add_interactive, edit_interactive;
24 static int take_worktree_changes;
25
26 struct update_callback_data {
27         int flags;
28         int add_errors;
29         const char *implicit_dot;
30         size_t implicit_dot_len;
31 };
32
33 static const char *option_with_implicit_dot;
34 static const char *short_option_with_implicit_dot;
35
36 static void warn_pathless_add(void)
37 {
38         static int shown;
39         assert(option_with_implicit_dot && short_option_with_implicit_dot);
40
41         if (shown)
42                 return;
43         shown = 1;
44
45         /*
46          * To be consistent with "git add -p" and most Git
47          * commands, we should default to being tree-wide, but
48          * this is not the original behavior and can't be
49          * changed until users trained themselves not to type
50          * "git add -u" or "git add -A". For now, we warn and
51          * keep the old behavior. Later, the behavior can be changed
52          * to tree-wide, keeping the warning for a while, and
53          * eventually we can drop the warning.
54          */
55         warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
56                   "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
57                   "To add content for the whole tree, run:\n"
58                   "\n"
59                   "  git add %s :/\n"
60                   "  (or git add %s :/)\n"
61                   "\n"
62                   "To restrict the command to the current directory, run:\n"
63                   "\n"
64                   "  git add %s .\n"
65                   "  (or git add %s .)\n"
66                   "\n"
67                   "With the current Git version, the command is restricted to "
68                   "the current directory.\n"
69                   ""),
70                 option_with_implicit_dot, short_option_with_implicit_dot,
71                 option_with_implicit_dot, short_option_with_implicit_dot,
72                 option_with_implicit_dot, short_option_with_implicit_dot);
73 }
74
75 static int fix_unmerged_status(struct diff_filepair *p,
76                                struct update_callback_data *data)
77 {
78         if (p->status != DIFF_STATUS_UNMERGED)
79                 return p->status;
80         if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
81                 /*
82                  * This is not an explicit add request, and the
83                  * path is missing from the working tree (deleted)
84                  */
85                 return DIFF_STATUS_DELETED;
86         else
87                 /*
88                  * Either an explicit add request, or path exists
89                  * in the working tree.  An attempt to explicitly
90                  * add a path that does not exist in the working tree
91                  * will be caught as an error by the caller immediately.
92                  */
93                 return DIFF_STATUS_MODIFIED;
94 }
95
96 static void update_callback(struct diff_queue_struct *q,
97                             struct diff_options *opt, void *cbdata)
98 {
99         int i;
100         struct update_callback_data *data = cbdata;
101         const char *implicit_dot = data->implicit_dot;
102         size_t implicit_dot_len = data->implicit_dot_len;
103
104         for (i = 0; i < q->nr; i++) {
105                 struct diff_filepair *p = q->queue[i];
106                 const char *path = p->one->path;
107                 /*
108                  * Check if "git add -A" or "git add -u" was run from a
109                  * subdirectory with a modified file outside that directory,
110                  * and warn if so.
111                  *
112                  * "git add -u" will behave like "git add -u :/" instead of
113                  * "git add -u ." in the future.  This warning prepares for
114                  * that change.
115                  */
116                 if (implicit_dot &&
117                     strncmp_icase(path, implicit_dot, implicit_dot_len)) {
118                         warn_pathless_add();
119                         continue;
120                 }
121                 switch (fix_unmerged_status(p, data)) {
122                 default:
123                         die(_("unexpected diff status %c"), p->status);
124                 case DIFF_STATUS_MODIFIED:
125                 case DIFF_STATUS_TYPE_CHANGED:
126                         if (add_file_to_index(&the_index, path, data->flags)) {
127                                 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
128                                         die(_("updating files failed"));
129                                 data->add_errors++;
130                         }
131                         break;
132                 case DIFF_STATUS_DELETED:
133                         if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
134                                 break;
135                         if (!(data->flags & ADD_CACHE_PRETEND))
136                                 remove_file_from_index(&the_index, path);
137                         if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
138                                 printf(_("remove '%s'\n"), path);
139                         break;
140                 }
141         }
142 }
143
144 int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
145 {
146         struct update_callback_data data;
147         struct rev_info rev;
148
149         memset(&data, 0, sizeof(data));
150         data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
151         if ((flags & ADD_CACHE_IMPLICIT_DOT) && prefix) {
152                 /*
153                  * Check for modified files throughout the worktree so
154                  * update_callback has a chance to warn about changes
155                  * outside the cwd.
156                  */
157                 data.implicit_dot = prefix;
158                 data.implicit_dot_len = strlen(prefix);
159                 pathspec = NULL;
160         }
161
162         init_revisions(&rev, prefix);
163         setup_revisions(0, NULL, &rev, NULL);
164         init_pathspec(&rev.prune_data, pathspec);
165         rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
166         rev.diffopt.format_callback = update_callback;
167         rev.diffopt.format_callback_data = &data;
168         rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
169         run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
170         return !!data.add_errors;
171 }
172
173 static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
174 {
175         char *seen;
176         int i, specs;
177         struct dir_entry **src, **dst;
178
179         for (specs = 0; pathspec[specs];  specs++)
180                 /* nothing */;
181         seen = xcalloc(specs, 1);
182
183         src = dst = dir->entries;
184         i = dir->nr;
185         while (--i >= 0) {
186                 struct dir_entry *entry = *src++;
187                 if (match_pathspec(pathspec, entry->name, entry->len,
188                                    prefix, seen))
189                         *dst++ = entry;
190         }
191         dir->nr = dst - dir->entries;
192         add_pathspec_matches_against_index(pathspec, seen, specs);
193         return seen;
194 }
195
196 /*
197  * Checks the index to see whether any path in pathspec refers to
198  * something inside a submodule.  If so, dies with an error message.
199  */
200 static void treat_gitlinks(const char **pathspec)
201 {
202         int i;
203
204         if (!pathspec || !*pathspec)
205                 return;
206
207         for (i = 0; pathspec[i]; i++)
208                 pathspec[i] = check_path_for_gitlink(pathspec[i]);
209 }
210
211 static void refresh(int verbose, const char **pathspec)
212 {
213         char *seen;
214         int i, specs;
215
216         for (specs = 0; pathspec[specs];  specs++)
217                 /* nothing */;
218         seen = xcalloc(specs, 1);
219         refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
220                       pathspec, seen, _("Unstaged changes after refreshing the index:"));
221         for (i = 0; i < specs; i++) {
222                 if (!seen[i])
223                         die(_("pathspec '%s' did not match any files"), pathspec[i]);
224         }
225         free(seen);
226 }
227
228 /*
229  * Normalizes argv relative to prefix, via get_pathspec(), and then
230  * runs die_if_path_beyond_symlink() on each path in the normalized
231  * list.
232  */
233 static const char **validate_pathspec(const char **argv, const char *prefix)
234 {
235         const char **pathspec = get_pathspec(prefix, argv);
236
237         if (pathspec) {
238                 const char **p;
239                 for (p = pathspec; *p; p++) {
240                         die_if_path_beyond_symlink(*p, prefix);
241                 }
242         }
243
244         return pathspec;
245 }
246
247 int run_add_interactive(const char *revision, const char *patch_mode,
248                         const char **pathspec)
249 {
250         int status, ac, pc = 0;
251         const char **args;
252
253         if (pathspec)
254                 while (pathspec[pc])
255                         pc++;
256
257         args = xcalloc(sizeof(const char *), (pc + 5));
258         ac = 0;
259         args[ac++] = "add--interactive";
260         if (patch_mode)
261                 args[ac++] = patch_mode;
262         if (revision)
263                 args[ac++] = revision;
264         args[ac++] = "--";
265         if (pc) {
266                 memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
267                 ac += pc;
268         }
269         args[ac] = NULL;
270
271         status = run_command_v_opt(args, RUN_GIT_CMD);
272         free(args);
273         return status;
274 }
275
276 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
277 {
278         const char **pathspec = NULL;
279
280         if (argc) {
281                 pathspec = validate_pathspec(argv, prefix);
282                 if (!pathspec)
283                         return -1;
284         }
285
286         return run_add_interactive(NULL,
287                                    patch ? "--patch" : NULL,
288                                    pathspec);
289 }
290
291 static int edit_patch(int argc, const char **argv, const char *prefix)
292 {
293         char *file = git_pathdup("ADD_EDIT.patch");
294         const char *apply_argv[] = { "apply", "--recount", "--cached",
295                 NULL, NULL };
296         struct child_process child;
297         struct rev_info rev;
298         int out;
299         struct stat st;
300
301         apply_argv[3] = file;
302
303         git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
304
305         if (read_cache() < 0)
306                 die (_("Could not read the index"));
307
308         init_revisions(&rev, prefix);
309         rev.diffopt.context = 7;
310
311         argc = setup_revisions(argc, argv, &rev, NULL);
312         rev.diffopt.output_format = DIFF_FORMAT_PATCH;
313         DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
314         out = open(file, O_CREAT | O_WRONLY, 0666);
315         if (out < 0)
316                 die (_("Could not open '%s' for writing."), file);
317         rev.diffopt.file = xfdopen(out, "w");
318         rev.diffopt.close_file = 1;
319         if (run_diff_files(&rev, 0))
320                 die (_("Could not write patch"));
321
322         launch_editor(file, NULL, NULL);
323
324         if (stat(file, &st))
325                 die_errno(_("Could not stat '%s'"), file);
326         if (!st.st_size)
327                 die(_("Empty patch. Aborted."));
328
329         memset(&child, 0, sizeof(child));
330         child.git_cmd = 1;
331         child.argv = apply_argv;
332         if (run_command(&child))
333                 die (_("Could not apply '%s'"), file);
334
335         unlink(file);
336         free(file);
337         return 0;
338 }
339
340 static struct lock_file lock_file;
341
342 static const char ignore_error[] =
343 N_("The following paths are ignored by one of your .gitignore files:\n");
344
345 static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
346 static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
347
348 static struct option builtin_add_options[] = {
349         OPT__DRY_RUN(&show_only, N_("dry run")),
350         OPT__VERBOSE(&verbose, N_("be verbose")),
351         OPT_GROUP(""),
352         OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
353         OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
354         OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
355         OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
356         OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
357         OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
358         OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
359         OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
360         OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
361         OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
362         OPT_END(),
363 };
364
365 static int add_config(const char *var, const char *value, void *cb)
366 {
367         if (!strcmp(var, "add.ignoreerrors") ||
368             !strcmp(var, "add.ignore-errors")) {
369                 ignore_add_errors = git_config_bool(var, value);
370                 return 0;
371         }
372         return git_default_config(var, value, cb);
373 }
374
375 static int add_files(struct dir_struct *dir, int flags)
376 {
377         int i, exit_status = 0;
378
379         if (dir->ignored_nr) {
380                 fprintf(stderr, _(ignore_error));
381                 for (i = 0; i < dir->ignored_nr; i++)
382                         fprintf(stderr, "%s\n", dir->ignored[i]->name);
383                 fprintf(stderr, _("Use -f if you really want to add them.\n"));
384                 die(_("no files added"));
385         }
386
387         for (i = 0; i < dir->nr; i++)
388                 if (add_file_to_cache(dir->entries[i]->name, flags)) {
389                         if (!ignore_add_errors)
390                                 die(_("adding files failed"));
391                         exit_status = 1;
392                 }
393         return exit_status;
394 }
395
396 int cmd_add(int argc, const char **argv, const char *prefix)
397 {
398         int exit_status = 0;
399         int newfd;
400         const char **pathspec;
401         struct dir_struct dir;
402         int flags;
403         int add_new_files;
404         int require_pathspec;
405         char *seen = NULL;
406         int implicit_dot = 0;
407
408         git_config(add_config, NULL);
409
410         argc = parse_options(argc, argv, prefix, builtin_add_options,
411                           builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
412         if (patch_interactive)
413                 add_interactive = 1;
414         if (add_interactive)
415                 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
416
417         if (edit_interactive)
418                 return(edit_patch(argc, argv, prefix));
419         argc--;
420         argv++;
421
422         if (addremove && take_worktree_changes)
423                 die(_("-A and -u are mutually incompatible"));
424         if (!show_only && ignore_missing)
425                 die(_("Option --ignore-missing can only be used together with --dry-run"));
426         if (addremove) {
427                 option_with_implicit_dot = "--all";
428                 short_option_with_implicit_dot = "-A";
429         }
430         if (take_worktree_changes) {
431                 option_with_implicit_dot = "--update";
432                 short_option_with_implicit_dot = "-u";
433         }
434         if (option_with_implicit_dot && !argc) {
435                 static const char *here[2] = { ".", NULL };
436                 if (prefix && addremove)
437                         warn_pathless_add();
438                 argc = 1;
439                 argv = here;
440                 implicit_dot = 1;
441         }
442
443         add_new_files = !take_worktree_changes && !refresh_only;
444         require_pathspec = !take_worktree_changes;
445
446         newfd = hold_locked_index(&lock_file, 1);
447
448         flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
449                  (show_only ? ADD_CACHE_PRETEND : 0) |
450                  (intent_to_add ? ADD_CACHE_INTENT : 0) |
451                  (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
452                  (!(addremove || take_worktree_changes)
453                   ? ADD_CACHE_IGNORE_REMOVAL : 0)) |
454                  (implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0);
455
456         if (require_pathspec && argc == 0) {
457                 fprintf(stderr, _("Nothing specified, nothing added.\n"));
458                 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
459                 return 0;
460         }
461         pathspec = validate_pathspec(argv, prefix);
462
463         if (read_cache() < 0)
464                 die(_("index file corrupt"));
465         treat_gitlinks(pathspec);
466
467         if (add_new_files) {
468                 int baselen;
469
470                 /* Set up the default git porcelain excludes */
471                 memset(&dir, 0, sizeof(dir));
472                 if (!ignored_too) {
473                         dir.flags |= DIR_COLLECT_IGNORED;
474                         setup_standard_excludes(&dir);
475                 }
476
477                 /* This picks up the paths that are not tracked */
478                 baselen = fill_directory(&dir, pathspec);
479                 if (pathspec)
480                         seen = prune_directory(&dir, pathspec, baselen);
481         }
482
483         if (refresh_only) {
484                 refresh(verbose, pathspec);
485                 goto finish;
486         }
487
488         if (pathspec) {
489                 int i;
490                 struct path_exclude_check check;
491
492                 path_exclude_check_init(&check, &dir);
493                 if (!seen)
494                         seen = find_pathspecs_matching_against_index(pathspec);
495                 for (i = 0; pathspec[i]; i++) {
496                         if (!seen[i] && pathspec[i][0]
497                             && !file_exists(pathspec[i])) {
498                                 if (ignore_missing) {
499                                         int dtype = DT_UNKNOWN;
500                                         if (is_path_excluded(&check, pathspec[i], -1, &dtype))
501                                                 dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
502                                 } else
503                                         die(_("pathspec '%s' did not match any files"),
504                                             pathspec[i]);
505                         }
506                 }
507                 free(seen);
508                 path_exclude_check_clear(&check);
509         }
510
511         plug_bulk_checkin();
512
513         exit_status |= add_files_to_cache(prefix, pathspec, flags);
514
515         if (add_new_files)
516                 exit_status |= add_files(&dir, flags);
517
518         unplug_bulk_checkin();
519
520  finish:
521         if (active_cache_changed) {
522                 if (write_cache(newfd, active_cache, active_nr) ||
523                     commit_locked_index(&lock_file))
524                         die(_("Unable to write new index file"));
525         }
526
527         return exit_status;
528 }