git add -e: Explicitly specify that patch should have no color
[git/jrn.git] / builtin / add.c
blob8b2aa5bff109e29c13ddff34143e0b4dc64bce4d
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 int fix_unmerged_status(struct diff_filepair *p,
32 struct update_callback_data *data)
34 if (p->status != DIFF_STATUS_UNMERGED)
35 return p->status;
36 if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
38 * This is not an explicit add request, and the
39 * path is missing from the working tree (deleted)
41 return DIFF_STATUS_DELETED;
42 else
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.
49 return DIFF_STATUS_MODIFIED;
52 static void update_callback(struct diff_queue_struct *q,
53 struct diff_options *opt, void *cbdata)
55 int i;
56 struct update_callback_data *data = cbdata;
58 for (i = 0; i < q->nr; i++) {
59 struct diff_filepair *p = q->queue[i];
60 const char *path = p->one->path;
61 switch (fix_unmerged_status(p, data)) {
62 default:
63 die(_("unexpected diff status %c"), p->status);
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))
68 die(_("updating files failed"));
69 data->add_errors++;
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))
78 printf(_("remove '%s'\n"), path);
79 break;
84 int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
86 struct update_callback_data data;
87 struct rev_info rev;
88 init_revisions(&rev, prefix);
89 setup_revisions(0, NULL, &rev, NULL);
90 init_pathspec(&rev.prune_data, pathspec);
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;
96 rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
97 run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
98 return !!data.add_errors;
101 static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
103 char *seen;
104 int i, specs;
105 struct dir_entry **src, **dst;
107 for (specs = 0; pathspec[specs]; specs++)
108 /* nothing */;
109 seen = xcalloc(specs, 1);
111 src = dst = dir->entries;
112 i = dir->nr;
113 while (--i >= 0) {
114 struct dir_entry *entry = *src++;
115 if (match_pathspec(pathspec, entry->name, entry->len,
116 prefix, seen))
117 *dst++ = entry;
119 dir->nr = dst - dir->entries;
120 add_pathspec_matches_against_index(pathspec, seen, specs);
121 return seen;
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.
128 static void treat_gitlinks(const char **pathspec)
130 int i;
132 if (!pathspec || !*pathspec)
133 return;
135 for (i = 0; pathspec[i]; i++)
136 pathspec[i] = check_path_for_gitlink(pathspec[i]);
139 static void refresh(int verbose, const char **pathspec)
141 char *seen;
142 int i, specs;
144 for (specs = 0; pathspec[specs]; specs++)
145 /* nothing */;
146 seen = xcalloc(specs, 1);
147 refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
148 pathspec, seen, _("Unstaged changes after refreshing the index:"));
149 for (i = 0; i < specs; i++) {
150 if (!seen[i])
151 die(_("pathspec '%s' did not match any files"), pathspec[i]);
153 free(seen);
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.
161 static const char **validate_pathspec(const char **argv, const char *prefix)
163 const char **pathspec = get_pathspec(prefix, argv);
165 if (pathspec) {
166 const char **p;
167 for (p = pathspec; *p; p++) {
168 die_if_path_beyond_symlink(*p, prefix);
172 return pathspec;
175 int run_add_interactive(const char *revision, const char *patch_mode,
176 const char **pathspec)
178 int status, ac, pc = 0;
179 const char **args;
181 if (pathspec)
182 while (pathspec[pc])
183 pc++;
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;
197 args[ac] = NULL;
199 status = run_command_v_opt(args, RUN_GIT_CMD);
200 free(args);
201 return status;
204 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
206 const char **pathspec = NULL;
208 if (argc) {
209 pathspec = validate_pathspec(argv, prefix);
210 if (!pathspec)
211 return -1;
214 return run_add_interactive(NULL,
215 patch ? "--patch" : NULL,
216 pathspec);
219 static int edit_patch(int argc, const char **argv, const char *prefix)
221 char *file = git_pathdup("ADD_EDIT.patch");
222 const char *apply_argv[] = { "apply", "--recount", "--cached",
223 NULL, NULL };
224 struct child_process child;
225 struct rev_info rev;
226 int out;
227 struct stat st;
229 apply_argv[3] = file;
231 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
233 if (read_cache() < 0)
234 die (_("Could not read the index"));
236 init_revisions(&rev, prefix);
237 rev.diffopt.context = 7;
239 argc = setup_revisions(argc, argv, &rev, NULL);
240 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
241 rev.diffopt.use_color = 0;
242 DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
243 out = open(file, O_CREAT | O_WRONLY, 0666);
244 if (out < 0)
245 die (_("Could not open '%s' for writing."), file);
246 rev.diffopt.file = xfdopen(out, "w");
247 rev.diffopt.close_file = 1;
248 if (run_diff_files(&rev, 0))
249 die (_("Could not write patch"));
251 launch_editor(file, NULL, NULL);
253 if (stat(file, &st))
254 die_errno(_("Could not stat '%s'"), file);
255 if (!st.st_size)
256 die(_("Empty patch. Aborted."));
258 memset(&child, 0, sizeof(child));
259 child.git_cmd = 1;
260 child.argv = apply_argv;
261 if (run_command(&child))
262 die (_("Could not apply '%s'"), file);
264 unlink(file);
265 free(file);
266 return 0;
269 static struct lock_file lock_file;
271 static const char ignore_error[] =
272 N_("The following paths are ignored by one of your .gitignore files:\n");
274 static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
275 static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
277 static struct option builtin_add_options[] = {
278 OPT__DRY_RUN(&show_only, N_("dry run")),
279 OPT__VERBOSE(&verbose, N_("be verbose")),
280 OPT_GROUP(""),
281 OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
282 OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
283 OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
284 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
285 OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
286 OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
287 OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
288 OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
289 OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
290 OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
291 OPT_END(),
294 static int add_config(const char *var, const char *value, void *cb)
296 if (!strcmp(var, "add.ignoreerrors") ||
297 !strcmp(var, "add.ignore-errors")) {
298 ignore_add_errors = git_config_bool(var, value);
299 return 0;
301 return git_default_config(var, value, cb);
304 static int add_files(struct dir_struct *dir, int flags)
306 int i, exit_status = 0;
308 if (dir->ignored_nr) {
309 fprintf(stderr, _(ignore_error));
310 for (i = 0; i < dir->ignored_nr; i++)
311 fprintf(stderr, "%s\n", dir->ignored[i]->name);
312 fprintf(stderr, _("Use -f if you really want to add them.\n"));
313 die(_("no files added"));
316 for (i = 0; i < dir->nr; i++)
317 if (add_file_to_cache(dir->entries[i]->name, flags)) {
318 if (!ignore_add_errors)
319 die(_("adding files failed"));
320 exit_status = 1;
322 return exit_status;
325 static void warn_pathless_add(const char *option_name, const char *short_name) {
327 * To be consistent with "git add -p" and most Git
328 * commands, we should default to being tree-wide, but
329 * this is not the original behavior and can't be
330 * changed until users trained themselves not to type
331 * "git add -u" or "git add -A". For now, we warn and
332 * keep the old behavior. Later, the behavior can be changed
333 * to tree-wide, keeping the warning for a while, and
334 * eventually we can drop the warning.
336 warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
337 "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
338 "To add content for the whole tree, run:\n"
339 "\n"
340 " git add %s :/\n"
341 " (or git add %s :/)\n"
342 "\n"
343 "To restrict the command to the current directory, run:\n"
344 "\n"
345 " git add %s .\n"
346 " (or git add %s .)\n"
347 "\n"
348 "With the current Git version, the command is restricted to the current directory."),
349 option_name, short_name,
350 option_name, short_name,
351 option_name, short_name);
354 int cmd_add(int argc, const char **argv, const char *prefix)
356 int exit_status = 0;
357 int newfd;
358 const char **pathspec;
359 struct dir_struct dir;
360 int flags;
361 int add_new_files;
362 int require_pathspec;
363 char *seen = NULL;
364 const char *option_with_implicit_dot = NULL;
365 const char *short_option_with_implicit_dot = NULL;
367 git_config(add_config, NULL);
369 argc = parse_options(argc, argv, prefix, builtin_add_options,
370 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
371 if (patch_interactive)
372 add_interactive = 1;
373 if (add_interactive)
374 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
376 if (edit_interactive)
377 return(edit_patch(argc, argv, prefix));
378 argc--;
379 argv++;
381 if (addremove && take_worktree_changes)
382 die(_("-A and -u are mutually incompatible"));
383 if (!show_only && ignore_missing)
384 die(_("Option --ignore-missing can only be used together with --dry-run"));
385 if (addremove) {
386 option_with_implicit_dot = "--all";
387 short_option_with_implicit_dot = "-A";
389 if (take_worktree_changes) {
390 option_with_implicit_dot = "--update";
391 short_option_with_implicit_dot = "-u";
393 if (option_with_implicit_dot && !argc) {
394 static const char *here[2] = { ".", NULL };
395 if (prefix)
396 warn_pathless_add(option_with_implicit_dot,
397 short_option_with_implicit_dot);
398 argc = 1;
399 argv = here;
402 add_new_files = !take_worktree_changes && !refresh_only;
403 require_pathspec = !take_worktree_changes;
405 newfd = hold_locked_index(&lock_file, 1);
407 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
408 (show_only ? ADD_CACHE_PRETEND : 0) |
409 (intent_to_add ? ADD_CACHE_INTENT : 0) |
410 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
411 (!(addremove || take_worktree_changes)
412 ? ADD_CACHE_IGNORE_REMOVAL : 0));
414 if (require_pathspec && argc == 0) {
415 fprintf(stderr, _("Nothing specified, nothing added.\n"));
416 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
417 return 0;
419 pathspec = validate_pathspec(argv, prefix);
421 if (read_cache() < 0)
422 die(_("index file corrupt"));
423 treat_gitlinks(pathspec);
425 if (add_new_files) {
426 int baselen;
428 /* Set up the default git porcelain excludes */
429 memset(&dir, 0, sizeof(dir));
430 if (!ignored_too) {
431 dir.flags |= DIR_COLLECT_IGNORED;
432 setup_standard_excludes(&dir);
435 /* This picks up the paths that are not tracked */
436 baselen = fill_directory(&dir, pathspec);
437 if (pathspec)
438 seen = prune_directory(&dir, pathspec, baselen);
441 if (refresh_only) {
442 refresh(verbose, pathspec);
443 goto finish;
446 if (pathspec) {
447 int i;
448 struct path_exclude_check check;
450 path_exclude_check_init(&check, &dir);
451 if (!seen)
452 seen = find_pathspecs_matching_against_index(pathspec);
453 for (i = 0; pathspec[i]; i++) {
454 if (!seen[i] && pathspec[i][0]
455 && !file_exists(pathspec[i])) {
456 if (ignore_missing) {
457 int dtype = DT_UNKNOWN;
458 if (is_path_excluded(&check, pathspec[i], -1, &dtype))
459 dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
460 } else
461 die(_("pathspec '%s' did not match any files"),
462 pathspec[i]);
465 free(seen);
466 path_exclude_check_clear(&check);
469 plug_bulk_checkin();
471 exit_status |= add_files_to_cache(prefix, pathspec, flags);
473 if (add_new_files)
474 exit_status |= add_files(&dir, flags);
476 unplug_bulk_checkin();
478 finish:
479 if (active_cache_changed) {
480 if (write_cache(newfd, active_cache, active_nr) ||
481 commit_locked_index(&lock_file))
482 die(_("Unable to write new index file"));
485 return exit_status;