blob: ab1c9e8fb7a0f7c6f60cc78ff0f345838210459a [file] [log] [blame]
Linus Torvalds0d781532006-05-17 09:33:32 -07001/*
2 * "git add" builtin command
3 *
4 * Copyright (C) 2006 Linus Torvalds
5 */
Linus Torvalds0d781532006-05-17 09:33:32 -07006#include "cache.h"
7#include "builtin.h"
8#include "dir.h"
Adam Spiers6f525e72013-01-06 16:58:08 +00009#include "pathspec.h"
Junio C Hamano5cde71d2006-12-10 20:55:50 -080010#include "exec_cmd.h"
Junio C Hamano93872e02006-05-20 01:28:49 -070011#include "cache-tree.h"
Kristian Høgsberg58680162007-09-17 20:06:44 -040012#include "run-command.h"
Kristian Høgsberg5c46f752007-10-03 17:45:02 -040013#include "parse-options.h"
Johannes Schindelinc59cb032009-04-08 23:30:24 +020014#include "diff.h"
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080015#include "diffcore.h"
Johannes Schindelinc59cb032009-04-08 23:30:24 +020016#include "revision.h"
Junio C Hamano568508e2011-10-28 14:48:40 -070017#include "bulk-checkin.h"
Linus Torvalds0d781532006-05-17 09:33:32 -070018
Kristian Høgsberg5c46f752007-10-03 17:45:02 -040019static const char * const builtin_add_usage[] = {
Matthieu Moyd32805d2013-02-12 10:24:44 +010020 N_("git add [options] [--] <pathspec>..."),
Kristian Høgsberg5c46f752007-10-03 17:45:02 -040021 NULL
22};
Johannes Schindelinc59cb032009-04-08 23:30:24 +020023static int patch_interactive, add_interactive, edit_interactive;
Jeff King93c44d42007-05-12 02:42:00 -040024static int take_worktree_changes;
James Bowes896bdfa2007-02-27 22:31:10 -050025
Jonathan Nieder9cba13c2011-03-16 02:08:34 -050026struct update_callback_data {
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080027 int flags;
28 int add_errors;
29};
30
Junio C Hamano75973b22011-04-20 18:11:19 -070031static 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
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080052static 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;
Junio C Hamano75973b22011-04-20 18:11:19 -070061 switch (fix_unmerged_status(p, data)) {
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080062 default:
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +000063 die(_("unexpected diff status %c"), p->status);
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080064 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))
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +000068 die(_("updating files failed"));
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080069 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))
Ævar Arnfjörð Bjarmason475c73e2011-02-22 23:41:32 +000078 printf(_("remove '%s'\n"), path);
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080079 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);
Nguyễn Thái Ngọc Duyafe069d2010-12-17 19:43:06 +070090 init_pathspec(&rev.prune_data, pathspec);
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080091 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;
Junio C Hamano75973b22011-04-20 18:11:19 -070096 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
Linus Torvaldsfb7d3f32010-01-21 11:37:38 -080097 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
98 return !!data.add_errors;
99}
100
Junio C Hamano81f45e72010-02-09 17:30:49 -0500101static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
Linus Torvalds0d781532006-05-17 09:33:32 -0700102{
Linus Torvaldsf2593392006-05-17 13:23:19 -0700103 char *seen;
104 int i, specs;
Linus Torvalds0d781532006-05-17 09:33:32 -0700105 struct dir_entry **src, **dst;
106
Linus Torvaldsf2593392006-05-17 13:23:19 -0700107 for (specs = 0; pathspec[specs]; specs++)
108 /* nothing */;
Peter Eriksen28f75812006-07-25 09:30:18 +0200109 seen = xcalloc(specs, 1);
Linus Torvaldsf2593392006-05-17 13:23:19 -0700110
Linus Torvalds0d781532006-05-17 09:33:32 -0700111 src = dst = dir->entries;
112 i = dir->nr;
113 while (--i >= 0) {
114 struct dir_entry *entry = *src++;
Junio C Hamano4d06f8a2006-12-29 11:01:31 -0800115 if (match_pathspec(pathspec, entry->name, entry->len,
116 prefix, seen))
117 *dst++ = entry;
Linus Torvalds0d781532006-05-17 09:33:32 -0700118 }
119 dir->nr = dst - dir->entries;
Adam Spiers4b78d7b2013-01-06 16:58:09 +0000120 add_pathspec_matches_against_index(pathspec, seen, specs);
Junio C Hamano81f45e72010-02-09 17:30:49 -0500121 return seen;
Linus Torvalds0d781532006-05-17 09:33:32 -0700122}
123
Adam Spiers9d67b612013-01-06 16:58:10 +0000124/*
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 */
Johannes Schindelin2ce53f92009-01-02 19:08:40 +0100128static void treat_gitlinks(const char **pathspec)
129{
130 int i;
131
132 if (!pathspec || !*pathspec)
133 return;
134
Adam Spiers9d67b612013-01-06 16:58:10 +0000135 for (i = 0; pathspec[i]; i++)
136 pathspec[i] = check_path_for_gitlink(pathspec[i]);
Johannes Schindelin2ce53f92009-01-02 19:08:40 +0100137}
138
Alexandre Julliardd6168132007-08-11 23:59:01 +0200139static 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);
Matthieu Moy43673fd2009-08-21 10:57:58 +0200147 refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
Ævar Arnfjörð Bjarmasoned2a8082011-02-22 23:41:33 +0000148 pathspec, seen, _("Unstaged changes after refreshing the index:"));
Alexandre Julliardd6168132007-08-11 23:59:01 +0200149 for (i = 0; i < specs; i++) {
150 if (!seen[i])
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000151 die(_("pathspec '%s' did not match any files"), pathspec[i]);
Alexandre Julliardd6168132007-08-11 23:59:01 +0200152 }
Benoit Sigoure399f0a82007-10-29 08:00:33 +0100153 free(seen);
Alexandre Julliardd6168132007-08-11 23:59:01 +0200154}
155
Adam Spiers512aaf92013-01-06 16:58:11 +0000156/*
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 */
Adam Spiersf8a11132013-01-06 16:58:07 +0000161static const char **validate_pathspec(const char **argv, const char *prefix)
Junio C Hamano3f061882007-11-25 10:10:10 -0800162{
163 const char **pathspec = get_pathspec(prefix, argv);
164
Junio C Hamano725b0602008-08-04 00:52:37 -0700165 if (pathspec) {
166 const char **p;
167 for (p = pathspec; *p; p++) {
Adam Spiers512aaf92013-01-06 16:58:11 +0000168 die_if_path_beyond_symlink(*p, prefix);
Junio C Hamano725b0602008-08-04 00:52:37 -0700169 }
170 }
171
Junio C Hamano3f061882007-11-25 10:10:10 -0800172 return pathspec;
173}
174
Thomas Rast46b51392009-08-13 14:29:41 +0200175int run_add_interactive(const char *revision, const char *patch_mode,
176 const char **pathspec)
177{
178 int status, ac, pc = 0;
179 const char **args;
180
181 if (pathspec)
182 while (pathspec[pc])
183 pc++;
184
185 args = xcalloc(sizeof(const char *), (pc + 5));
186 ac = 0;
187 args[ac++] = "add--interactive";
188 if (patch_mode)
189 args[ac++] = patch_mode;
190 if (revision)
191 args[ac++] = revision;
192 args[ac++] = "--";
193 if (pc) {
194 memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
195 ac += pc;
196 }
197 args[ac] = NULL;
198
199 status = run_command_v_opt(args, RUN_GIT_CMD);
200 free(args);
201 return status;
202}
203
Conrad Irwinb4bd4662011-05-07 10:58:07 -0700204int interactive_add(int argc, const char **argv, const char *prefix, int patch)
Kristian Høgsberg58680162007-09-17 20:06:44 -0400205{
Junio C Hamano3f061882007-11-25 10:10:10 -0800206 const char **pathspec = NULL;
Junio C Hamano324ccbd2007-11-25 10:07:55 -0800207
Junio C Hamano3f061882007-11-25 10:10:10 -0800208 if (argc) {
Adam Spiersf8a11132013-01-06 16:58:07 +0000209 pathspec = validate_pathspec(argv, prefix);
Junio C Hamano3f061882007-11-25 10:10:10 -0800210 if (!pathspec)
211 return -1;
212 }
213
Thomas Rast46b51392009-08-13 14:29:41 +0200214 return run_add_interactive(NULL,
Conrad Irwinb4bd4662011-05-07 10:58:07 -0700215 patch ? "--patch" : NULL,
Thomas Rast46b51392009-08-13 14:29:41 +0200216 pathspec);
Kristian Høgsberg58680162007-09-17 20:06:44 -0400217}
218
Linus Torvalds2af202b2009-06-18 10:28:43 -0700219static int edit_patch(int argc, const char **argv, const char *prefix)
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200220{
Ramsay Jonesd292bfa2012-09-04 18:30:21 +0100221 char *file = git_pathdup("ADD_EDIT.patch");
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200222 const char *apply_argv[] = { "apply", "--recount", "--cached",
Gary V. Vaughan66dbfd52010-05-14 09:31:33 +0000223 NULL, NULL };
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200224 struct child_process child;
225 struct rev_info rev;
226 int out;
227 struct stat st;
228
Gary V. Vaughan66dbfd52010-05-14 09:31:33 +0000229 apply_argv[3] = file;
230
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200231 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
232
233 if (read_cache() < 0)
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000234 die (_("Could not read the index"));
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200235
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;
Johannes Schindelin701825d2012-02-07 05:05:48 +0100241 DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
Jeff King6ff2b722012-07-10 02:37:22 -0400242 out = open(file, O_CREAT | O_WRONLY, 0666);
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200243 if (out < 0)
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000244 die (_("Could not open '%s' for writing."), file);
Jim Meyering41698372009-09-12 10:43:27 +0200245 rev.diffopt.file = xfdopen(out, "w");
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200246 rev.diffopt.close_file = 1;
247 if (run_diff_files(&rev, 0))
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000248 die (_("Could not write patch"));
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200249
250 launch_editor(file, NULL, NULL);
251
252 if (stat(file, &st))
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000253 die_errno(_("Could not stat '%s'"), file);
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200254 if (!st.st_size)
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000255 die(_("Empty patch. Aborted."));
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200256
257 memset(&child, 0, sizeof(child));
258 child.git_cmd = 1;
259 child.argv = apply_argv;
260 if (run_command(&child))
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000261 die (_("Could not apply '%s'"), file);
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200262
263 unlink(file);
Ramsay Jonesd292bfa2012-09-04 18:30:21 +0100264 free(file);
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200265 return 0;
266}
267
Junio C Hamano021b6e42006-06-06 12:51:49 -0700268static struct lock_file lock_file;
Linus Torvalds0d781532006-05-17 09:33:32 -0700269
Petr Baudisb39c53e2007-08-29 00:41:23 +0200270static const char ignore_error[] =
Ævar Arnfjörð Bjarmason439fb822011-02-22 23:41:30 +0000271N_("The following paths are ignored by one of your .gitignore files:\n");
Junio C Hamano6a1ad322006-12-25 17:46:38 -0800272
Kristian Høgsberg5c46f752007-10-03 17:45:02 -0400273static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
Jens Lehmann108da0d2010-07-10 00:18:38 +0200274static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
Kristian Høgsberg5c46f752007-10-03 17:45:02 -0400275
276static struct option builtin_add_options[] = {
Nguyễn Thái Ngọc Duy1b560242012-08-20 19:31:52 +0700277 OPT__DRY_RUN(&show_only, N_("dry run")),
278 OPT__VERBOSE(&verbose, N_("be verbose")),
Kristian Høgsberg5c46f752007-10-03 17:45:02 -0400279 OPT_GROUP(""),
Nguyễn Thái Ngọc Duy1b560242012-08-20 19:31:52 +0700280 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")),
Kristian Høgsberg5c46f752007-10-03 17:45:02 -0400290 OPT_END(),
291};
292
Junio C Hamano9bd81e42008-05-25 14:25:02 -0700293static int add_config(const char *var, const char *value, void *cb)
Alex Riesendad25e42008-05-12 19:59:23 +0200294{
Jonathan Nieder8c2be752011-05-14 15:19:21 -0500295 if (!strcmp(var, "add.ignoreerrors") ||
296 !strcmp(var, "add.ignore-errors")) {
Alex Riesendad25e42008-05-12 19:59:23 +0200297 ignore_add_errors = git_config_bool(var, value);
298 return 0;
299 }
Junio C Hamano9bd81e42008-05-25 14:25:02 -0700300 return git_default_config(var, value, cb);
Alex Riesendad25e42008-05-12 19:59:23 +0200301}
302
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700303static int add_files(struct dir_struct *dir, int flags)
304{
305 int i, exit_status = 0;
306
307 if (dir->ignored_nr) {
Ævar Arnfjörð Bjarmason439fb822011-02-22 23:41:30 +0000308 fprintf(stderr, _(ignore_error));
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700309 for (i = 0; i < dir->ignored_nr; i++)
310 fprintf(stderr, "%s\n", dir->ignored[i]->name);
Ævar Arnfjörð Bjarmason439fb822011-02-22 23:41:30 +0000311 fprintf(stderr, _("Use -f if you really want to add them.\n"));
312 die(_("no files added"));
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700313 }
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)
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000318 die(_("adding files failed"));
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700319 exit_status = 1;
320 }
321 return exit_status;
322}
323
Matthieu Moy0fa2eb52013-01-28 10:16:33 +0100324static 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
Matthieu Moyc6898eb2013-03-11 09:01:32 +0100331 * 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.
Matthieu Moy0fa2eb52013-01-28 10:16:33 +0100334 */
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
Linus Torvaldsa633fca2006-07-28 22:44:25 -0700353int cmd_add(int argc, const char **argv, const char *prefix)
Linus Torvalds0d781532006-05-17 09:33:32 -0700354{
Alex Riesen7ae02a32008-05-12 19:58:10 +0200355 int exit_status = 0;
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700356 int newfd;
Linus Torvalds0d781532006-05-17 09:33:32 -0700357 const char **pathspec;
358 struct dir_struct dir;
Gustaf Hendeby205ffa92008-05-22 23:59:42 +0200359 int flags;
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700360 int add_new_files;
361 int require_pathspec;
Junio C Hamano81f45e72010-02-09 17:30:49 -0500362 char *seen = NULL;
Matthieu Moy0fa2eb52013-01-28 10:16:33 +0100363 const char *option_with_implicit_dot = NULL;
364 const char *short_option_with_implicit_dot = NULL;
Junio C Hamano5cde71d2006-12-10 20:55:50 -0800365
Stephen Boyded342fd2009-06-18 02:17:54 -0700366 git_config(add_config, NULL);
367
Stephen Boyd37782922009-05-23 11:53:12 -0700368 argc = parse_options(argc, argv, prefix, builtin_add_options,
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200369 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
Wincent Colaiutab63e9952007-11-25 14:15:42 +0100370 if (patch_interactive)
371 add_interactive = 1;
Wincent Colaiuta7c0ab442007-11-22 01:02:52 +0100372 if (add_interactive)
Conrad Irwinb4bd4662011-05-07 10:58:07 -0700373 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
Linus Torvalds0d781532006-05-17 09:33:32 -0700374
Johannes Schindelinc59cb032009-04-08 23:30:24 +0200375 if (edit_interactive)
376 return(edit_patch(argc, argv, prefix));
377 argc--;
378 argv++;
379
Junio C Hamano3ba1f112008-07-19 19:51:11 -0700380 if (addremove && take_worktree_changes)
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000381 die(_("-A and -u are mutually incompatible"));
Jens Lehmann108da0d2010-07-10 00:18:38 +0200382 if (!show_only && ignore_missing)
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000383 die(_("Option --ignore-missing can only be used together with --dry-run"));
Matthieu Moy0fa2eb52013-01-28 10:16:33 +0100384 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) {
Junio C Hamano3ba1f112008-07-19 19:51:11 -0700393 static const char *here[2] = { ".", NULL };
Matthieu Moy0fa2eb52013-01-28 10:16:33 +0100394 if (prefix)
395 warn_pathless_add(option_with_implicit_dot,
396 short_option_with_implicit_dot);
Junio C Hamano3ba1f112008-07-19 19:51:11 -0700397 argc = 1;
398 argv = here;
399 }
400
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700401 add_new_files = !take_worktree_changes && !refresh_only;
402 require_pathspec = !take_worktree_changes;
403
Junio C Hamano30ca07a2007-03-31 23:09:02 -0700404 newfd = hold_locked_index(&lock_file, 1);
Linus Torvalds0d781532006-05-17 09:33:32 -0700405
Gustaf Hendeby205ffa92008-05-22 23:59:42 +0200406 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
Junio C Hamano01665922008-05-25 14:03:50 -0700407 (show_only ? ADD_CACHE_PRETEND : 0) |
Junio C Hamano39425812008-08-21 01:44:53 -0700408 (intent_to_add ? ADD_CACHE_INTENT : 0) |
Junio C Hamano1e5f7642008-07-22 22:30:40 -0700409 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
410 (!(addremove || take_worktree_changes)
411 ? ADD_CACHE_IGNORE_REMOVAL : 0));
Gustaf Hendeby205ffa92008-05-22 23:59:42 +0200412
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700413 if (require_pathspec && argc == 0) {
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000414 fprintf(stderr, _("Nothing specified, nothing added.\n"));
415 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
Junio C Hamano93b0d862006-12-20 13:06:46 -0800416 return 0;
417 }
Adam Spiersf8a11132013-01-06 16:58:07 +0000418 pathspec = validate_pathspec(argv, prefix);
Linus Torvalds0d781532006-05-17 09:33:32 -0700419
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700420 if (read_cache() < 0)
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000421 die(_("index file corrupt"));
Johannes Schindelin2ce53f92009-01-02 19:08:40 +0100422 treat_gitlinks(pathspec);
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700423
Linus Torvalds1d8842d2009-05-14 13:22:36 -0700424 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
Junio C Hamano1e5f7642008-07-22 22:30:40 -0700434 /* This picks up the paths that are not tracked */
Linus Torvalds1d8842d2009-05-14 13:22:36 -0700435 baselen = fill_directory(&dir, pathspec);
436 if (pathspec)
Junio C Hamano81f45e72010-02-09 17:30:49 -0500437 seen = prune_directory(&dir, pathspec, baselen);
Linus Torvalds1d8842d2009-05-14 13:22:36 -0700438 }
Junio C Hamano1e5f7642008-07-22 22:30:40 -0700439
Alexandre Julliardd6168132007-08-11 23:59:01 +0200440 if (refresh_only) {
441 refresh(verbose, pathspec);
442 goto finish;
443 }
444
Junio C Hamano81f45e72010-02-09 17:30:49 -0500445 if (pathspec) {
446 int i;
Junio C Hamanoeb699342012-06-05 21:44:22 -0700447 struct path_exclude_check check;
448
449 path_exclude_check_init(&check, &dir);
Junio C Hamano81f45e72010-02-09 17:30:49 -0500450 if (!seen)
Adam Spiers4b78d7b2013-01-06 16:58:09 +0000451 seen = find_pathspecs_matching_against_index(pathspec);
Junio C Hamano81f45e72010-02-09 17:30:49 -0500452 for (i = 0; pathspec[i]; i++) {
453 if (!seen[i] && pathspec[i][0]
Jens Lehmann108da0d2010-07-10 00:18:38 +0200454 && !file_exists(pathspec[i])) {
455 if (ignore_missing) {
Nguyễn Thái Ngọc Duy0188f6b2010-11-11 20:03:22 +0700456 int dtype = DT_UNKNOWN;
Adam Spiers90130892012-12-27 02:32:23 +0000457 if (is_path_excluded(&check, pathspec[i], -1, &dtype))
Jens Lehmann108da0d2010-07-10 00:18:38 +0200458 dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
459 } else
Ævar Arnfjörð Bjarmason48168852011-02-22 23:41:31 +0000460 die(_("pathspec '%s' did not match any files"),
Jens Lehmann108da0d2010-07-10 00:18:38 +0200461 pathspec[i]);
462 }
Junio C Hamano81f45e72010-02-09 17:30:49 -0500463 }
464 free(seen);
Junio C Hamanoeb699342012-06-05 21:44:22 -0700465 path_exclude_check_clear(&check);
Junio C Hamano81f45e72010-02-09 17:30:49 -0500466 }
467
Junio C Hamano568508e2011-10-28 14:48:40 -0700468 plug_bulk_checkin();
469
Junio C Hamano1e5f7642008-07-22 22:30:40 -0700470 exit_status |= add_files_to_cache(prefix, pathspec, flags);
Linus Torvalds0d781532006-05-17 09:33:32 -0700471
Junio C Hamanoc972ec02008-07-19 19:22:25 -0700472 if (add_new_files)
473 exit_status |= add_files(&dir, flags);
Linus Torvalds0d781532006-05-17 09:33:32 -0700474
Junio C Hamano568508e2011-10-28 14:48:40 -0700475 unplug_bulk_checkin();
476
Junio C Hamanodfdac5d2007-04-20 01:39:39 -0700477 finish:
Linus Torvalds0d781532006-05-17 09:33:32 -0700478 if (active_cache_changed) {
479 if (write_cache(newfd, active_cache, active_nr) ||
Brandon Casey4ed7cd32008-01-16 13:12:46 -0600480 commit_locked_index(&lock_file))
Ævar Arnfjörð Bjarmason990ac4b2011-02-22 23:41:29 +0000481 die(_("Unable to write new index file"));
Linus Torvalds0d781532006-05-17 09:33:32 -0700482 }
483
Alex Riesen7ae02a32008-05-12 19:58:10 +0200484 return exit_status;
Linus Torvalds0d781532006-05-17 09:33:32 -0700485}