add: make pathless 'add [-u|-A]' warning a file-global function
[git.git] / builtin / add.c
bloba4028eea9ee013559c9bbe2fd0b248874af23c8c
1 /*
2 * "git add" builtin command
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"
19 static const char * const builtin_add_usage[] = {
20 N_("git add [options] [--] <pathspec>..."),
21 NULL
23 static int patch_interactive, add_interactive, edit_interactive;
24 static int take_worktree_changes;
26 struct update_callback_data {
27 int flags;
28 int add_errors;
31 static const char *option_with_implicit_dot;
32 static const char *short_option_with_implicit_dot;
34 static void warn_pathless_add(void)
36 assert(option_with_implicit_dot && short_option_with_implicit_dot);
39 * To be consistent with "git add -p" and most Git
40 * commands, we should default to being tree-wide, but
41 * this is not the original behavior and can't be
42 * changed until users trained themselves not to type
43 * "git add -u" or "git add -A". For now, we warn and
44 * keep the old behavior. Later, the behavior can be changed
45 * to tree-wide, keeping the warning for a while, and
46 * eventually we can drop the warning.
48 warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
49 "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
50 "To add content for the whole tree, run:\n"
51 "\n"
52 " git add %s :/\n"
53 " (or git add %s :/)\n"
54 "\n"
55 "To restrict the command to the current directory, run:\n"
56 "\n"
57 " git add %s .\n"
58 " (or git add %s .)\n"
59 "\n"
60 "With the current Git version, the command is restricted to the current directory."),
61 option_with_implicit_dot, short_option_with_implicit_dot,
62 option_with_implicit_dot, short_option_with_implicit_dot,
63 option_with_implicit_dot, short_option_with_implicit_dot);
66 static int fix_unmerged_status(struct diff_filepair *p,
67 struct update_callback_data *data)
69 if (p->status != DIFF_STATUS_UNMERGED)
70 return p->status;
71 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
73 * This is not an explicit add request, and the
74 * path is missing from the working tree (deleted)
76 return DIFF_STATUS_DELETED;
77 else
79 * Either an explicit add request, or path exists
80 * in the working tree. An attempt to explicitly
81 * add a path that does not exist in the working tree
82 * will be caught as an error by the caller immediately.
84 return DIFF_STATUS_MODIFIED;
87 static void update_callback(struct diff_queue_struct *q,
88 struct diff_options *opt, void *cbdata)
90 int i;
91 struct update_callback_data *data = cbdata;
93 for (i = 0; i < q->nr; i++) {
94 struct diff_filepair *p = q->queue[i];
95 const char *path = p->one->path;
96 switch (fix_unmerged_status(p, data)) {
97 default:
98 die(_("unexpected diff status %c"), p->status);
99 case DIFF_STATUS_MODIFIED:
100 case DIFF_STATUS_TYPE_CHANGED:
101 if (add_file_to_index(&the_index, path, data->flags)) {
102 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
103 die(_("updating files failed"));
104 data->add_errors++;
106 break;
107 case DIFF_STATUS_DELETED:
108 if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
109 break;
110 if (!(data->flags & ADD_CACHE_PRETEND))
111 remove_file_from_index(&the_index, path);
112 if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
113 printf(_("remove '%s'\n"), path);
114 break;
119 int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
121 struct update_callback_data data;
122 struct rev_info rev;
123 init_revisions(&rev, prefix);
124 setup_revisions(0, NULL, &rev, NULL);
125 init_pathspec(&rev.prune_data, pathspec);
126 rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
127 rev.diffopt.format_callback = update_callback;
128 data.flags = flags;
129 data.add_errors = 0;
130 rev.diffopt.format_callback_data = &data;
131 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
132 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
133 return !!data.add_errors;
136 static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
138 char *seen;
139 int i, specs;
140 struct dir_entry **src, **dst;
142 for (specs = 0; pathspec[specs]; specs++)
143 /* nothing */;
144 seen = xcalloc(specs, 1);
146 src = dst = dir->entries;
147 i = dir->nr;
148 while (--i >= 0) {
149 struct dir_entry *entry = *src++;
150 if (match_pathspec(pathspec, entry->name, entry->len,
151 prefix, seen))
152 *dst++ = entry;
154 dir->nr = dst - dir->entries;
155 add_pathspec_matches_against_index(pathspec, seen, specs);
156 return seen;
160 * Checks the index to see whether any path in pathspec refers to
161 * something inside a submodule. If so, dies with an error message.
163 static void treat_gitlinks(const char **pathspec)
165 int i;
167 if (!pathspec || !*pathspec)
168 return;
170 for (i = 0; pathspec[i]; i++)
171 pathspec[i] = check_path_for_gitlink(pathspec[i]);
174 static void refresh(int verbose, const char **pathspec)
176 char *seen;
177 int i, specs;
179 for (specs = 0; pathspec[specs]; specs++)
180 /* nothing */;
181 seen = xcalloc(specs, 1);
182 refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
183 pathspec, seen, _("Unstaged changes after refreshing the index:"));
184 for (i = 0; i < specs; i++) {
185 if (!seen[i])
186 die(_("pathspec '%s' did not match any files"), pathspec[i]);
188 free(seen);
192 * Normalizes argv relative to prefix, via get_pathspec(), and then
193 * runs die_if_path_beyond_symlink() on each path in the normalized
194 * list.
196 static const char **validate_pathspec(const char **argv, const char *prefix)
198 const char **pathspec = get_pathspec(prefix, argv);
200 if (pathspec) {
201 const char **p;
202 for (p = pathspec; *p; p++) {
203 die_if_path_beyond_symlink(*p, prefix);
207 return pathspec;
210 int run_add_interactive(const char *revision, const char *patch_mode,
211 const char **pathspec)
213 int status, ac, pc = 0;
214 const char **args;
216 if (pathspec)
217 while (pathspec[pc])
218 pc++;
220 args = xcalloc(sizeof(const char *), (pc + 5));
221 ac = 0;
222 args[ac++] = "add--interactive";
223 if (patch_mode)
224 args[ac++] = patch_mode;
225 if (revision)
226 args[ac++] = revision;
227 args[ac++] = "--";
228 if (pc) {
229 memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
230 ac += pc;
232 args[ac] = NULL;
234 status = run_command_v_opt(args, RUN_GIT_CMD);
235 free(args);
236 return status;
239 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
241 const char **pathspec = NULL;
243 if (argc) {
244 pathspec = validate_pathspec(argv, prefix);
245 if (!pathspec)
246 return -1;
249 return run_add_interactive(NULL,
250 patch ? "--patch" : NULL,
251 pathspec);
254 static int edit_patch(int argc, const char **argv, const char *prefix)
256 char *file = git_pathdup("ADD_EDIT.patch");
257 const char *apply_argv[] = { "apply", "--recount", "--cached",
258 NULL, NULL };
259 struct child_process child;
260 struct rev_info rev;
261 int out;
262 struct stat st;
264 apply_argv[3] = file;
266 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
268 if (read_cache() < 0)
269 die (_("Could not read the index"));
271 init_revisions(&rev, prefix);
272 rev.diffopt.context = 7;
274 argc = setup_revisions(argc, argv, &rev, NULL);
275 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
276 DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
277 out = open(file, O_CREAT | O_WRONLY, 0666);
278 if (out < 0)
279 die (_("Could not open '%s' for writing."), file);
280 rev.diffopt.file = xfdopen(out, "w");
281 rev.diffopt.close_file = 1;
282 if (run_diff_files(&rev, 0))
283 die (_("Could not write patch"));
285 launch_editor(file, NULL, NULL);
287 if (stat(file, &st))
288 die_errno(_("Could not stat '%s'"), file);
289 if (!st.st_size)
290 die(_("Empty patch. Aborted."));
292 memset(&child, 0, sizeof(child));
293 child.git_cmd = 1;
294 child.argv = apply_argv;
295 if (run_command(&child))
296 die (_("Could not apply '%s'"), file);
298 unlink(file);
299 free(file);
300 return 0;
303 static struct lock_file lock_file;
305 static const char ignore_error[] =
306 N_("The following paths are ignored by one of your .gitignore files:\n");
308 static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
309 static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
311 static struct option builtin_add_options[] = {
312 OPT__DRY_RUN(&show_only, N_("dry run")),
313 OPT__VERBOSE(&verbose, N_("be verbose")),
314 OPT_GROUP(""),
315 OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
316 OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
317 OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
318 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
319 OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
320 OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
321 OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
322 OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
323 OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
324 OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
325 OPT_END(),
328 static int add_config(const char *var, const char *value, void *cb)
330 if (!strcmp(var, "add.ignoreerrors") ||
331 !strcmp(var, "add.ignore-errors")) {
332 ignore_add_errors = git_config_bool(var, value);
333 return 0;
335 return git_default_config(var, value, cb);
338 static int add_files(struct dir_struct *dir, int flags)
340 int i, exit_status = 0;
342 if (dir->ignored_nr) {
343 fprintf(stderr, _(ignore_error));
344 for (i = 0; i < dir->ignored_nr; i++)
345 fprintf(stderr, "%s\n", dir->ignored[i]->name);
346 fprintf(stderr, _("Use -f if you really want to add them.\n"));
347 die(_("no files added"));
350 for (i = 0; i < dir->nr; i++)
351 if (add_file_to_cache(dir->entries[i]->name, flags)) {
352 if (!ignore_add_errors)
353 die(_("adding files failed"));
354 exit_status = 1;
356 return exit_status;
359 int cmd_add(int argc, const char **argv, const char *prefix)
361 int exit_status = 0;
362 int newfd;
363 const char **pathspec;
364 struct dir_struct dir;
365 int flags;
366 int add_new_files;
367 int require_pathspec;
368 char *seen = NULL;
370 git_config(add_config, NULL);
372 argc = parse_options(argc, argv, prefix, builtin_add_options,
373 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
374 if (patch_interactive)
375 add_interactive = 1;
376 if (add_interactive)
377 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
379 if (edit_interactive)
380 return(edit_patch(argc, argv, prefix));
381 argc--;
382 argv++;
384 if (addremove && take_worktree_changes)
385 die(_("-A and -u are mutually incompatible"));
386 if (!show_only && ignore_missing)
387 die(_("Option --ignore-missing can only be used together with --dry-run"));
388 if (addremove) {
389 option_with_implicit_dot = "--all";
390 short_option_with_implicit_dot = "-A";
392 if (take_worktree_changes) {
393 option_with_implicit_dot = "--update";
394 short_option_with_implicit_dot = "-u";
396 if (option_with_implicit_dot && !argc) {
397 static const char *here[2] = { ".", NULL };
398 if (prefix)
399 warn_pathless_add();
400 argc = 1;
401 argv = here;
404 add_new_files = !take_worktree_changes && !refresh_only;
405 require_pathspec = !take_worktree_changes;
407 newfd = hold_locked_index(&lock_file, 1);
409 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
410 (show_only ? ADD_CACHE_PRETEND : 0) |
411 (intent_to_add ? ADD_CACHE_INTENT : 0) |
412 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
413 (!(addremove || take_worktree_changes)
414 ? ADD_CACHE_IGNORE_REMOVAL : 0));
416 if (require_pathspec && argc == 0) {
417 fprintf(stderr, _("Nothing specified, nothing added.\n"));
418 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
419 return 0;
421 pathspec = validate_pathspec(argv, prefix);
423 if (read_cache() < 0)
424 die(_("index file corrupt"));
425 treat_gitlinks(pathspec);
427 if (add_new_files) {
428 int baselen;
430 /* Set up the default git porcelain excludes */
431 memset(&dir, 0, sizeof(dir));
432 if (!ignored_too) {
433 dir.flags |= DIR_COLLECT_IGNORED;
434 setup_standard_excludes(&dir);
437 /* This picks up the paths that are not tracked */
438 baselen = fill_directory(&dir, pathspec);
439 if (pathspec)
440 seen = prune_directory(&dir, pathspec, baselen);
443 if (refresh_only) {
444 refresh(verbose, pathspec);
445 goto finish;
448 if (pathspec) {
449 int i;
450 struct path_exclude_check check;
452 path_exclude_check_init(&check, &dir);
453 if (!seen)
454 seen = find_pathspecs_matching_against_index(pathspec);
455 for (i = 0; pathspec[i]; i++) {
456 if (!seen[i] && pathspec[i][0]
457 && !file_exists(pathspec[i])) {
458 if (ignore_missing) {
459 int dtype = DT_UNKNOWN;
460 if (is_path_excluded(&check, pathspec[i], -1, &dtype))
461 dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
462 } else
463 die(_("pathspec '%s' did not match any files"),
464 pathspec[i]);
467 free(seen);
468 path_exclude_check_clear(&check);
471 plug_bulk_checkin();
473 exit_status |= add_files_to_cache(prefix, pathspec, flags);
475 if (add_new_files)
476 exit_status |= add_files(&dir, flags);
478 unplug_bulk_checkin();
480 finish:
481 if (active_cache_changed) {
482 if (write_cache(newfd, active_cache, active_nr) ||
483 commit_locked_index(&lock_file))
484 die(_("Unable to write new index file"));
487 return exit_status;