Merge branch 'ao/check-resolve-ref-unsafe-result' into maint
[git] / builtin / add.c
1 /*
2  * "git add" builtin command
3  *
4  * Copyright (C) 2006 Linus Torvalds
5  */
6 #include "cache.h"
7 #include "config.h"
8 #include "builtin.h"
9 #include "lockfile.h"
10 #include "dir.h"
11 #include "pathspec.h"
12 #include "exec_cmd.h"
13 #include "cache-tree.h"
14 #include "run-command.h"
15 #include "parse-options.h"
16 #include "diff.h"
17 #include "diffcore.h"
18 #include "revision.h"
19 #include "bulk-checkin.h"
20 #include "argv-array.h"
21 #include "submodule.h"
22
23 static const char * const builtin_add_usage[] = {
24         N_("git add [<options>] [--] <pathspec>..."),
25         NULL
26 };
27 static int patch_interactive, add_interactive, edit_interactive;
28 static int take_worktree_changes;
29
30 struct update_callback_data {
31         int flags;
32         int add_errors;
33 };
34
35 static void chmod_pathspec(struct pathspec *pathspec, char flip)
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
45                 if (chmod_cache_entry(ce, flip) < 0)
46                         fprintf(stderr, "cannot chmod %cx '%s'\n", flip, ce->name);
47         }
48 }
49
50 static 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
71 static 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;
80                 switch (fix_unmerged_status(p, data)) {
81                 default:
82                         die(_("unexpected diff status %c"), p->status);
83                 case DIFF_STATUS_MODIFIED:
84                 case DIFF_STATUS_TYPE_CHANGED:
85                         if (add_file_to_index(&the_index, path, data->flags)) {
86                                 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
87                                         die(_("updating files failed"));
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))
97                                 printf(_("remove '%s'\n"), path);
98                         break;
99                 }
100         }
101 }
102
103 int add_files_to_cache(const char *prefix,
104                        const struct pathspec *pathspec, int flags)
105 {
106         struct update_callback_data data;
107         struct rev_info rev;
108
109         memset(&data, 0, sizeof(data));
110         data.flags = flags;
111
112         init_revisions(&rev, prefix);
113         setup_revisions(0, NULL, &rev, NULL);
114         if (pathspec)
115                 copy_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.diffopt.flags |= DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
120         rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
121         run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
122         clear_pathspec(&rev.prune_data);
123         return !!data.add_errors;
124 }
125
126 static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
127 {
128         char *seen;
129         int i;
130         struct dir_entry **src, **dst;
131
132         seen = xcalloc(pathspec->nr, 1);
133
134         src = dst = dir->entries;
135         i = dir->nr;
136         while (--i >= 0) {
137                 struct dir_entry *entry = *src++;
138                 if (dir_path_match(entry, pathspec, prefix, seen))
139                         *dst++ = entry;
140         }
141         dir->nr = dst - dir->entries;
142         add_pathspec_matches_against_index(pathspec, &the_index, seen);
143         return seen;
144 }
145
146 static void refresh(int verbose, const struct pathspec *pathspec)
147 {
148         char *seen;
149         int i;
150
151         seen = xcalloc(pathspec->nr, 1);
152         refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
153                       pathspec, seen, _("Unstaged changes after refreshing the index:"));
154         for (i = 0; i < pathspec->nr; i++) {
155                 if (!seen[i])
156                         die(_("pathspec '%s' did not match any files"),
157                             pathspec->items[i].match);
158         }
159         free(seen);
160 }
161
162 int run_add_interactive(const char *revision, const char *patch_mode,
163                         const struct pathspec *pathspec)
164 {
165         int status, i;
166         struct argv_array argv = ARGV_ARRAY_INIT;
167
168         argv_array_push(&argv, "add--interactive");
169         if (patch_mode)
170                 argv_array_push(&argv, patch_mode);
171         if (revision)
172                 argv_array_push(&argv, revision);
173         argv_array_push(&argv, "--");
174         for (i = 0; i < pathspec->nr; i++)
175                 /* pass original pathspec, to be re-parsed */
176                 argv_array_push(&argv, pathspec->items[i].original);
177
178         status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
179         argv_array_clear(&argv);
180         return status;
181 }
182
183 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
184 {
185         struct pathspec pathspec;
186
187         parse_pathspec(&pathspec, 0,
188                        PATHSPEC_PREFER_FULL |
189                        PATHSPEC_SYMLINK_LEADING_PATH |
190                        PATHSPEC_PREFIX_ORIGIN,
191                        prefix, argv);
192
193         return run_add_interactive(NULL,
194                                    patch ? "--patch" : NULL,
195                                    &pathspec);
196 }
197
198 static int edit_patch(int argc, const char **argv, const char *prefix)
199 {
200         char *file = git_pathdup("ADD_EDIT.patch");
201         const char *apply_argv[] = { "apply", "--recount", "--cached",
202                 NULL, NULL };
203         struct child_process child = CHILD_PROCESS_INIT;
204         struct rev_info rev;
205         int out;
206         struct stat st;
207
208         apply_argv[3] = file;
209
210         git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
211
212         if (read_cache() < 0)
213                 die(_("Could not read the index"));
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;
220         rev.diffopt.use_color = 0;
221         DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
222         out = open(file, O_CREAT | O_WRONLY, 0666);
223         if (out < 0)
224                 die(_("Could not open '%s' for writing."), file);
225         rev.diffopt.file = xfdopen(out, "w");
226         rev.diffopt.close_file = 1;
227         if (run_diff_files(&rev, 0))
228                 die(_("Could not write patch"));
229
230         if (launch_editor(file, NULL, NULL))
231                 die(_("editing patch failed"));
232
233         if (stat(file, &st))
234                 die_errno(_("Could not stat '%s'"), file);
235         if (!st.st_size)
236                 die(_("Empty patch. Aborted."));
237
238         child.git_cmd = 1;
239         child.argv = apply_argv;
240         if (run_command(&child))
241                 die(_("Could not apply '%s'"), file);
242
243         unlink(file);
244         free(file);
245         return 0;
246 }
247
248 static struct lock_file lock_file;
249
250 static const char ignore_error[] =
251 N_("The following paths are ignored by one of your .gitignore files:\n");
252
253 static int verbose, show_only, ignored_too, refresh_only;
254 static int ignore_add_errors, intent_to_add, ignore_missing;
255 static int warn_on_embedded_repo = 1;
256
257 #define ADDREMOVE_DEFAULT 1
258 static int addremove = ADDREMOVE_DEFAULT;
259 static int addremove_explicit = -1; /* unspecified */
260
261 static char *chmod_arg;
262
263 static 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
270 static struct option builtin_add_options[] = {
271         OPT__DRY_RUN(&show_only, N_("dry run")),
272         OPT__VERBOSE(&verbose, N_("be verbose")),
273         OPT_GROUP(""),
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")),
277         OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
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")),
280         OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
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 },
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")),
288         OPT_STRING( 0 , "chmod", &chmod_arg, N_("(+/-)x"), N_("override the executable bit of the listed files")),
289         OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
290                         N_("warn when adding an embedded repository")),
291         OPT_END(),
292 };
293
294 static int add_config(const char *var, const char *value, void *cb)
295 {
296         if (!strcmp(var, "add.ignoreerrors") ||
297             !strcmp(var, "add.ignore-errors")) {
298                 ignore_add_errors = git_config_bool(var, value);
299                 return 0;
300         }
301         return git_default_config(var, value, cb);
302 }
303
304 static 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
320 static 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
343 static int add_files(struct dir_struct *dir, int flags)
344 {
345         int i, exit_status = 0;
346
347         if (dir->ignored_nr) {
348                 fprintf(stderr, _(ignore_error));
349                 for (i = 0; i < dir->ignored_nr; i++)
350                         fprintf(stderr, "%s\n", dir->ignored[i]->name);
351                 fprintf(stderr, _("Use -f if you really want to add them.\n"));
352                 exit_status = 1;
353         }
354
355         for (i = 0; i < dir->nr; i++) {
356                 check_embedded_repo(dir->entries[i]->name);
357                 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
358                         if (!ignore_add_errors)
359                                 die(_("adding files failed"));
360                         exit_status = 1;
361                 }
362         }
363         return exit_status;
364 }
365
366 int cmd_add(int argc, const char **argv, const char *prefix)
367 {
368         int exit_status = 0;
369         struct pathspec pathspec;
370         struct dir_struct dir;
371         int flags;
372         int add_new_files;
373         int require_pathspec;
374         char *seen = NULL;
375
376         git_config(add_config, NULL);
377
378         argc = parse_options(argc, argv, prefix, builtin_add_options,
379                           builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
380         if (patch_interactive)
381                 add_interactive = 1;
382         if (add_interactive)
383                 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
384
385         if (edit_interactive)
386                 return(edit_patch(argc, argv, prefix));
387         argc--;
388         argv++;
389
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
395         if (addremove && take_worktree_changes)
396                 die(_("-A and -u are mutually incompatible"));
397
398         if (!take_worktree_changes && addremove_explicit < 0 && argc)
399                 /* Turn "git add pathspec..." to "git add -A pathspec..." */
400                 addremove = 1;
401
402         if (!show_only && ignore_missing)
403                 die(_("Option --ignore-missing can only be used together with --dry-run"));
404
405         if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
406                           chmod_arg[1] != 'x' || chmod_arg[2]))
407                 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
408
409         add_new_files = !take_worktree_changes && !refresh_only;
410         require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
411
412         hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
413
414         flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
415                  (show_only ? ADD_CACHE_PRETEND : 0) |
416                  (intent_to_add ? ADD_CACHE_INTENT : 0) |
417                  (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
418                  (!(addremove || take_worktree_changes)
419                   ? ADD_CACHE_IGNORE_REMOVAL : 0));
420
421         if (require_pathspec && argc == 0) {
422                 fprintf(stderr, _("Nothing specified, nothing added.\n"));
423                 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
424                 return 0;
425         }
426
427         if (read_cache() < 0)
428                 die(_("index file corrupt"));
429
430         die_in_unpopulated_submodule(&the_index, prefix);
431
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 |
438                        PATHSPEC_SYMLINK_LEADING_PATH,
439                        prefix, argv);
440
441         die_path_inside_submodule(&the_index, &pathspec);
442
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
453                 /* This picks up the paths that are not tracked */
454                 baselen = fill_directory(&dir, &the_index, &pathspec);
455                 if (pathspec.nr)
456                         seen = prune_directory(&dir, &pathspec, baselen);
457         }
458
459         if (refresh_only) {
460                 refresh(verbose, &pathspec);
461                 goto finish;
462         }
463
464         if (pathspec.nr) {
465                 int i;
466
467                 if (!seen)
468                         seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
469
470                 /*
471                  * file_exists() assumes exact match
472                  */
473                 GUARD_PATHSPEC(&pathspec,
474                                PATHSPEC_FROMTOP |
475                                PATHSPEC_LITERAL |
476                                PATHSPEC_GLOB |
477                                PATHSPEC_ICASE |
478                                PATHSPEC_EXCLUDE);
479
480                 for (i = 0; i < pathspec.nr; i++) {
481                         const char *path = pathspec.items[i].match;
482                         if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
483                                 continue;
484                         if (!seen[i] && path[0] &&
485                             ((pathspec.items[i].magic &
486                               (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
487                              !file_exists(path))) {
488                                 if (ignore_missing) {
489                                         int dtype = DT_UNKNOWN;
490                                         if (is_excluded(&dir, &the_index, path, &dtype))
491                                                 dir_add_ignored(&dir, &the_index,
492                                                                 path, pathspec.items[i].len);
493                                 } else
494                                         die(_("pathspec '%s' did not match any files"),
495                                             pathspec.items[i].original);
496                         }
497                 }
498                 free(seen);
499         }
500
501         plug_bulk_checkin();
502
503         exit_status |= add_files_to_cache(prefix, &pathspec, flags);
504
505         if (add_new_files)
506                 exit_status |= add_files(&dir, flags);
507
508         if (chmod_arg && pathspec.nr)
509                 chmod_pathspec(&pathspec, chmod_arg[0]);
510         unplug_bulk_checkin();
511
512 finish:
513         if (active_cache_changed) {
514                 if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
515                         die(_("Unable to write new index file"));
516         }
517
518         UNLEAK(pathspec);
519         UNLEAK(dir);
520         return exit_status;
521 }