2 * "git add" builtin command
4 * Copyright (C) 2006 Linus Torvalds
6 #define USE_THE_INDEX_COMPATIBILITY_MACROS
14 #include "cache-tree.h"
15 #include "run-command.h"
16 #include "parse-options.h"
20 #include "bulk-checkin.h"
21 #include "argv-array.h"
22 #include "submodule.h"
23 #include "add-interactive.h"
25 static const char * const builtin_add_usage[] = {
26 N_("git add [<options>] [--] <pathspec>..."),
29 static int patch_interactive, add_interactive, edit_interactive;
30 static int take_worktree_changes;
31 static int add_renormalize;
33 struct update_callback_data {
38 static void chmod_pathspec(struct pathspec *pathspec, char flip)
42 for (i = 0; i < active_nr; i++) {
43 struct cache_entry *ce = active_cache[i];
45 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
48 if (chmod_cache_entry(ce, flip) < 0)
49 fprintf(stderr, "cannot chmod %cx '%s'\n", flip, ce->name);
53 static int fix_unmerged_status(struct diff_filepair *p,
54 struct update_callback_data *data)
56 if (p->status != DIFF_STATUS_UNMERGED)
58 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
60 * This is not an explicit add request, and the
61 * path is missing from the working tree (deleted)
63 return DIFF_STATUS_DELETED;
66 * Either an explicit add request, or path exists
67 * in the working tree. An attempt to explicitly
68 * add a path that does not exist in the working tree
69 * will be caught as an error by the caller immediately.
71 return DIFF_STATUS_MODIFIED;
74 static void update_callback(struct diff_queue_struct *q,
75 struct diff_options *opt, void *cbdata)
78 struct update_callback_data *data = cbdata;
80 for (i = 0; i < q->nr; i++) {
81 struct diff_filepair *p = q->queue[i];
82 const char *path = p->one->path;
83 switch (fix_unmerged_status(p, data)) {
85 die(_("unexpected diff status %c"), p->status);
86 case DIFF_STATUS_MODIFIED:
87 case DIFF_STATUS_TYPE_CHANGED:
88 if (add_file_to_index(&the_index, path, data->flags)) {
89 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
90 die(_("updating files failed"));
94 case DIFF_STATUS_DELETED:
95 if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
97 if (!(data->flags & ADD_CACHE_PRETEND))
98 remove_file_from_index(&the_index, path);
99 if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
100 printf(_("remove '%s'\n"), path);
106 int add_files_to_cache(const char *prefix,
107 const struct pathspec *pathspec, int flags)
109 struct update_callback_data data;
112 memset(&data, 0, sizeof(data));
115 repo_init_revisions(the_repository, &rev, prefix);
116 setup_revisions(0, NULL, &rev, NULL);
118 copy_pathspec(&rev.prune_data, pathspec);
119 rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
120 rev.diffopt.format_callback = update_callback;
121 rev.diffopt.format_callback_data = &data;
122 rev.diffopt.flags.override_submodule_config = 1;
123 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
124 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
125 clear_pathspec(&rev.prune_data);
126 return !!data.add_errors;
129 static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
133 for (i = 0; i < active_nr; i++) {
134 struct cache_entry *ce = active_cache[i];
137 continue; /* do not touch unmerged paths */
138 if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
139 continue; /* do not touch non blobs */
140 if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
142 retval |= add_file_to_cache(ce->name, flags | ADD_CACHE_RENORMALIZE);
148 static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
152 struct dir_entry **src, **dst;
154 seen = xcalloc(pathspec->nr, 1);
156 src = dst = dir->entries;
159 struct dir_entry *entry = *src++;
160 if (dir_path_match(&the_index, entry, pathspec, prefix, seen))
163 dir->nr = dst - dir->entries;
164 add_pathspec_matches_against_index(pathspec, &the_index, seen);
168 static void refresh(int verbose, const struct pathspec *pathspec)
173 seen = xcalloc(pathspec->nr, 1);
174 refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
175 pathspec, seen, _("Unstaged changes after refreshing the index:"));
176 for (i = 0; i < pathspec->nr; i++) {
178 die(_("pathspec '%s' did not match any files"),
179 pathspec->items[i].match);
184 int run_add_interactive(const char *revision, const char *patch_mode,
185 const struct pathspec *pathspec)
188 struct argv_array argv = ARGV_ARRAY_INIT;
189 int use_builtin_add_i =
190 git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
192 if (use_builtin_add_i < 0)
193 git_config_get_bool("add.interactive.usebuiltin",
196 if (use_builtin_add_i == 1) {
197 enum add_p_mode mode;
200 return !!run_add_i(the_repository, pathspec);
202 if (!strcmp(patch_mode, "--patch"))
204 else if (!strcmp(patch_mode, "--patch=stash"))
206 else if (!strcmp(patch_mode, "--patch=reset"))
209 die("'%s' not yet supported in the built-in add -p",
212 return !!run_add_p(the_repository, mode, revision, pathspec);
215 argv_array_push(&argv, "add--interactive");
217 argv_array_push(&argv, patch_mode);
219 argv_array_push(&argv, revision);
220 argv_array_push(&argv, "--");
221 for (i = 0; i < pathspec->nr; i++)
222 /* pass original pathspec, to be re-parsed */
223 argv_array_push(&argv, pathspec->items[i].original);
225 status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
226 argv_array_clear(&argv);
230 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
232 struct pathspec pathspec;
234 parse_pathspec(&pathspec, 0,
235 PATHSPEC_PREFER_FULL |
236 PATHSPEC_SYMLINK_LEADING_PATH |
237 PATHSPEC_PREFIX_ORIGIN,
240 return run_add_interactive(NULL,
241 patch ? "--patch" : NULL,
245 static int edit_patch(int argc, const char **argv, const char *prefix)
247 char *file = git_pathdup("ADD_EDIT.patch");
248 const char *apply_argv[] = { "apply", "--recount", "--cached",
250 struct child_process child = CHILD_PROCESS_INIT;
255 apply_argv[3] = file;
257 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
259 if (read_cache() < 0)
260 die(_("Could not read the index"));
262 repo_init_revisions(the_repository, &rev, prefix);
263 rev.diffopt.context = 7;
265 argc = setup_revisions(argc, argv, &rev, NULL);
266 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
267 rev.diffopt.use_color = 0;
268 rev.diffopt.flags.ignore_dirty_submodules = 1;
269 out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
271 die(_("Could not open '%s' for writing."), file);
272 rev.diffopt.file = xfdopen(out, "w");
273 rev.diffopt.close_file = 1;
274 if (run_diff_files(&rev, 0))
275 die(_("Could not write patch"));
277 if (launch_editor(file, NULL, NULL))
278 die(_("editing patch failed"));
281 die_errno(_("Could not stat '%s'"), file);
283 die(_("Empty patch. Aborted."));
286 child.argv = apply_argv;
287 if (run_command(&child))
288 die(_("Could not apply '%s'"), file);
295 static const char ignore_error[] =
296 N_("The following paths are ignored by one of your .gitignore files:\n");
298 static int verbose, show_only, ignored_too, refresh_only;
299 static int ignore_add_errors, intent_to_add, ignore_missing;
300 static int warn_on_embedded_repo = 1;
302 #define ADDREMOVE_DEFAULT 1
303 static int addremove = ADDREMOVE_DEFAULT;
304 static int addremove_explicit = -1; /* unspecified */
306 static char *chmod_arg;
308 static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
310 /* if we are told to ignore, we are not adding removals */
311 *(int *)opt->value = !unset ? 0 : 1;
315 static struct option builtin_add_options[] = {
316 OPT__DRY_RUN(&show_only, N_("dry run")),
317 OPT__VERBOSE(&verbose, N_("be verbose")),
319 OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
320 OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
321 OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
322 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
323 OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
324 OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
325 OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
326 OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
327 { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
328 NULL /* takes no arguments */,
329 N_("ignore paths removed in the working tree (same as --no-all)"),
330 PARSE_OPT_NOARG, ignore_removal_cb },
331 OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
332 OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
333 OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
334 OPT_STRING(0, "chmod", &chmod_arg, "(+|-)x",
335 N_("override the executable bit of the listed files")),
336 OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
337 N_("warn when adding an embedded repository")),
341 static int add_config(const char *var, const char *value, void *cb)
343 if (!strcmp(var, "add.ignoreerrors") ||
344 !strcmp(var, "add.ignore-errors")) {
345 ignore_add_errors = git_config_bool(var, value);
349 return git_default_config(var, value, cb);
352 static const char embedded_advice[] = N_(
353 "You've added another git repository inside your current repository.\n"
354 "Clones of the outer repository will not contain the contents of\n"
355 "the embedded repository and will not know how to obtain it.\n"
356 "If you meant to add a submodule, use:\n"
358 " git submodule add <url> %s\n"
360 "If you added this path by mistake, you can remove it from the\n"
363 " git rm --cached %s\n"
365 "See \"git help submodule\" for more information."
368 static void check_embedded_repo(const char *path)
370 struct strbuf name = STRBUF_INIT;
372 if (!warn_on_embedded_repo)
374 if (!ends_with(path, "/"))
377 /* Drop trailing slash for aesthetics */
378 strbuf_addstr(&name, path);
379 strbuf_strip_suffix(&name, "/");
381 warning(_("adding embedded git repository: %s"), name.buf);
382 if (advice_add_embedded_repo) {
383 advise(embedded_advice, name.buf, name.buf);
384 /* there may be multiple entries; advise only once */
385 advice_add_embedded_repo = 0;
388 strbuf_release(&name);
391 static int add_files(struct dir_struct *dir, int flags)
393 int i, exit_status = 0;
395 if (dir->ignored_nr) {
396 fprintf(stderr, _(ignore_error));
397 for (i = 0; i < dir->ignored_nr; i++)
398 fprintf(stderr, "%s\n", dir->ignored[i]->name);
399 fprintf(stderr, _("Use -f if you really want to add them.\n"));
403 for (i = 0; i < dir->nr; i++) {
404 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
405 if (!ignore_add_errors)
406 die(_("adding files failed"));
409 check_embedded_repo(dir->entries[i]->name);
415 int cmd_add(int argc, const char **argv, const char *prefix)
418 struct pathspec pathspec;
419 struct dir_struct dir;
422 int require_pathspec;
424 struct lock_file lock_file = LOCK_INIT;
426 git_config(add_config, NULL);
428 argc = parse_options(argc, argv, prefix, builtin_add_options,
429 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
430 if (patch_interactive)
433 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
435 if (edit_interactive)
436 return(edit_patch(argc, argv, prefix));
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" */
445 if (addremove && take_worktree_changes)
446 die(_("-A and -u are mutually incompatible"));
448 if (!take_worktree_changes && addremove_explicit < 0 && argc)
449 /* Turn "git add pathspec..." to "git add -A pathspec..." */
452 if (!show_only && ignore_missing)
453 die(_("Option --ignore-missing can only be used together with --dry-run"));
455 if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
456 chmod_arg[1] != 'x' || chmod_arg[2]))
457 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
459 add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
460 require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
462 hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
464 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
465 (show_only ? ADD_CACHE_PRETEND : 0) |
466 (intent_to_add ? ADD_CACHE_INTENT : 0) |
467 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
468 (!(addremove || take_worktree_changes)
469 ? ADD_CACHE_IGNORE_REMOVAL : 0));
471 if (require_pathspec && argc == 0) {
472 fprintf(stderr, _("Nothing specified, nothing added.\n"));
473 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
478 * Check the "pathspec '%s' did not match any files" block
479 * below before enabling new magic.
481 parse_pathspec(&pathspec, PATHSPEC_ATTR,
482 PATHSPEC_PREFER_FULL |
483 PATHSPEC_SYMLINK_LEADING_PATH,
486 if (read_cache_preload(&pathspec) < 0)
487 die(_("index file corrupt"));
489 die_in_unpopulated_submodule(&the_index, prefix);
490 die_path_inside_submodule(&the_index, &pathspec);
495 /* Set up the default git porcelain excludes */
496 memset(&dir, 0, sizeof(dir));
498 dir.flags |= DIR_COLLECT_IGNORED;
499 setup_standard_excludes(&dir);
502 /* This picks up the paths that are not tracked */
503 baselen = fill_directory(&dir, &the_index, &pathspec);
505 seen = prune_directory(&dir, &pathspec, baselen);
509 refresh(verbose, &pathspec);
517 seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
520 * file_exists() assumes exact match
522 GUARD_PATHSPEC(&pathspec,
529 for (i = 0; i < pathspec.nr; i++) {
530 const char *path = pathspec.items[i].match;
531 if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
533 if (!seen[i] && path[0] &&
534 ((pathspec.items[i].magic &
535 (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
536 !file_exists(path))) {
537 if (ignore_missing) {
538 int dtype = DT_UNKNOWN;
539 if (is_excluded(&dir, &the_index, path, &dtype))
540 dir_add_ignored(&dir, &the_index,
541 path, pathspec.items[i].len);
543 die(_("pathspec '%s' did not match any files"),
544 pathspec.items[i].original);
553 exit_status |= renormalize_tracked_files(&pathspec, flags);
555 exit_status |= add_files_to_cache(prefix, &pathspec, flags);
558 exit_status |= add_files(&dir, flags);
560 if (chmod_arg && pathspec.nr)
561 chmod_pathspec(&pathspec, chmod_arg[0]);
562 unplug_bulk_checkin();
565 if (write_locked_index(&the_index, &lock_file,
566 COMMIT_LOCK | SKIP_IF_UNCHANGED))
567 die(_("Unable to write new index file"));