built-in add -p: implement the "checkout" patch modes
[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
212                         die("'%s' not supported", patch_mode);
213
214                 return !!run_add_p(the_repository, mode, revision, pathspec);
215         }
216
217         argv_array_push(&argv, "add--interactive");
218         if (patch_mode)
219                 argv_array_push(&argv, patch_mode);
220         if (revision)
221                 argv_array_push(&argv, revision);
222         argv_array_push(&argv, "--");
223         for (i = 0; i < pathspec->nr; i++)
224                 /* pass original pathspec, to be re-parsed */
225                 argv_array_push(&argv, pathspec->items[i].original);
226
227         status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
228         argv_array_clear(&argv);
229         return status;
230 }
231
232 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
233 {
234         struct pathspec pathspec;
235
236         parse_pathspec(&pathspec, 0,
237                        PATHSPEC_PREFER_FULL |
238                        PATHSPEC_SYMLINK_LEADING_PATH |
239                        PATHSPEC_PREFIX_ORIGIN,
240                        prefix, argv);
241
242         return run_add_interactive(NULL,
243                                    patch ? "--patch" : NULL,
244                                    &pathspec);
245 }
246
247 static int edit_patch(int argc, const char **argv, const char *prefix)
248 {
249         char *file = git_pathdup("ADD_EDIT.patch");
250         const char *apply_argv[] = { "apply", "--recount", "--cached",
251                 NULL, NULL };
252         struct child_process child = CHILD_PROCESS_INIT;
253         struct rev_info rev;
254         int out;
255         struct stat st;
256
257         apply_argv[3] = file;
258
259         git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
260
261         if (read_cache() < 0)
262                 die(_("Could not read the index"));
263
264         repo_init_revisions(the_repository, &rev, prefix);
265         rev.diffopt.context = 7;
266
267         argc = setup_revisions(argc, argv, &rev, NULL);
268         rev.diffopt.output_format = DIFF_FORMAT_PATCH;
269         rev.diffopt.use_color = 0;
270         rev.diffopt.flags.ignore_dirty_submodules = 1;
271         out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
272         if (out < 0)
273                 die(_("Could not open '%s' for writing."), file);
274         rev.diffopt.file = xfdopen(out, "w");
275         rev.diffopt.close_file = 1;
276         if (run_diff_files(&rev, 0))
277                 die(_("Could not write patch"));
278
279         if (launch_editor(file, NULL, NULL))
280                 die(_("editing patch failed"));
281
282         if (stat(file, &st))
283                 die_errno(_("Could not stat '%s'"), file);
284         if (!st.st_size)
285                 die(_("Empty patch. Aborted."));
286
287         child.git_cmd = 1;
288         child.argv = apply_argv;
289         if (run_command(&child))
290                 die(_("Could not apply '%s'"), file);
291
292         unlink(file);
293         free(file);
294         return 0;
295 }
296
297 static const char ignore_error[] =
298 N_("The following paths are ignored by one of your .gitignore files:\n");
299
300 static int verbose, show_only, ignored_too, refresh_only;
301 static int ignore_add_errors, intent_to_add, ignore_missing;
302 static int warn_on_embedded_repo = 1;
303
304 #define ADDREMOVE_DEFAULT 1
305 static int addremove = ADDREMOVE_DEFAULT;
306 static int addremove_explicit = -1; /* unspecified */
307
308 static char *chmod_arg;
309
310 static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
311 {
312         /* if we are told to ignore, we are not adding removals */
313         *(int *)opt->value = !unset ? 0 : 1;
314         return 0;
315 }
316
317 static struct option builtin_add_options[] = {
318         OPT__DRY_RUN(&show_only, N_("dry run")),
319         OPT__VERBOSE(&verbose, N_("be verbose")),
320         OPT_GROUP(""),
321         OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
322         OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
323         OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
324         OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
325         OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
326         OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
327         OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
328         OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
329         { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
330           NULL /* takes no arguments */,
331           N_("ignore paths removed in the working tree (same as --no-all)"),
332           PARSE_OPT_NOARG, ignore_removal_cb },
333         OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
334         OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
335         OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
336         OPT_STRING(0, "chmod", &chmod_arg, "(+|-)x",
337                    N_("override the executable bit of the listed files")),
338         OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
339                         N_("warn when adding an embedded repository")),
340         OPT_HIDDEN_BOOL(0, "legacy-stash-p", &legacy_stash_p,
341                         N_("backend for `git stash -p`")),
342         OPT_END(),
343 };
344
345 static int add_config(const char *var, const char *value, void *cb)
346 {
347         if (!strcmp(var, "add.ignoreerrors") ||
348             !strcmp(var, "add.ignore-errors")) {
349                 ignore_add_errors = git_config_bool(var, value);
350                 return 0;
351         }
352
353         return git_default_config(var, value, cb);
354 }
355
356 static const char embedded_advice[] = N_(
357 "You've added another git repository inside your current repository.\n"
358 "Clones of the outer repository will not contain the contents of\n"
359 "the embedded repository and will not know how to obtain it.\n"
360 "If you meant to add a submodule, use:\n"
361 "\n"
362 "       git submodule add <url> %s\n"
363 "\n"
364 "If you added this path by mistake, you can remove it from the\n"
365 "index with:\n"
366 "\n"
367 "       git rm --cached %s\n"
368 "\n"
369 "See \"git help submodule\" for more information."
370 );
371
372 static void check_embedded_repo(const char *path)
373 {
374         struct strbuf name = STRBUF_INIT;
375
376         if (!warn_on_embedded_repo)
377                 return;
378         if (!ends_with(path, "/"))
379                 return;
380
381         /* Drop trailing slash for aesthetics */
382         strbuf_addstr(&name, path);
383         strbuf_strip_suffix(&name, "/");
384
385         warning(_("adding embedded git repository: %s"), name.buf);
386         if (advice_add_embedded_repo) {
387                 advise(embedded_advice, name.buf, name.buf);
388                 /* there may be multiple entries; advise only once */
389                 advice_add_embedded_repo = 0;
390         }
391
392         strbuf_release(&name);
393 }
394
395 static int add_files(struct dir_struct *dir, int flags)
396 {
397         int i, exit_status = 0;
398
399         if (dir->ignored_nr) {
400                 fprintf(stderr, _(ignore_error));
401                 for (i = 0; i < dir->ignored_nr; i++)
402                         fprintf(stderr, "%s\n", dir->ignored[i]->name);
403                 fprintf(stderr, _("Use -f if you really want to add them.\n"));
404                 exit_status = 1;
405         }
406
407         for (i = 0; i < dir->nr; i++) {
408                 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
409                         if (!ignore_add_errors)
410                                 die(_("adding files failed"));
411                         exit_status = 1;
412                 } else {
413                         check_embedded_repo(dir->entries[i]->name);
414                 }
415         }
416         return exit_status;
417 }
418
419 int cmd_add(int argc, const char **argv, const char *prefix)
420 {
421         int exit_status = 0;
422         struct pathspec pathspec;
423         struct dir_struct dir;
424         int flags;
425         int add_new_files;
426         int require_pathspec;
427         char *seen = NULL;
428         struct lock_file lock_file = LOCK_INIT;
429
430         git_config(add_config, NULL);
431
432         argc = parse_options(argc, argv, prefix, builtin_add_options,
433                           builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
434         if (patch_interactive)
435                 add_interactive = 1;
436         if (add_interactive)
437                 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
438         if (legacy_stash_p) {
439                 struct pathspec pathspec;
440
441                 parse_pathspec(&pathspec, 0,
442                         PATHSPEC_PREFER_FULL |
443                         PATHSPEC_SYMLINK_LEADING_PATH |
444                         PATHSPEC_PREFIX_ORIGIN,
445                         prefix, argv);
446
447                 return run_add_interactive(NULL, "--patch=stash", &pathspec);
448         }
449
450         if (edit_interactive)
451                 return(edit_patch(argc, argv, prefix));
452         argc--;
453         argv++;
454
455         if (0 <= addremove_explicit)
456                 addremove = addremove_explicit;
457         else if (take_worktree_changes && ADDREMOVE_DEFAULT)
458                 addremove = 0; /* "-u" was given but not "-A" */
459
460         if (addremove && take_worktree_changes)
461                 die(_("-A and -u are mutually incompatible"));
462
463         if (!take_worktree_changes && addremove_explicit < 0 && argc)
464                 /* Turn "git add pathspec..." to "git add -A pathspec..." */
465                 addremove = 1;
466
467         if (!show_only && ignore_missing)
468                 die(_("Option --ignore-missing can only be used together with --dry-run"));
469
470         if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
471                           chmod_arg[1] != 'x' || chmod_arg[2]))
472                 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
473
474         add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
475         require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
476
477         hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
478
479         flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
480                  (show_only ? ADD_CACHE_PRETEND : 0) |
481                  (intent_to_add ? ADD_CACHE_INTENT : 0) |
482                  (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
483                  (!(addremove || take_worktree_changes)
484                   ? ADD_CACHE_IGNORE_REMOVAL : 0));
485
486         if (require_pathspec && argc == 0) {
487                 fprintf(stderr, _("Nothing specified, nothing added.\n"));
488                 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
489                 return 0;
490         }
491
492         /*
493          * Check the "pathspec '%s' did not match any files" block
494          * below before enabling new magic.
495          */
496         parse_pathspec(&pathspec, PATHSPEC_ATTR,
497                        PATHSPEC_PREFER_FULL |
498                        PATHSPEC_SYMLINK_LEADING_PATH,
499                        prefix, argv);
500
501         if (read_cache_preload(&pathspec) < 0)
502                 die(_("index file corrupt"));
503
504         die_in_unpopulated_submodule(&the_index, prefix);
505         die_path_inside_submodule(&the_index, &pathspec);
506
507         if (add_new_files) {
508                 int baselen;
509
510                 /* Set up the default git porcelain excludes */
511                 memset(&dir, 0, sizeof(dir));
512                 if (!ignored_too) {
513                         dir.flags |= DIR_COLLECT_IGNORED;
514                         setup_standard_excludes(&dir);
515                 }
516
517                 /* This picks up the paths that are not tracked */
518                 baselen = fill_directory(&dir, &the_index, &pathspec);
519                 if (pathspec.nr)
520                         seen = prune_directory(&dir, &pathspec, baselen);
521         }
522
523         if (refresh_only) {
524                 refresh(verbose, &pathspec);
525                 goto finish;
526         }
527
528         if (pathspec.nr) {
529                 int i;
530
531                 if (!seen)
532                         seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
533
534                 /*
535                  * file_exists() assumes exact match
536                  */
537                 GUARD_PATHSPEC(&pathspec,
538                                PATHSPEC_FROMTOP |
539                                PATHSPEC_LITERAL |
540                                PATHSPEC_GLOB |
541                                PATHSPEC_ICASE |
542                                PATHSPEC_EXCLUDE);
543
544                 for (i = 0; i < pathspec.nr; i++) {
545                         const char *path = pathspec.items[i].match;
546                         if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
547                                 continue;
548                         if (!seen[i] && path[0] &&
549                             ((pathspec.items[i].magic &
550                               (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
551                              !file_exists(path))) {
552                                 if (ignore_missing) {
553                                         int dtype = DT_UNKNOWN;
554                                         if (is_excluded(&dir, &the_index, path, &dtype))
555                                                 dir_add_ignored(&dir, &the_index,
556                                                                 path, pathspec.items[i].len);
557                                 } else
558                                         die(_("pathspec '%s' did not match any files"),
559                                             pathspec.items[i].original);
560                         }
561                 }
562                 free(seen);
563         }
564
565         plug_bulk_checkin();
566
567         if (add_renormalize)
568                 exit_status |= renormalize_tracked_files(&pathspec, flags);
569         else
570                 exit_status |= add_files_to_cache(prefix, &pathspec, flags);
571
572         if (add_new_files)
573                 exit_status |= add_files(&dir, flags);
574
575         if (chmod_arg && pathspec.nr)
576                 chmod_pathspec(&pathspec, chmod_arg[0]);
577         unplug_bulk_checkin();
578
579 finish:
580         if (write_locked_index(&the_index, &lock_file,
581                                COMMIT_LOCK | SKIP_IF_UNCHANGED))
582                 die(_("Unable to write new index file"));
583
584         UNLEAK(pathspec);
585         UNLEAK(dir);
586         return exit_status;
587 }