Merge branch 'jx/i18n-branch-error-messages'
[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 #define WARN_IMPLICIT_DOT (1u << 0)
174 static char *prune_directory(struct dir_struct *dir, const char **pathspec,
175                              int prefix, unsigned flag)
176 {
177         char *seen;
178         int i, specs;
179         struct dir_entry **src, **dst;
180
181         for (specs = 0; pathspec[specs];  specs++)
182                 /* nothing */;
183         seen = xcalloc(specs, 1);
184
185         src = dst = dir->entries;
186         i = dir->nr;
187         while (--i >= 0) {
188                 struct dir_entry *entry = *src++;
189                 if (match_pathspec(pathspec, entry->name, entry->len,
190                                    prefix, seen))
191                         *dst++ = entry;
192                 else if (flag & WARN_IMPLICIT_DOT)
193                         /*
194                          * "git add -A" was run from a subdirectory with a
195                          * new file outside that directory.
196                          *
197                          * "git add -A" will behave like "git add -A :/"
198                          * instead of "git add -A ." in the future.
199                          * Warn about the coming behavior change.
200                          */
201                         warn_pathless_add();
202         }
203         dir->nr = dst - dir->entries;
204         add_pathspec_matches_against_index(pathspec, seen, specs);
205         return seen;
206 }
207
208 /*
209  * Checks the index to see whether any path in pathspec refers to
210  * something inside a submodule.  If so, dies with an error message.
211  */
212 static void treat_gitlinks(const char **pathspec)
213 {
214         int i;
215
216         if (!pathspec || !*pathspec)
217                 return;
218
219         for (i = 0; pathspec[i]; i++)
220                 pathspec[i] = check_path_for_gitlink(pathspec[i]);
221 }
222
223 static void refresh(int verbose, const char **pathspec)
224 {
225         char *seen;
226         int i, specs;
227
228         for (specs = 0; pathspec[specs];  specs++)
229                 /* nothing */;
230         seen = xcalloc(specs, 1);
231         refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
232                       pathspec, seen, _("Unstaged changes after refreshing the index:"));
233         for (i = 0; i < specs; i++) {
234                 if (!seen[i])
235                         die(_("pathspec '%s' did not match any files"), pathspec[i]);
236         }
237         free(seen);
238 }
239
240 /*
241  * Normalizes argv relative to prefix, via get_pathspec(), and then
242  * runs die_if_path_beyond_symlink() on each path in the normalized
243  * list.
244  */
245 static const char **validate_pathspec(const char **argv, const char *prefix)
246 {
247         const char **pathspec = get_pathspec(prefix, argv);
248
249         if (pathspec) {
250                 const char **p;
251                 for (p = pathspec; *p; p++) {
252                         die_if_path_beyond_symlink(*p, prefix);
253                 }
254         }
255
256         return pathspec;
257 }
258
259 int run_add_interactive(const char *revision, const char *patch_mode,
260                         const char **pathspec)
261 {
262         int status, ac, pc = 0;
263         const char **args;
264
265         if (pathspec)
266                 while (pathspec[pc])
267                         pc++;
268
269         args = xcalloc(sizeof(const char *), (pc + 5));
270         ac = 0;
271         args[ac++] = "add--interactive";
272         if (patch_mode)
273                 args[ac++] = patch_mode;
274         if (revision)
275                 args[ac++] = revision;
276         args[ac++] = "--";
277         if (pc) {
278                 memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
279                 ac += pc;
280         }
281         args[ac] = NULL;
282
283         status = run_command_v_opt(args, RUN_GIT_CMD);
284         free(args);
285         return status;
286 }
287
288 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
289 {
290         const char **pathspec = NULL;
291
292         if (argc) {
293                 pathspec = validate_pathspec(argv, prefix);
294                 if (!pathspec)
295                         return -1;
296         }
297
298         return run_add_interactive(NULL,
299                                    patch ? "--patch" : NULL,
300                                    pathspec);
301 }
302
303 static int edit_patch(int argc, const char **argv, const char *prefix)
304 {
305         char *file = git_pathdup("ADD_EDIT.patch");
306         const char *apply_argv[] = { "apply", "--recount", "--cached",
307                 NULL, NULL };
308         struct child_process child;
309         struct rev_info rev;
310         int out;
311         struct stat st;
312
313         apply_argv[3] = file;
314
315         git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
316
317         if (read_cache() < 0)
318                 die (_("Could not read the index"));
319
320         init_revisions(&rev, prefix);
321         rev.diffopt.context = 7;
322
323         argc = setup_revisions(argc, argv, &rev, NULL);
324         rev.diffopt.output_format = DIFF_FORMAT_PATCH;
325         DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
326         out = open(file, O_CREAT | O_WRONLY, 0666);
327         if (out < 0)
328                 die (_("Could not open '%s' for writing."), file);
329         rev.diffopt.file = xfdopen(out, "w");
330         rev.diffopt.close_file = 1;
331         if (run_diff_files(&rev, 0))
332                 die (_("Could not write patch"));
333
334         launch_editor(file, NULL, NULL);
335
336         if (stat(file, &st))
337                 die_errno(_("Could not stat '%s'"), file);
338         if (!st.st_size)
339                 die(_("Empty patch. Aborted."));
340
341         memset(&child, 0, sizeof(child));
342         child.git_cmd = 1;
343         child.argv = apply_argv;
344         if (run_command(&child))
345                 die (_("Could not apply '%s'"), file);
346
347         unlink(file);
348         free(file);
349         return 0;
350 }
351
352 static struct lock_file lock_file;
353
354 static const char ignore_error[] =
355 N_("The following paths are ignored by one of your .gitignore files:\n");
356
357 static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
358 static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
359
360 static struct option builtin_add_options[] = {
361         OPT__DRY_RUN(&show_only, N_("dry run")),
362         OPT__VERBOSE(&verbose, N_("be verbose")),
363         OPT_GROUP(""),
364         OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
365         OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
366         OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
367         OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
368         OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
369         OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
370         OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
371         OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
372         OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
373         OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
374         OPT_END(),
375 };
376
377 static int add_config(const char *var, const char *value, void *cb)
378 {
379         if (!strcmp(var, "add.ignoreerrors") ||
380             !strcmp(var, "add.ignore-errors")) {
381                 ignore_add_errors = git_config_bool(var, value);
382                 return 0;
383         }
384         return git_default_config(var, value, cb);
385 }
386
387 static int add_files(struct dir_struct *dir, int flags)
388 {
389         int i, exit_status = 0;
390
391         if (dir->ignored_nr) {
392                 fprintf(stderr, _(ignore_error));
393                 for (i = 0; i < dir->ignored_nr; i++)
394                         fprintf(stderr, "%s\n", dir->ignored[i]->name);
395                 fprintf(stderr, _("Use -f if you really want to add them.\n"));
396                 die(_("no files added"));
397         }
398
399         for (i = 0; i < dir->nr; i++)
400                 if (add_file_to_cache(dir->entries[i]->name, flags)) {
401                         if (!ignore_add_errors)
402                                 die(_("adding files failed"));
403                         exit_status = 1;
404                 }
405         return exit_status;
406 }
407
408 int cmd_add(int argc, const char **argv, const char *prefix)
409 {
410         int exit_status = 0;
411         int newfd;
412         const char **pathspec;
413         struct dir_struct dir;
414         int flags;
415         int add_new_files;
416         int require_pathspec;
417         char *seen = NULL;
418         int implicit_dot = 0;
419
420         git_config(add_config, NULL);
421
422         argc = parse_options(argc, argv, prefix, builtin_add_options,
423                           builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
424         if (patch_interactive)
425                 add_interactive = 1;
426         if (add_interactive)
427                 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
428
429         if (edit_interactive)
430                 return(edit_patch(argc, argv, prefix));
431         argc--;
432         argv++;
433
434         if (addremove && take_worktree_changes)
435                 die(_("-A and -u are mutually incompatible"));
436         if (!show_only && ignore_missing)
437                 die(_("Option --ignore-missing can only be used together with --dry-run"));
438         if (addremove) {
439                 option_with_implicit_dot = "--all";
440                 short_option_with_implicit_dot = "-A";
441         }
442         if (take_worktree_changes) {
443                 option_with_implicit_dot = "--update";
444                 short_option_with_implicit_dot = "-u";
445         }
446         if (option_with_implicit_dot && !argc) {
447                 static const char *here[2] = { ".", NULL };
448                 argc = 1;
449                 argv = here;
450                 implicit_dot = 1;
451         }
452
453         add_new_files = !take_worktree_changes && !refresh_only;
454         require_pathspec = !take_worktree_changes;
455
456         newfd = hold_locked_index(&lock_file, 1);
457
458         flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
459                  (show_only ? ADD_CACHE_PRETEND : 0) |
460                  (intent_to_add ? ADD_CACHE_INTENT : 0) |
461                  (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
462                  (!(addremove || take_worktree_changes)
463                   ? ADD_CACHE_IGNORE_REMOVAL : 0)) |
464                  (implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0);
465
466         if (require_pathspec && argc == 0) {
467                 fprintf(stderr, _("Nothing specified, nothing added.\n"));
468                 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
469                 return 0;
470         }
471         pathspec = validate_pathspec(argv, prefix);
472
473         if (read_cache() < 0)
474                 die(_("index file corrupt"));
475         treat_gitlinks(pathspec);
476
477         if (add_new_files) {
478                 int baselen;
479
480                 /* Set up the default git porcelain excludes */
481                 memset(&dir, 0, sizeof(dir));
482                 if (!ignored_too) {
483                         dir.flags |= DIR_COLLECT_IGNORED;
484                         setup_standard_excludes(&dir);
485                 }
486
487                 /* This picks up the paths that are not tracked */
488                 baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec);
489                 if (pathspec)
490                         seen = prune_directory(&dir, pathspec, baselen,
491                                         implicit_dot ? WARN_IMPLICIT_DOT : 0);
492         }
493
494         if (refresh_only) {
495                 refresh(verbose, pathspec);
496                 goto finish;
497         }
498
499         if (pathspec) {
500                 int i;
501                 struct path_exclude_check check;
502
503                 path_exclude_check_init(&check, &dir);
504                 if (!seen)
505                         seen = find_pathspecs_matching_against_index(pathspec);
506                 for (i = 0; pathspec[i]; i++) {
507                         if (!seen[i] && pathspec[i][0]
508                             && !file_exists(pathspec[i])) {
509                                 if (ignore_missing) {
510                                         int dtype = DT_UNKNOWN;
511                                         if (is_path_excluded(&check, pathspec[i], -1, &dtype))
512                                                 dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
513                                 } else
514                                         die(_("pathspec '%s' did not match any files"),
515                                             pathspec[i]);
516                         }
517                 }
518                 free(seen);
519                 path_exclude_check_clear(&check);
520         }
521
522         plug_bulk_checkin();
523
524         exit_status |= add_files_to_cache(prefix, pathspec, flags);
525
526         if (add_new_files)
527                 exit_status |= add_files(&dir, flags);
528
529         unplug_bulk_checkin();
530
531  finish:
532         if (active_cache_changed) {
533                 if (write_cache(newfd, active_cache, active_nr) ||
534                     commit_locked_index(&lock_file))
535                         die(_("Unable to write new index file"));
536         }
537
538         return exit_status;
539 }