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