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