commit --interactive: make it work with the built-in `add -i`
[git] / builtin / add.c
1 /*
2  * "git add" builtin command
3  *
4  * Copyright (C) 2006 Linus Torvalds
5  */
6 #define USE_THE_INDEX_COMPATIBILITY_MACROS
7 #include "cache.h"
8 #include "config.h"
9 #include "builtin.h"
10 #include "lockfile.h"
11 #include "dir.h"
12 #include "pathspec.h"
13 #include "exec-cmd.h"
14 #include "cache-tree.h"
15 #include "run-command.h"
16 #include "parse-options.h"
17 #include "diff.h"
18 #include "diffcore.h"
19 #include "revision.h"
20 #include "bulk-checkin.h"
21 #include "argv-array.h"
22 #include "submodule.h"
23 #include "add-interactive.h"
24
25 static const char * const builtin_add_usage[] = {
26         N_("git add [<options>] [--] <pathspec>..."),
27         NULL
28 };
29 static int patch_interactive, add_interactive, edit_interactive;
30 static int take_worktree_changes;
31 static int add_renormalize;
32 static int legacy_stash_p; /* support for the scripted `git stash` */
33
34 struct update_callback_data {
35         int flags;
36         int add_errors;
37 };
38
39 static void chmod_pathspec(struct pathspec *pathspec, char flip)
40 {
41         int i;
42
43         for (i = 0; i < active_nr; i++) {
44                 struct cache_entry *ce = active_cache[i];
45
46                 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
47                         continue;
48
49                 if (chmod_cache_entry(ce, flip) < 0)
50                         fprintf(stderr, "cannot chmod %cx '%s'\n", flip, ce->name);
51         }
52 }
53
54 static int fix_unmerged_status(struct diff_filepair *p,
55                                struct update_callback_data *data)
56 {
57         if (p->status != DIFF_STATUS_UNMERGED)
58                 return p->status;
59         if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
60                 /*
61                  * This is not an explicit add request, and the
62                  * path is missing from the working tree (deleted)
63                  */
64                 return DIFF_STATUS_DELETED;
65         else
66                 /*
67                  * Either an explicit add request, or path exists
68                  * in the working tree.  An attempt to explicitly
69                  * add a path that does not exist in the working tree
70                  * will be caught as an error by the caller immediately.
71                  */
72                 return DIFF_STATUS_MODIFIED;
73 }
74
75 static void update_callback(struct diff_queue_struct *q,
76                             struct diff_options *opt, void *cbdata)
77 {
78         int i;
79         struct update_callback_data *data = cbdata;
80
81         for (i = 0; i < q->nr; i++) {
82                 struct diff_filepair *p = q->queue[i];
83                 const char *path = p->one->path;
84                 switch (fix_unmerged_status(p, data)) {
85                 default:
86                         die(_("unexpected diff status %c"), p->status);
87                 case DIFF_STATUS_MODIFIED:
88                 case DIFF_STATUS_TYPE_CHANGED:
89                         if (add_file_to_index(&the_index, path, data->flags)) {
90                                 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
91                                         die(_("updating files failed"));
92                                 data->add_errors++;
93                         }
94                         break;
95                 case DIFF_STATUS_DELETED:
96                         if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
97                                 break;
98                         if (!(data->flags & ADD_CACHE_PRETEND))
99                                 remove_file_from_index(&the_index, path);
100                         if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
101                                 printf(_("remove '%s'\n"), path);
102                         break;
103                 }
104         }
105 }
106
107 int add_files_to_cache(const char *prefix,
108                        const struct pathspec *pathspec, int flags)
109 {
110         struct update_callback_data data;
111         struct rev_info rev;
112
113         memset(&data, 0, sizeof(data));
114         data.flags = flags;
115
116         repo_init_revisions(the_repository, &rev, prefix);
117         setup_revisions(0, NULL, &rev, NULL);
118         if (pathspec)
119                 copy_pathspec(&rev.prune_data, pathspec);
120         rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
121         rev.diffopt.format_callback = update_callback;
122         rev.diffopt.format_callback_data = &data;
123         rev.diffopt.flags.override_submodule_config = 1;
124         rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
125         run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
126         clear_pathspec(&rev.prune_data);
127         return !!data.add_errors;
128 }
129
130 static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
131 {
132         int i, retval = 0;
133
134         for (i = 0; i < active_nr; i++) {
135                 struct cache_entry *ce = active_cache[i];
136
137                 if (ce_stage(ce))
138                         continue; /* do not touch unmerged paths */
139                 if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
140                         continue; /* do not touch non blobs */
141                 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
142                         continue;
143                 retval |= add_file_to_cache(ce->name, flags | ADD_CACHE_RENORMALIZE);
144         }
145
146         return retval;
147 }
148
149 static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
150 {
151         char *seen;
152         int i;
153         struct dir_entry **src, **dst;
154
155         seen = xcalloc(pathspec->nr, 1);
156
157         src = dst = dir->entries;
158         i = dir->nr;
159         while (--i >= 0) {
160                 struct dir_entry *entry = *src++;
161                 if (dir_path_match(&the_index, entry, pathspec, prefix, seen))
162                         *dst++ = entry;
163         }
164         dir->nr = dst - dir->entries;
165         add_pathspec_matches_against_index(pathspec, &the_index, seen);
166         return seen;
167 }
168
169 static void refresh(int verbose, const struct pathspec *pathspec)
170 {
171         char *seen;
172         int i;
173
174         seen = xcalloc(pathspec->nr, 1);
175         refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
176                       pathspec, seen, _("Unstaged changes after refreshing the index:"));
177         for (i = 0; i < pathspec->nr; i++) {
178                 if (!seen[i])
179                         die(_("pathspec '%s' did not match any files"),
180                             pathspec->items[i].match);
181         }
182         free(seen);
183 }
184
185 int run_add_interactive(const char *revision, const char *patch_mode,
186                         const struct pathspec *pathspec)
187 {
188         int status, i;
189         struct argv_array argv = ARGV_ARRAY_INIT;
190         int use_builtin_add_i =
191                 git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
192
193         if (use_builtin_add_i < 0)
194                 git_config_get_bool("add.interactive.usebuiltin",
195                                     &use_builtin_add_i);
196
197         if (use_builtin_add_i == 1) {
198                 enum add_p_mode mode;
199
200                 if (!patch_mode)
201                         return !!run_add_i(the_repository, pathspec);
202
203                 if (!strcmp(patch_mode, "--patch"))
204                         mode = ADD_P_ADD;
205                 else if (!strcmp(patch_mode, "--patch=stash"))
206                         mode = ADD_P_STASH;
207                 else if (!strcmp(patch_mode, "--patch=reset"))
208                         mode = ADD_P_RESET;
209                 else if (!strcmp(patch_mode, "--patch=checkout"))
210                         mode = ADD_P_CHECKOUT;
211                 else if (!strcmp(patch_mode, "--patch=worktree"))
212                         mode = ADD_P_WORKTREE;
213                 else
214                         die("'%s' not supported", patch_mode);
215
216                 return !!run_add_p(the_repository, mode, revision, pathspec);
217         }
218
219         argv_array_push(&argv, "add--interactive");
220         if (patch_mode)
221                 argv_array_push(&argv, patch_mode);
222         if (revision)
223                 argv_array_push(&argv, revision);
224         argv_array_push(&argv, "--");
225         for (i = 0; i < pathspec->nr; i++)
226                 /* pass original pathspec, to be re-parsed */
227                 argv_array_push(&argv, pathspec->items[i].original);
228
229         status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
230         argv_array_clear(&argv);
231         return status;
232 }
233
234 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
235 {
236         struct pathspec pathspec;
237
238         parse_pathspec(&pathspec, 0,
239                        PATHSPEC_PREFER_FULL |
240                        PATHSPEC_SYMLINK_LEADING_PATH |
241                        PATHSPEC_PREFIX_ORIGIN,
242                        prefix, argv);
243
244         return run_add_interactive(NULL,
245                                    patch ? "--patch" : NULL,
246                                    &pathspec);
247 }
248
249 static int edit_patch(int argc, const char **argv, const char *prefix)
250 {
251         char *file = git_pathdup("ADD_EDIT.patch");
252         const char *apply_argv[] = { "apply", "--recount", "--cached",
253                 NULL, NULL };
254         struct child_process child = CHILD_PROCESS_INIT;
255         struct rev_info rev;
256         int out;
257         struct stat st;
258
259         apply_argv[3] = file;
260
261         git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
262
263         if (read_cache() < 0)
264                 die(_("Could not read the index"));
265
266         repo_init_revisions(the_repository, &rev, prefix);
267         rev.diffopt.context = 7;
268
269         argc = setup_revisions(argc, argv, &rev, NULL);
270         rev.diffopt.output_format = DIFF_FORMAT_PATCH;
271         rev.diffopt.use_color = 0;
272         rev.diffopt.flags.ignore_dirty_submodules = 1;
273         out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
274         if (out < 0)
275                 die(_("Could not open '%s' for writing."), file);
276         rev.diffopt.file = xfdopen(out, "w");
277         rev.diffopt.close_file = 1;
278         if (run_diff_files(&rev, 0))
279                 die(_("Could not write patch"));
280
281         if (launch_editor(file, NULL, NULL))
282                 die(_("editing patch failed"));
283
284         if (stat(file, &st))
285                 die_errno(_("Could not stat '%s'"), file);
286         if (!st.st_size)
287                 die(_("Empty patch. Aborted."));
288
289         child.git_cmd = 1;
290         child.argv = apply_argv;
291         if (run_command(&child))
292                 die(_("Could not apply '%s'"), file);
293
294         unlink(file);
295         free(file);
296         return 0;
297 }
298
299 static const char ignore_error[] =
300 N_("The following paths are ignored by one of your .gitignore files:\n");
301
302 static int verbose, show_only, ignored_too, refresh_only;
303 static int ignore_add_errors, intent_to_add, ignore_missing;
304 static int warn_on_embedded_repo = 1;
305
306 #define ADDREMOVE_DEFAULT 1
307 static int addremove = ADDREMOVE_DEFAULT;
308 static int addremove_explicit = -1; /* unspecified */
309
310 static char *chmod_arg;
311
312 static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
313 {
314         /* if we are told to ignore, we are not adding removals */
315         *(int *)opt->value = !unset ? 0 : 1;
316         return 0;
317 }
318
319 static struct option builtin_add_options[] = {
320         OPT__DRY_RUN(&show_only, N_("dry run")),
321         OPT__VERBOSE(&verbose, N_("be verbose")),
322         OPT_GROUP(""),
323         OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
324         OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
325         OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
326         OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
327         OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
328         OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
329         OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
330         OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
331         { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
332           NULL /* takes no arguments */,
333           N_("ignore paths removed in the working tree (same as --no-all)"),
334           PARSE_OPT_NOARG, ignore_removal_cb },
335         OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
336         OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
337         OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
338         OPT_STRING(0, "chmod", &chmod_arg, "(+|-)x",
339                    N_("override the executable bit of the listed files")),
340         OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
341                         N_("warn when adding an embedded repository")),
342         OPT_HIDDEN_BOOL(0, "legacy-stash-p", &legacy_stash_p,
343                         N_("backend for `git stash -p`")),
344         OPT_END(),
345 };
346
347 static int add_config(const char *var, const char *value, void *cb)
348 {
349         if (!strcmp(var, "add.ignoreerrors") ||
350             !strcmp(var, "add.ignore-errors")) {
351                 ignore_add_errors = git_config_bool(var, value);
352                 return 0;
353         }
354
355         return git_default_config(var, value, cb);
356 }
357
358 static const char embedded_advice[] = N_(
359 "You've added another git repository inside your current repository.\n"
360 "Clones of the outer repository will not contain the contents of\n"
361 "the embedded repository and will not know how to obtain it.\n"
362 "If you meant to add a submodule, use:\n"
363 "\n"
364 "       git submodule add <url> %s\n"
365 "\n"
366 "If you added this path by mistake, you can remove it from the\n"
367 "index with:\n"
368 "\n"
369 "       git rm --cached %s\n"
370 "\n"
371 "See \"git help submodule\" for more information."
372 );
373
374 static void check_embedded_repo(const char *path)
375 {
376         struct strbuf name = STRBUF_INIT;
377
378         if (!warn_on_embedded_repo)
379                 return;
380         if (!ends_with(path, "/"))
381                 return;
382
383         /* Drop trailing slash for aesthetics */
384         strbuf_addstr(&name, path);
385         strbuf_strip_suffix(&name, "/");
386
387         warning(_("adding embedded git repository: %s"), name.buf);
388         if (advice_add_embedded_repo) {
389                 advise(embedded_advice, name.buf, name.buf);
390                 /* there may be multiple entries; advise only once */
391                 advice_add_embedded_repo = 0;
392         }
393
394         strbuf_release(&name);
395 }
396
397 static int add_files(struct dir_struct *dir, int flags)
398 {
399         int i, exit_status = 0;
400
401         if (dir->ignored_nr) {
402                 fprintf(stderr, _(ignore_error));
403                 for (i = 0; i < dir->ignored_nr; i++)
404                         fprintf(stderr, "%s\n", dir->ignored[i]->name);
405                 fprintf(stderr, _("Use -f if you really want to add them.\n"));
406                 exit_status = 1;
407         }
408
409         for (i = 0; i < dir->nr; i++) {
410                 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
411                         if (!ignore_add_errors)
412                                 die(_("adding files failed"));
413                         exit_status = 1;
414                 } else {
415                         check_embedded_repo(dir->entries[i]->name);
416                 }
417         }
418         return exit_status;
419 }
420
421 int cmd_add(int argc, const char **argv, const char *prefix)
422 {
423         int exit_status = 0;
424         struct pathspec pathspec;
425         struct dir_struct dir;
426         int flags;
427         int add_new_files;
428         int require_pathspec;
429         char *seen = NULL;
430         struct lock_file lock_file = LOCK_INIT;
431
432         git_config(add_config, NULL);
433
434         argc = parse_options(argc, argv, prefix, builtin_add_options,
435                           builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
436         if (patch_interactive)
437                 add_interactive = 1;
438         if (add_interactive)
439                 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
440         if (legacy_stash_p) {
441                 struct pathspec pathspec;
442
443                 parse_pathspec(&pathspec, 0,
444                         PATHSPEC_PREFER_FULL |
445                         PATHSPEC_SYMLINK_LEADING_PATH |
446                         PATHSPEC_PREFIX_ORIGIN,
447                         prefix, argv);
448
449                 return run_add_interactive(NULL, "--patch=stash", &pathspec);
450         }
451
452         if (edit_interactive)
453                 return(edit_patch(argc, argv, prefix));
454         argc--;
455         argv++;
456
457         if (0 <= addremove_explicit)
458                 addremove = addremove_explicit;
459         else if (take_worktree_changes && ADDREMOVE_DEFAULT)
460                 addremove = 0; /* "-u" was given but not "-A" */
461
462         if (addremove && take_worktree_changes)
463                 die(_("-A and -u are mutually incompatible"));
464
465         if (!take_worktree_changes && addremove_explicit < 0 && argc)
466                 /* Turn "git add pathspec..." to "git add -A pathspec..." */
467                 addremove = 1;
468
469         if (!show_only && ignore_missing)
470                 die(_("Option --ignore-missing can only be used together with --dry-run"));
471
472         if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
473                           chmod_arg[1] != 'x' || chmod_arg[2]))
474                 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
475
476         add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
477         require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
478
479         hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
480
481         flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
482                  (show_only ? ADD_CACHE_PRETEND : 0) |
483                  (intent_to_add ? ADD_CACHE_INTENT : 0) |
484                  (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
485                  (!(addremove || take_worktree_changes)
486                   ? ADD_CACHE_IGNORE_REMOVAL : 0));
487
488         if (require_pathspec && argc == 0) {
489                 fprintf(stderr, _("Nothing specified, nothing added.\n"));
490                 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
491                 return 0;
492         }
493
494         /*
495          * Check the "pathspec '%s' did not match any files" block
496          * below before enabling new magic.
497          */
498         parse_pathspec(&pathspec, PATHSPEC_ATTR,
499                        PATHSPEC_PREFER_FULL |
500                        PATHSPEC_SYMLINK_LEADING_PATH,
501                        prefix, argv);
502
503         if (read_cache_preload(&pathspec) < 0)
504                 die(_("index file corrupt"));
505
506         die_in_unpopulated_submodule(&the_index, prefix);
507         die_path_inside_submodule(&the_index, &pathspec);
508
509         if (add_new_files) {
510                 int baselen;
511
512                 /* Set up the default git porcelain excludes */
513                 memset(&dir, 0, sizeof(dir));
514                 if (!ignored_too) {
515                         dir.flags |= DIR_COLLECT_IGNORED;
516                         setup_standard_excludes(&dir);
517                 }
518
519                 /* This picks up the paths that are not tracked */
520                 baselen = fill_directory(&dir, &the_index, &pathspec);
521                 if (pathspec.nr)
522                         seen = prune_directory(&dir, &pathspec, baselen);
523         }
524
525         if (refresh_only) {
526                 refresh(verbose, &pathspec);
527                 goto finish;
528         }
529
530         if (pathspec.nr) {
531                 int i;
532
533                 if (!seen)
534                         seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
535
536                 /*
537                  * file_exists() assumes exact match
538                  */
539                 GUARD_PATHSPEC(&pathspec,
540                                PATHSPEC_FROMTOP |
541                                PATHSPEC_LITERAL |
542                                PATHSPEC_GLOB |
543                                PATHSPEC_ICASE |
544                                PATHSPEC_EXCLUDE);
545
546                 for (i = 0; i < pathspec.nr; i++) {
547                         const char *path = pathspec.items[i].match;
548                         if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
549                                 continue;
550                         if (!seen[i] && path[0] &&
551                             ((pathspec.items[i].magic &
552                               (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
553                              !file_exists(path))) {
554                                 if (ignore_missing) {
555                                         int dtype = DT_UNKNOWN;
556                                         if (is_excluded(&dir, &the_index, path, &dtype))
557                                                 dir_add_ignored(&dir, &the_index,
558                                                                 path, pathspec.items[i].len);
559                                 } else
560                                         die(_("pathspec '%s' did not match any files"),
561                                             pathspec.items[i].original);
562                         }
563                 }
564                 free(seen);
565         }
566
567         plug_bulk_checkin();
568
569         if (add_renormalize)
570                 exit_status |= renormalize_tracked_files(&pathspec, flags);
571         else
572                 exit_status |= add_files_to_cache(prefix, &pathspec, flags);
573
574         if (add_new_files)
575                 exit_status |= add_files(&dir, flags);
576
577         if (chmod_arg && pathspec.nr)
578                 chmod_pathspec(&pathspec, chmod_arg[0]);
579         unplug_bulk_checkin();
580
581 finish:
582         if (write_locked_index(&the_index, &lock_file,
583                                COMMIT_LOCK | SKIP_IF_UNCHANGED))
584                 die(_("Unable to write new index file"));
585
586         UNLEAK(pathspec);
587         UNLEAK(dir);
588         return exit_status;
589 }