Git fork
1/*
2 * "git add" builtin command
3 *
4 * Copyright (C) 2006 Linus Torvalds
5 */
6
7#include "builtin.h"
8#include "advice.h"
9#include "config.h"
10#include "environment.h"
11#include "lockfile.h"
12#include "editor.h"
13#include "dir.h"
14#include "gettext.h"
15#include "pathspec.h"
16#include "run-command.h"
17#include "object-file.h"
18#include "odb.h"
19#include "parse-options.h"
20#include "path.h"
21#include "preload-index.h"
22#include "diff.h"
23#include "read-cache.h"
24#include "revision.h"
25#include "strvec.h"
26#include "submodule.h"
27#include "add-interactive.h"
28
29static const char * const builtin_add_usage[] = {
30 N_("git add [<options>] [--] <pathspec>..."),
31 NULL
32};
33static int patch_interactive, add_interactive, edit_interactive;
34static struct add_p_opt add_p_opt = ADD_P_OPT_INIT;
35static int take_worktree_changes;
36static int add_renormalize;
37static int pathspec_file_nul;
38static int include_sparse;
39static const char *pathspec_from_file;
40
41static int chmod_pathspec(struct repository *repo,
42 struct pathspec *pathspec,
43 char flip,
44 int show_only)
45{
46 int ret = 0;
47
48 for (size_t i = 0; i < repo->index->cache_nr; i++) {
49 struct cache_entry *ce = repo->index->cache[i];
50 int err;
51
52 if (!include_sparse &&
53 (ce_skip_worktree(ce) ||
54 !path_in_sparse_checkout(ce->name, repo->index)))
55 continue;
56
57 if (pathspec && !ce_path_match(repo->index, ce, pathspec, NULL))
58 continue;
59
60 if (!show_only)
61 err = chmod_index_entry(repo->index, ce, flip);
62 else
63 err = S_ISREG(ce->ce_mode) ? 0 : -1;
64
65 if (err < 0)
66 ret = error(_("cannot chmod %cx '%s'"), flip, ce->name);
67 }
68
69 return ret;
70}
71
72static int renormalize_tracked_files(struct repository *repo,
73 const struct pathspec *pathspec,
74 int flags)
75{
76 int retval = 0;
77
78 for (size_t i = 0; i < repo->index->cache_nr; i++) {
79 struct cache_entry *ce = repo->index->cache[i];
80
81 if (!include_sparse &&
82 (ce_skip_worktree(ce) ||
83 !path_in_sparse_checkout(ce->name, repo->index)))
84 continue;
85 if (ce_stage(ce))
86 continue; /* do not touch unmerged paths */
87 if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
88 continue; /* do not touch non blobs */
89 if (pathspec && !ce_path_match(repo->index, ce, pathspec, NULL))
90 continue;
91 retval |= add_file_to_index(repo->index, ce->name,
92 flags | ADD_CACHE_RENORMALIZE);
93 }
94
95 return retval;
96}
97
98static char *prune_directory(struct repository *repo,
99 struct dir_struct *dir,
100 struct pathspec *pathspec,
101 int prefix)
102{
103 char *seen;
104 int i;
105 struct dir_entry **src, **dst;
106
107 seen = xcalloc(pathspec->nr, 1);
108
109 src = dst = dir->entries;
110 i = dir->nr;
111 while (--i >= 0) {
112 struct dir_entry *entry = *src++;
113 if (dir_path_match(repo->index, entry, pathspec, prefix, seen))
114 *dst++ = entry;
115 }
116 dir->nr = dst - dir->entries;
117 add_pathspec_matches_against_index(pathspec, repo->index, seen,
118 PS_IGNORE_SKIP_WORKTREE);
119 return seen;
120}
121
122static int refresh(struct repository *repo, int verbose, const struct pathspec *pathspec)
123{
124 char *seen;
125 int i, ret = 0;
126 char *skip_worktree_seen = NULL;
127 struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
128 unsigned int flags = REFRESH_IGNORE_SKIP_WORKTREE |
129 (verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
130
131 seen = xcalloc(pathspec->nr, 1);
132 refresh_index(repo->index, flags, pathspec, seen,
133 _("Unstaged changes after refreshing the index:"));
134 for (i = 0; i < pathspec->nr; i++) {
135 if (!seen[i]) {
136 const char *path = pathspec->items[i].original;
137
138 if (matches_skip_worktree(pathspec, i, &skip_worktree_seen) ||
139 !path_in_sparse_checkout(path, repo->index)) {
140 string_list_append(&only_match_skip_worktree,
141 pathspec->items[i].original);
142 } else {
143 die(_("pathspec '%s' did not match any files"),
144 pathspec->items[i].original);
145 }
146 }
147 }
148
149 if (only_match_skip_worktree.nr) {
150 advise_on_updating_sparse_paths(&only_match_skip_worktree);
151 ret = 1;
152 }
153
154 free(seen);
155 free(skip_worktree_seen);
156 string_list_clear(&only_match_skip_worktree, 0);
157 return ret;
158}
159
160int interactive_add(struct repository *repo,
161 const char **argv,
162 const char *prefix,
163 int patch, struct add_p_opt *add_p_opt)
164{
165 struct pathspec pathspec;
166 int ret;
167
168 parse_pathspec(&pathspec, 0,
169 PATHSPEC_PREFER_FULL |
170 PATHSPEC_SYMLINK_LEADING_PATH |
171 PATHSPEC_PREFIX_ORIGIN,
172 prefix, argv);
173
174 if (patch)
175 ret = !!run_add_p(repo, ADD_P_ADD, add_p_opt, NULL, &pathspec);
176 else
177 ret = !!run_add_i(repo, &pathspec, add_p_opt);
178
179 clear_pathspec(&pathspec);
180 return ret;
181}
182
183static int edit_patch(struct repository *repo,
184 int argc,
185 const char **argv,
186 const char *prefix)
187{
188 char *file = repo_git_path(repo, "ADD_EDIT.patch");
189 struct child_process child = CHILD_PROCESS_INIT;
190 struct rev_info rev;
191 int out;
192 struct stat st;
193
194 repo_config(repo, git_diff_basic_config, NULL);
195
196 if (repo_read_index(repo) < 0)
197 die(_("could not read the index"));
198
199 repo_init_revisions(repo, &rev, prefix);
200 rev.diffopt.context = 7;
201
202 argc = setup_revisions(argc, argv, &rev, NULL);
203 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
204 rev.diffopt.use_color = GIT_COLOR_NEVER;
205 rev.diffopt.flags.ignore_dirty_submodules = 1;
206 out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
207 rev.diffopt.file = xfdopen(out, "w");
208 rev.diffopt.close_file = 1;
209 run_diff_files(&rev, 0);
210
211 if (launch_editor(file, NULL, NULL))
212 die(_("editing patch failed"));
213
214 if (stat(file, &st))
215 die_errno(_("could not stat '%s'"), file);
216 if (!st.st_size)
217 die(_("empty patch. aborted"));
218
219 child.git_cmd = 1;
220 strvec_pushl(&child.args, "apply", "--recount", "--cached", file,
221 NULL);
222 if (run_command(&child))
223 die(_("could not apply '%s'"), file);
224
225 unlink(file);
226 free(file);
227 release_revisions(&rev);
228 return 0;
229}
230
231static const char ignore_error[] =
232N_("The following paths are ignored by one of your .gitignore files:\n");
233
234static int verbose, show_only, ignored_too, refresh_only;
235static int ignore_add_errors, intent_to_add, ignore_missing;
236static int warn_on_embedded_repo = 1;
237
238#define ADDREMOVE_DEFAULT 1
239static int addremove = ADDREMOVE_DEFAULT;
240static int addremove_explicit = -1; /* unspecified */
241
242static char *chmod_arg;
243
244static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
245{
246 BUG_ON_OPT_ARG(arg);
247
248 /* if we are told to ignore, we are not adding removals */
249 *(int *)opt->value = !unset ? 0 : 1;
250 return 0;
251}
252
253static struct option builtin_add_options[] = {
254 OPT__DRY_RUN(&show_only, N_("dry run")),
255 OPT__VERBOSE(&verbose, N_("be verbose")),
256 OPT_GROUP(""),
257 OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
258 OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
259 OPT_DIFF_UNIFIED(&add_p_opt.context),
260 OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext),
261 OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
262 OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
263 OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
264 OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
265 OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
266 OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
267 OPT_CALLBACK_F(0, "ignore-removal", &addremove_explicit,
268 NULL /* takes no arguments */,
269 N_("ignore paths removed in the working tree (same as --no-all)"),
270 PARSE_OPT_NOARG, ignore_removal_cb),
271 OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
272 OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
273 OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
274 OPT_BOOL(0, "sparse", &include_sparse, N_("allow updating entries outside of the sparse-checkout cone")),
275 OPT_STRING(0, "chmod", &chmod_arg, "(+|-)x",
276 N_("override the executable bit of the listed files")),
277 OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
278 N_("warn when adding an embedded repository")),
279 OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
280 OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
281 OPT_END(),
282};
283
284static int add_config(const char *var, const char *value,
285 const struct config_context *ctx, void *cb)
286{
287 if (!strcmp(var, "add.ignoreerrors") ||
288 !strcmp(var, "add.ignore-errors")) {
289 ignore_add_errors = git_config_bool(var, value);
290 return 0;
291 }
292
293 if (git_color_config(var, value, cb) < 0)
294 return -1;
295
296 return git_default_config(var, value, ctx, cb);
297}
298
299static const char embedded_advice[] = N_(
300"You've added another git repository inside your current repository.\n"
301"Clones of the outer repository will not contain the contents of\n"
302"the embedded repository and will not know how to obtain it.\n"
303"If you meant to add a submodule, use:\n"
304"\n"
305" git submodule add <url> %s\n"
306"\n"
307"If you added this path by mistake, you can remove it from the\n"
308"index with:\n"
309"\n"
310" git rm --cached %s\n"
311"\n"
312"See \"git help submodule\" for more information."
313);
314
315static void check_embedded_repo(const char *path)
316{
317 struct strbuf name = STRBUF_INIT;
318 static int adviced_on_embedded_repo = 0;
319
320 if (!warn_on_embedded_repo)
321 return;
322 if (!ends_with(path, "/"))
323 return;
324
325 /* Drop trailing slash for aesthetics */
326 strbuf_addstr(&name, path);
327 strbuf_strip_suffix(&name, "/");
328
329 warning(_("adding embedded git repository: %s"), name.buf);
330 if (!adviced_on_embedded_repo) {
331 advise_if_enabled(ADVICE_ADD_EMBEDDED_REPO,
332 embedded_advice, name.buf, name.buf);
333 adviced_on_embedded_repo = 1;
334 }
335
336 strbuf_release(&name);
337}
338
339static int add_files(struct repository *repo, struct dir_struct *dir, int flags)
340{
341 int i, exit_status = 0;
342 struct string_list matched_sparse_paths = STRING_LIST_INIT_NODUP;
343
344 if (dir->ignored_nr) {
345 fprintf(stderr, _(ignore_error));
346 for (i = 0; i < dir->ignored_nr; i++)
347 fprintf(stderr, "%s\n", dir->ignored[i]->name);
348 advise_if_enabled(ADVICE_ADD_IGNORED_FILE,
349 _("Use -f if you really want to add them."));
350 exit_status = 1;
351 }
352
353 for (i = 0; i < dir->nr; i++) {
354 if (!include_sparse &&
355 !path_in_sparse_checkout(dir->entries[i]->name, repo->index)) {
356 string_list_append(&matched_sparse_paths,
357 dir->entries[i]->name);
358 continue;
359 }
360 if (add_file_to_index(repo->index, dir->entries[i]->name, flags)) {
361 if (!ignore_add_errors)
362 die(_("adding files failed"));
363 exit_status = 1;
364 } else {
365 check_embedded_repo(dir->entries[i]->name);
366 }
367 }
368
369 if (matched_sparse_paths.nr) {
370 advise_on_updating_sparse_paths(&matched_sparse_paths);
371 exit_status = 1;
372 }
373
374 string_list_clear(&matched_sparse_paths, 0);
375
376 return exit_status;
377}
378
379int cmd_add(int argc,
380 const char **argv,
381 const char *prefix,
382 struct repository *repo)
383{
384 int exit_status = 0;
385 struct pathspec pathspec;
386 struct dir_struct dir = DIR_INIT;
387 int flags;
388 int add_new_files;
389 int require_pathspec;
390 char *seen = NULL;
391 char *ps_matched = NULL;
392 struct lock_file lock_file = LOCK_INIT;
393 struct odb_transaction *transaction;
394
395 repo_config(repo, add_config, NULL);
396
397 argc = parse_options(argc, argv, prefix, builtin_add_options,
398 builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
399
400 prepare_repo_settings(repo);
401 repo->settings.command_requires_full_index = 0;
402
403 if (add_p_opt.context < -1)
404 die(_("'%s' cannot be negative"), "--unified");
405 if (add_p_opt.interhunkcontext < -1)
406 die(_("'%s' cannot be negative"), "--inter-hunk-context");
407
408 if (patch_interactive)
409 add_interactive = 1;
410 if (add_interactive) {
411 if (show_only)
412 die(_("options '%s' and '%s' cannot be used together"), "--dry-run", "--interactive/--patch");
413 if (pathspec_from_file)
414 die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch");
415 exit(interactive_add(repo, argv + 1, prefix, patch_interactive, &add_p_opt));
416 } else {
417 if (add_p_opt.context != -1)
418 die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch");
419 if (add_p_opt.interhunkcontext != -1)
420 die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch");
421 }
422
423 if (edit_interactive) {
424 if (pathspec_from_file)
425 die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--edit");
426 return(edit_patch(repo, argc, argv, prefix));
427 }
428 argc--;
429 argv++;
430
431 if (0 <= addremove_explicit)
432 addremove = addremove_explicit;
433 else if (take_worktree_changes && ADDREMOVE_DEFAULT)
434 addremove = 0; /* "-u" was given but not "-A" */
435
436 if (addremove && take_worktree_changes)
437 die(_("options '%s' and '%s' cannot be used together"), "-A", "-u");
438
439 if (!show_only && ignore_missing)
440 die(_("the option '%s' requires '%s'"), "--ignore-missing", "--dry-run");
441
442 if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
443 chmod_arg[1] != 'x' || chmod_arg[2]))
444 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
445
446 add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
447 require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
448
449 repo_hold_locked_index(repo, &lock_file, LOCK_DIE_ON_ERROR);
450
451 /*
452 * Check the "pathspec '%s' did not match any files" block
453 * below before enabling new magic.
454 */
455 parse_pathspec(&pathspec, 0,
456 PATHSPEC_PREFER_FULL |
457 PATHSPEC_SYMLINK_LEADING_PATH,
458 prefix, argv);
459
460 if (pathspec_from_file) {
461 if (pathspec.nr)
462 die(_("'%s' and pathspec arguments cannot be used together"), "--pathspec-from-file");
463
464 parse_pathspec_file(&pathspec, 0,
465 PATHSPEC_PREFER_FULL |
466 PATHSPEC_SYMLINK_LEADING_PATH,
467 prefix, pathspec_from_file, pathspec_file_nul);
468 } else if (pathspec_file_nul) {
469 die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file");
470 }
471
472 if (require_pathspec && pathspec.nr == 0) {
473 fprintf(stderr, _("Nothing specified, nothing added.\n"));
474 advise_if_enabled(ADVICE_ADD_EMPTY_PATHSPEC,
475 _("Maybe you wanted to say 'git add .'?"));
476 return 0;
477 }
478
479 if (!take_worktree_changes && addremove_explicit < 0 && pathspec.nr)
480 /* Turn "git add pathspec..." to "git add -A pathspec..." */
481 addremove = 1;
482
483 flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
484 (show_only ? ADD_CACHE_PRETEND : 0) |
485 (intent_to_add ? ADD_CACHE_INTENT : 0) |
486 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
487 (!(addremove || take_worktree_changes)
488 ? ADD_CACHE_IGNORE_REMOVAL : 0));
489
490 if (repo_read_index_preload(repo, &pathspec, 0) < 0)
491 die(_("index file corrupt"));
492
493 die_in_unpopulated_submodule(repo->index, prefix);
494 die_path_inside_submodule(repo->index, &pathspec);
495
496 if (add_new_files) {
497 int baselen;
498
499 /* Set up the default git porcelain excludes */
500 if (!ignored_too) {
501 dir.flags |= DIR_COLLECT_IGNORED;
502 setup_standard_excludes(&dir);
503 }
504
505 /* This picks up the paths that are not tracked */
506 baselen = fill_directory(&dir, repo->index, &pathspec);
507 if (pathspec.nr)
508 seen = prune_directory(repo, &dir, &pathspec, baselen);
509 }
510
511 if (refresh_only) {
512 exit_status |= refresh(repo, verbose, &pathspec);
513 goto finish;
514 }
515
516 if (pathspec.nr) {
517 int i;
518 char *skip_worktree_seen = NULL;
519 struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
520
521 if (!seen)
522 seen = find_pathspecs_matching_against_index(&pathspec,
523 repo->index, PS_IGNORE_SKIP_WORKTREE);
524
525 /*
526 * file_exists() assumes exact match
527 */
528 GUARD_PATHSPEC(&pathspec,
529 PATHSPEC_FROMTOP |
530 PATHSPEC_LITERAL |
531 PATHSPEC_GLOB |
532 PATHSPEC_ICASE |
533 PATHSPEC_EXCLUDE |
534 PATHSPEC_ATTR);
535
536 for (i = 0; i < pathspec.nr; i++) {
537 const char *path = pathspec.items[i].match;
538
539 if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
540 continue;
541 if (seen[i])
542 continue;
543
544 if (!include_sparse &&
545 matches_skip_worktree(&pathspec, i, &skip_worktree_seen)) {
546 string_list_append(&only_match_skip_worktree,
547 pathspec.items[i].original);
548 continue;
549 }
550
551 /* Don't complain at 'git add .' on empty repo */
552 if (!path[0])
553 continue;
554
555 if ((pathspec.items[i].magic & (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
556 !file_exists(path)) {
557 if (ignore_missing) {
558 int dtype = DT_UNKNOWN;
559 if (is_excluded(&dir, repo->index, path, &dtype))
560 dir_add_ignored(&dir, repo->index,
561 path, pathspec.items[i].len);
562 } else
563 die(_("pathspec '%s' did not match any files"),
564 pathspec.items[i].original);
565 }
566 }
567
568
569 if (only_match_skip_worktree.nr) {
570 advise_on_updating_sparse_paths(&only_match_skip_worktree);
571 exit_status = 1;
572 }
573
574 free(seen);
575 free(skip_worktree_seen);
576 string_list_clear(&only_match_skip_worktree, 0);
577 }
578
579 transaction = odb_transaction_begin(repo->objects);
580
581 ps_matched = xcalloc(pathspec.nr, 1);
582 if (add_renormalize)
583 exit_status |= renormalize_tracked_files(repo, &pathspec, flags);
584 else
585 exit_status |= add_files_to_cache(repo, prefix,
586 &pathspec, ps_matched,
587 include_sparse, flags);
588
589 if (take_worktree_changes && !add_renormalize && !ignore_add_errors &&
590 report_path_error(ps_matched, &pathspec))
591 exit(128);
592
593 if (add_new_files)
594 exit_status |= add_files(repo, &dir, flags);
595
596 if (chmod_arg && pathspec.nr)
597 exit_status |= chmod_pathspec(repo, &pathspec, chmod_arg[0], show_only);
598 odb_transaction_commit(transaction);
599
600finish:
601 if (write_locked_index(repo->index, &lock_file,
602 COMMIT_LOCK | SKIP_IF_UNCHANGED))
603 die(_("unable to write new index file"));
604
605 free(ps_matched);
606 dir_clear(&dir);
607 clear_pathspec(&pathspec);
608 return exit_status;
609}