1/*
2 * "git add" builtin command
3 *
4 * Copyright (C) 2006 Linus Torvalds
5 */
6#include "cache.h"
7#include "builtin.h"
8#include "dir.h"
9#include "pathspec.h"
10#include "exec_cmd.h"
11#include "cache-tree.h"
12#include "run-command.h"
13#include "parse-options.h"
14#include "diff.h"
15#include "diffcore.h"
16#include "revision.h"
17#include "bulk-checkin.h"
18
19static const char * const builtin_add_usage[] = {
20 N_("git add [options] [--] <pathspec>..."),
21 NULL
22};
23static int patch_interactive, add_interactive, edit_interactive;
24static int take_worktree_changes;
25
26struct update_callback_data {
27 int flags;
28 int add_errors;
29 const char *implicit_dot;
30 size_t implicit_dot_len;
31};
32
33static const char *option_with_implicit_dot;
34static const char *short_option_with_implicit_dot;
35
36static void warn_pathless_add(void)
37{
38 static int shown;
39 assert(option_with_implicit_dot && short_option_with_implicit_dot);
40
41 if (shown)
42 return;
43 shown = 1;
44
45 /*
46 * To be consistent with "git add -p" and most Git
47 * commands, we should default to being tree-wide, but
48 * this is not the original behavior and can't be
49 * changed until users trained themselves not to type
50 * "git add -u" or "git add -A". For now, we warn and
51 * keep the old behavior. Later, the behavior can be changed
52 * to tree-wide, keeping the warning for a while, and
53 * eventually we can drop the warning.
54 */
55 warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
56 "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
57 "To add content for the whole tree, run:\n"
58 "\n"
59 " git add %s :/\n"
60 " (or git add %s :/)\n"
61 "\n"
62 "To restrict the command to the current directory, run:\n"
63 "\n"
64 " git add %s .\n"
65 " (or git add %s .)\n"
66 "\n"
67 "With the current Git version, the command is restricted to "
68 "the current directory.\n"
69 ""),
70 option_with_implicit_dot, short_option_with_implicit_dot,
71 option_with_implicit_dot, short_option_with_implicit_dot,
72 option_with_implicit_dot, short_option_with_implicit_dot);
73}
74
75static int fix_unmerged_status(struct diff_filepair *p,
76 struct update_callback_data *data)
77{
78 if (p->status != DIFF_STATUS_UNMERGED)
79 return p->status;
80 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
81 /*
82 * This is not an explicit add request, and the
83 * path is missing from the working tree (deleted)
84 */
85 return DIFF_STATUS_DELETED;
86 else
87 /*
88 * Either an explicit add request, or path exists
89 * in the working tree. An attempt to explicitly
90 * add a path that does not exist in the working tree
91 * will be caught as an error by the caller immediately.
92 */
93 return DIFF_STATUS_MODIFIED;
94}
95
96static void update_callback(struct diff_queue_struct *q,
97 struct diff_options *opt, void *cbdata)
98{
99 int i;
100 struct update_callback_data *data = cbdata;
101 const char *implicit_dot = data->implicit_dot;
102 size_t implicit_dot_len = data->implicit_dot_len;
103
104 for (i = 0; i < q->nr; i++) {
105 struct diff_filepair *p = q->queue[i];
106 const char *path = p->one->path;
107 /*
108 * Check if "git add -A" or "git add -u" was run from a
109 * subdirectory with a modified file outside that directory,
110 * and warn if so.
111 *
112 * "git add -u" will behave like "git add -u :/" instead of
113 * "git add -u ." in the future. This warning prepares for
114 * that change.
115 */
116 if (implicit_dot &&
117 strncmp_icase(path, implicit_dot, implicit_dot_len)) {
118 warn_pathless_add();
119 continue;
120 }
121 switch (fix_unmerged_status(p, data)) {
122 default:
123 die(_("unexpected diff status %c"), p->status);
124 case DIFF_STATUS_MODIFIED:
125 case DIFF_STATUS_TYPE_CHANGED:
126 if (add_file_to_index(&the_index, path, data->flags)) {
127 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
128 die(_("updating files failed"));
129 data->add_errors++;
130 }
131 break;
132 case DIFF_STATUS_DELETED:
133 if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
134 break;
135 if (!(data->flags & ADD_CACHE_PRETEND))
136 remove_file_from_index(&the_index, path);
137 if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
138 printf(_("remove '%s'\n"), path);
139 break;
140 }
141 }
142}
143
144int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
145{
146 struct update_callback_data data;
147 struct rev_info rev;
148
149 memset(&data, 0, sizeof(data));
150 data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
151 if ((flags & ADD_CACHE_IMPLICIT_DOT) && prefix) {
152 /*
153 * Check for modified files throughout the worktree so
154 * update_callback has a chance to warn about changes
155 * outside the cwd.
156 */
157 data.implicit_dot = prefix;
158 data.implicit_dot_len = strlen(prefix);
159 pathspec = NULL;
160 }
161
162 init_revisions(&rev, prefix);
163 setup_revisions(0, NULL, &rev, NULL);
164 init_pathspec(&rev.prune_data, pathspec);
165 rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
166 rev.diffopt.format_callback = update_callback;
167 rev.diffopt.format_callback_data = &data;
168 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
169 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
170 return !!data.add_errors;
171}
172
173static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
174{
175 char *seen;
176 int i, specs;
177 struct dir_entry **src, **dst;
178
179 for (specs = 0; pathspec[specs]; specs++)
180 /* nothing */;
181 seen = xcalloc(specs, 1);
182
183 src = dst = dir->entries;
184 i = dir->nr;
185 while (--i >= 0) {
186 struct dir_entry *entry = *src++;
187 if (match_pathspec(pathspec, entry->name, entry->len,
188 prefix, seen))
189 *dst++ = entry;
190 }
191 dir->nr = dst - dir->entries;
192 add_pathspec_matches_against_index(pathspec, seen, specs);
193 return seen;
194}
195
196/*
197 * Checks the index to see whether any path in pathspec refers to
198 * something inside a submodule. If so, dies with an error message.
199 */
200static void treat_gitlinks(const char **pathspec)
201{
202 int i;
203
204 if (!pathspec || !*pathspec)
205 return;
206
207 for (i = 0; pathspec[i]; i++)
208 pathspec[i] = check_path_for_gitlink(pathspec[i]);
209}
210
211static void refresh(int verbose, const char **pathspec)
212{
213 char *seen;
214 int i, specs;
215
216 for (specs = 0; pathspec[specs]; specs++)
217 /* nothing */;
218 seen = xcalloc(specs, 1);
219 refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
220 pathspec, seen, _("Unstaged changes after refreshing the index:"));
221 for (i = 0; i < specs; i++) {
222 if (!seen[i])
223 die(_("pathspec '%s' did not match any files"), pathspec[i]);
224 }
225 free(seen);
226}
227
228/*
229 * Normalizes argv relative to prefix, via get_pathspec(), and then
230 * runs die_if_path_beyond_symlink() on each path in the normalized
231 * list.
232 */
233static const char **validate_pathspec(const char **argv, const char *prefix)
234{
235 const char **pathspec = get_pathspec(prefix, argv);
236
237 if (pathspec) {
238 const char **p;
239 for (p = pathspec; *p; p++) {
240 die_if_path_beyond_symlink(*p, prefix);
241 }
242 }
243
244 return pathspec;
245}
246
247int run_add_interactive(const char *revision, const char *patch_mode,
248 const char **pathspec)
249{
250 int status, ac, pc = 0;
251 const char **args;
252
253 if (pathspec)
254 while (pathspec[pc])
255 pc++;
256
257 args = xcalloc(sizeof(const char *), (pc + 5));
258 ac = 0;
259 args[ac++] = "add--interactive";
260 if (patch_mode)
261 args[ac++] = patch_mode;
262 if (revision)
263 args[ac++] = revision;
264 args[ac++] = "--";
265 if (pc) {
266 memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
267 ac += pc;
268 }
269 args[ac] = NULL;
270
271 status = run_command_v_opt(args, RUN_GIT_CMD);
272 free(args);
273 return status;
274}
275
276int interactive_add(int argc, const char **argv, const char *prefix, int patch)
277{
278 const char **pathspec = NULL;
279
280 if (argc) {
281 pathspec = validate_pathspec(argv, prefix);
282 if (!pathspec)
283 return -1;
284 }
285
286 return run_add_interactive(NULL,
287 patch ? "--patch" : NULL,
288 pathspec);
289}
290
291static int edit_patch(int argc, const char **argv, const char *prefix)
292{
293 char *file = git_pathdup("ADD_EDIT.patch");
294 const char *apply_argv[] = { "apply", "--recount", "--cached",
295 NULL, NULL };
296 struct child_process child;
297 struct rev_info rev;
298 int out;
299 struct stat st;
300
301 apply_argv[3] = file;
302
303 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
304
305 if (read_cache() < 0)
306 die (_("Could not read the index"));
307
308 init_revisions(&rev, prefix);
309 rev.diffopt.context = 7;
310
311 argc = setup_revisions(argc, argv, &rev, NULL);
312 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
313 DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
314 out = open(file, O_CREAT | O_WRONLY, 0666);
315 if (out < 0)
316 die (_("Could not open '%s' for writing."), file);
317 rev.diffopt.file = xfdopen(out, "w");
318 rev.diffopt.close_file = 1;
319 if (run_diff_files(&rev, 0))
320 die (_("Could not write patch"));
321
322 launch_editor(file, NULL, NULL);
323
324 if (stat(file, &st))
325 die_errno(_("Could not stat '%s'"), file);
326 if (!st.st_size)
327 die(_("Empty patch. Aborted."));
328
329 memset(&child, 0, sizeof(child));
330 child.git_cmd = 1;
331 child.argv = apply_argv;
332 if (run_command(&child))
333 die (_("Could not apply '%s'"), file);
334
335 unlink(file);
336 free(file);
337 return 0;
338}
339
340static struct lock_file lock_file;
341
342static const char ignore_error[] =
343N_("The following paths are ignored by one of your .gitignore files:\n");
344
345static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
346static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
347
348static struct option builtin_add_options[] = {
349 OPT__DRY_RUN(&show_only, N_("dry run")),
350 OPT__VERBOSE(&verbose, N_("be verbose")),
351 OPT_GROUP(""),
352 OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
353 OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
354 OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
355 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
356 OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
357 OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
358 OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
359 OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
360 OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
361 OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
362 OPT_END(),
363};
364
365static int add_config(const char *var, const char *value, void *cb)
366{
367 if (!strcmp(var, "add.ignoreerrors") ||
368 !strcmp(var, "add.ignore-errors")) {
369 ignore_add_errors = git_config_bool(var, value);
370 return 0;
371 }
372 return git_default_config(var, value, cb);
373}
374
375static int add_files(struct dir_struct *dir, int flags)
376{
377 int i, exit_status = 0;
378
379 if (dir->ignored_nr) {
380 fprintf(stderr, _(ignore_error));
381 for (i = 0; i < dir->ignored_nr; i++)
382 fprintf(stderr, "%s\n", dir->ignored[i]->name);
383 fprintf(stderr, _("Use -f if you really want to add them.\n"));
384 die(_("no files added"));
385 }
386
387 for (i = 0; i < dir->nr; i++)
388 if (add_file_to_cache(dir->entries[i]->name, flags)) {
389 if (!ignore_add_errors)
390 die(_("adding files failed"));
391 exit_status = 1;
392 }
393 return exit_status;
394}
395
396int cmd_add(int argc, const char **argv, const char *prefix)
397{
398 int exit_status = 0;
399 int newfd;
400 const char **pathspec;
401 struct dir_struct dir;
402 int flags;
403 int add_new_files;
404 int require_pathspec;
405 char *seen = NULL;
406 int implicit_dot = 0;
407
408 git_config(add_config, NULL);
409
410 argc = parse_options(argc, argv, prefix, builtin_add_options,
411 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
412 if (patch_interactive)
413 add_interactive = 1;
414 if (add_interactive)
415 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
416
417 if (edit_interactive)
418 return(edit_patch(argc, argv, prefix));
419 argc--;
420 argv++;
421
422 if (addremove && take_worktree_changes)
423 die(_("-A and -u are mutually incompatible"));
424 if (!show_only && ignore_missing)
425 die(_("Option --ignore-missing can only be used together with --dry-run"));
426 if (addremove) {
427 option_with_implicit_dot = "--all";
428 short_option_with_implicit_dot = "-A";
429 }
430 if (take_worktree_changes) {
431 option_with_implicit_dot = "--update";
432 short_option_with_implicit_dot = "-u";
433 }
434 if (option_with_implicit_dot && !argc) {
435 static const char *here[2] = { ".", NULL };
436 if (prefix && addremove)
437 warn_pathless_add();
438 argc = 1;
439 argv = here;
440 implicit_dot = 1;
441 }
442
443 add_new_files = !take_worktree_changes && !refresh_only;
444 require_pathspec = !take_worktree_changes;
445
446 newfd = hold_locked_index(&lock_file, 1);
447
448 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
449 (show_only ? ADD_CACHE_PRETEND : 0) |
450 (intent_to_add ? ADD_CACHE_INTENT : 0) |
451 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
452 (!(addremove || take_worktree_changes)
453 ? ADD_CACHE_IGNORE_REMOVAL : 0)) |
454 (implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0);
455
456 if (require_pathspec && argc == 0) {
457 fprintf(stderr, _("Nothing specified, nothing added.\n"));
458 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
459 return 0;
460 }
461 pathspec = validate_pathspec(argv, prefix);
462
463 if (read_cache() < 0)
464 die(_("index file corrupt"));
465 treat_gitlinks(pathspec);
466
467 if (add_new_files) {
468 int baselen;
469
470 /* Set up the default git porcelain excludes */
471 memset(&dir, 0, sizeof(dir));
472 if (!ignored_too) {
473 dir.flags |= DIR_COLLECT_IGNORED;
474 setup_standard_excludes(&dir);
475 }
476
477 /* This picks up the paths that are not tracked */
478 baselen = fill_directory(&dir, pathspec);
479 if (pathspec)
480 seen = prune_directory(&dir, pathspec, baselen);
481 }
482
483 if (refresh_only) {
484 refresh(verbose, pathspec);
485 goto finish;
486 }
487
488 if (pathspec) {
489 int i;
490 struct path_exclude_check check;
491
492 path_exclude_check_init(&check, &dir);
493 if (!seen)
494 seen = find_pathspecs_matching_against_index(pathspec);
495 for (i = 0; pathspec[i]; i++) {
496 if (!seen[i] && pathspec[i][0]
497 && !file_exists(pathspec[i])) {
498 if (ignore_missing) {
499 int dtype = DT_UNKNOWN;
500 if (is_path_excluded(&check, pathspec[i], -1, &dtype))
501 dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
502 } else
503 die(_("pathspec '%s' did not match any files"),
504 pathspec[i]);
505 }
506 }
507 free(seen);
508 path_exclude_check_clear(&check);
509 }
510
511 plug_bulk_checkin();
512
513 exit_status |= add_files_to_cache(prefix, pathspec, flags);
514
515 if (add_new_files)
516 exit_status |= add_files(&dir, flags);
517
518 unplug_bulk_checkin();
519
520 finish:
521 if (active_cache_changed) {
522 if (write_cache(newfd, active_cache, active_nr) ||
523 commit_locked_index(&lock_file))
524 die(_("Unable to write new index file"));
525 }
526
527 return exit_status;
528}