Merge branch 'bc/vcs-svn-cleanup' into maint
[git] / builtin / add.c
1 /*
2  * "git add" builtin command
3  *
4  * Copyright (C) 2006 Linus Torvalds
5  */
6 #include "cache.h"
7 #include "config.h"
8 #include "builtin.h"
9 #include "lockfile.h"
10 #include "dir.h"
11 #include "pathspec.h"
12 #include "exec_cmd.h"
13 #include "cache-tree.h"
14 #include "run-command.h"
15 #include "parse-options.h"
16 #include "diff.h"
17 #include "diffcore.h"
18 #include "revision.h"
19 #include "bulk-checkin.h"
20 #include "argv-array.h"
21 #include "submodule.h"
22
23 static const char * const builtin_add_usage[] = {
24         N_("git add [<options>] [--] <pathspec>..."),
25         NULL
26 };
27 static int patch_interactive, add_interactive, edit_interactive;
28 static int take_worktree_changes;
29
30 struct update_callback_data {
31         int flags;
32         int add_errors;
33 };
34
35 static void chmod_pathspec(struct pathspec *pathspec, char flip)
36 {
37         int i;
38
39         for (i = 0; i < active_nr; i++) {
40                 struct cache_entry *ce = active_cache[i];
41
42                 if (pathspec && !ce_path_match(ce, pathspec, NULL))
43                         continue;
44
45                 if (chmod_cache_entry(ce, flip) < 0)
46                         fprintf(stderr, "cannot chmod %cx '%s'\n", flip, ce->name);
47         }
48 }
49
50 static int fix_unmerged_status(struct diff_filepair *p,
51                                struct update_callback_data *data)
52 {
53         if (p->status != DIFF_STATUS_UNMERGED)
54                 return p->status;
55         if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
56                 /*
57                  * This is not an explicit add request, and the
58                  * path is missing from the working tree (deleted)
59                  */
60                 return DIFF_STATUS_DELETED;
61         else
62                 /*
63                  * Either an explicit add request, or path exists
64                  * in the working tree.  An attempt to explicitly
65                  * add a path that does not exist in the working tree
66                  * will be caught as an error by the caller immediately.
67                  */
68                 return DIFF_STATUS_MODIFIED;
69 }
70
71 static void update_callback(struct diff_queue_struct *q,
72                             struct diff_options *opt, void *cbdata)
73 {
74         int i;
75         struct update_callback_data *data = cbdata;
76
77         for (i = 0; i < q->nr; i++) {
78                 struct diff_filepair *p = q->queue[i];
79                 const char *path = p->one->path;
80                 switch (fix_unmerged_status(p, data)) {
81                 default:
82                         die(_("unexpected diff status %c"), p->status);
83                 case DIFF_STATUS_MODIFIED:
84                 case DIFF_STATUS_TYPE_CHANGED:
85                         if (add_file_to_index(&the_index, path, data->flags)) {
86                                 if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
87                                         die(_("updating files failed"));
88                                 data->add_errors++;
89                         }
90                         break;
91                 case DIFF_STATUS_DELETED:
92                         if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
93                                 break;
94                         if (!(data->flags & ADD_CACHE_PRETEND))
95                                 remove_file_from_index(&the_index, path);
96                         if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
97                                 printf(_("remove '%s'\n"), path);
98                         break;
99                 }
100         }
101 }
102
103 int add_files_to_cache(const char *prefix,
104                        const struct pathspec *pathspec, int flags)
105 {
106         struct update_callback_data data;
107         struct rev_info rev;
108
109         memset(&data, 0, sizeof(data));
110         data.flags = flags;
111
112         init_revisions(&rev, prefix);
113         setup_revisions(0, NULL, &rev, NULL);
114         if (pathspec)
115                 copy_pathspec(&rev.prune_data, pathspec);
116         rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
117         rev.diffopt.format_callback = update_callback;
118         rev.diffopt.format_callback_data = &data;
119         rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
120         run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
121         return !!data.add_errors;
122 }
123
124 static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
125 {
126         char *seen;
127         int i;
128         struct dir_entry **src, **dst;
129
130         seen = xcalloc(pathspec->nr, 1);
131
132         src = dst = dir->entries;
133         i = dir->nr;
134         while (--i >= 0) {
135                 struct dir_entry *entry = *src++;
136                 if (dir_path_match(entry, pathspec, prefix, seen))
137                         *dst++ = entry;
138         }
139         dir->nr = dst - dir->entries;
140         add_pathspec_matches_against_index(pathspec, &the_index, seen);
141         return seen;
142 }
143
144 static void refresh(int verbose, const struct pathspec *pathspec)
145 {
146         char *seen;
147         int i;
148
149         seen = xcalloc(pathspec->nr, 1);
150         refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
151                       pathspec, seen, _("Unstaged changes after refreshing the index:"));
152         for (i = 0; i < pathspec->nr; i++) {
153                 if (!seen[i])
154                         die(_("pathspec '%s' did not match any files"),
155                             pathspec->items[i].match);
156         }
157         free(seen);
158 }
159
160 int run_add_interactive(const char *revision, const char *patch_mode,
161                         const struct pathspec *pathspec)
162 {
163         int status, i;
164         struct argv_array argv = ARGV_ARRAY_INIT;
165
166         argv_array_push(&argv, "add--interactive");
167         if (patch_mode)
168                 argv_array_push(&argv, patch_mode);
169         if (revision)
170                 argv_array_push(&argv, revision);
171         argv_array_push(&argv, "--");
172         for (i = 0; i < pathspec->nr; i++)
173                 /* pass original pathspec, to be re-parsed */
174                 argv_array_push(&argv, pathspec->items[i].original);
175
176         status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
177         argv_array_clear(&argv);
178         return status;
179 }
180
181 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
182 {
183         struct pathspec pathspec;
184
185         parse_pathspec(&pathspec, 0,
186                        PATHSPEC_PREFER_FULL |
187                        PATHSPEC_SYMLINK_LEADING_PATH |
188                        PATHSPEC_PREFIX_ORIGIN,
189                        prefix, argv);
190
191         return run_add_interactive(NULL,
192                                    patch ? "--patch" : NULL,
193                                    &pathspec);
194 }
195
196 static int edit_patch(int argc, const char **argv, const char *prefix)
197 {
198         char *file = git_pathdup("ADD_EDIT.patch");
199         const char *apply_argv[] = { "apply", "--recount", "--cached",
200                 NULL, NULL };
201         struct child_process child = CHILD_PROCESS_INIT;
202         struct rev_info rev;
203         int out;
204         struct stat st;
205
206         apply_argv[3] = file;
207
208         git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
209
210         if (read_cache() < 0)
211                 die(_("Could not read the index"));
212
213         init_revisions(&rev, prefix);
214         rev.diffopt.context = 7;
215
216         argc = setup_revisions(argc, argv, &rev, NULL);
217         rev.diffopt.output_format = DIFF_FORMAT_PATCH;
218         rev.diffopt.use_color = 0;
219         DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
220         out = open(file, O_CREAT | O_WRONLY, 0666);
221         if (out < 0)
222                 die(_("Could not open '%s' for writing."), file);
223         rev.diffopt.file = xfdopen(out, "w");
224         rev.diffopt.close_file = 1;
225         if (run_diff_files(&rev, 0))
226                 die(_("Could not write patch"));
227
228         if (launch_editor(file, NULL, NULL))
229                 die(_("editing patch failed"));
230
231         if (stat(file, &st))
232                 die_errno(_("Could not stat '%s'"), file);
233         if (!st.st_size)
234                 die(_("Empty patch. Aborted."));
235
236         child.git_cmd = 1;
237         child.argv = apply_argv;
238         if (run_command(&child))
239                 die(_("Could not apply '%s'"), file);
240
241         unlink(file);
242         free(file);
243         return 0;
244 }
245
246 static struct lock_file lock_file;
247
248 static const char ignore_error[] =
249 N_("The following paths are ignored by one of your .gitignore files:\n");
250
251 static int verbose, show_only, ignored_too, refresh_only;
252 static int ignore_add_errors, intent_to_add, ignore_missing;
253 static int warn_on_embedded_repo = 1;
254
255 #define ADDREMOVE_DEFAULT 1
256 static int addremove = ADDREMOVE_DEFAULT;
257 static int addremove_explicit = -1; /* unspecified */
258
259 static char *chmod_arg;
260
261 static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
262 {
263         /* if we are told to ignore, we are not adding removals */
264         *(int *)opt->value = !unset ? 0 : 1;
265         return 0;
266 }
267
268 static struct option builtin_add_options[] = {
269         OPT__DRY_RUN(&show_only, N_("dry run")),
270         OPT__VERBOSE(&verbose, N_("be verbose")),
271         OPT_GROUP(""),
272         OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
273         OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
274         OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
275         OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
276         OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
277         OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
278         OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
279         { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
280           NULL /* takes no arguments */,
281           N_("ignore paths removed in the working tree (same as --no-all)"),
282           PARSE_OPT_NOARG, ignore_removal_cb },
283         OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
284         OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
285         OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
286         OPT_STRING( 0 , "chmod", &chmod_arg, N_("(+/-)x"), N_("override the executable bit of the listed files")),
287         OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
288                         N_("warn when adding an embedded repository")),
289         OPT_END(),
290 };
291
292 static int add_config(const char *var, const char *value, void *cb)
293 {
294         if (!strcmp(var, "add.ignoreerrors") ||
295             !strcmp(var, "add.ignore-errors")) {
296                 ignore_add_errors = git_config_bool(var, value);
297                 return 0;
298         }
299         return git_default_config(var, value, cb);
300 }
301
302 static const char embedded_advice[] = N_(
303 "You've added another git repository inside your current repository.\n"
304 "Clones of the outer repository will not contain the contents of\n"
305 "the embedded repository and will not know how to obtain it.\n"
306 "If you meant to add a submodule, use:\n"
307 "\n"
308 "       git submodule add <url> %s\n"
309 "\n"
310 "If you added this path by mistake, you can remove it from the\n"
311 "index with:\n"
312 "\n"
313 "       git rm --cached %s\n"
314 "\n"
315 "See \"git help submodule\" for more information."
316 );
317
318 static void check_embedded_repo(const char *path)
319 {
320         struct strbuf name = STRBUF_INIT;
321
322         if (!warn_on_embedded_repo)
323                 return;
324         if (!ends_with(path, "/"))
325                 return;
326
327         /* Drop trailing slash for aesthetics */
328         strbuf_addstr(&name, path);
329         strbuf_strip_suffix(&name, "/");
330
331         warning(_("adding embedded git repository: %s"), name.buf);
332         if (advice_add_embedded_repo) {
333                 advise(embedded_advice, name.buf, name.buf);
334                 /* there may be multiple entries; advise only once */
335                 advice_add_embedded_repo = 0;
336         }
337
338         strbuf_release(&name);
339 }
340
341 static int add_files(struct dir_struct *dir, int flags)
342 {
343         int i, exit_status = 0;
344
345         if (dir->ignored_nr) {
346                 fprintf(stderr, _(ignore_error));
347                 for (i = 0; i < dir->ignored_nr; i++)
348                         fprintf(stderr, "%s\n", dir->ignored[i]->name);
349                 fprintf(stderr, _("Use -f if you really want to add them.\n"));
350                 exit_status = 1;
351         }
352
353         for (i = 0; i < dir->nr; i++) {
354                 check_embedded_repo(dir->entries[i]->name);
355                 if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
356                         if (!ignore_add_errors)
357                                 die(_("adding files failed"));
358                         exit_status = 1;
359                 }
360         }
361         return exit_status;
362 }
363
364 int cmd_add(int argc, const char **argv, const char *prefix)
365 {
366         int exit_status = 0;
367         struct pathspec pathspec;
368         struct dir_struct dir;
369         int flags;
370         int add_new_files;
371         int require_pathspec;
372         char *seen = NULL;
373
374         git_config(add_config, NULL);
375
376         argc = parse_options(argc, argv, prefix, builtin_add_options,
377                           builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
378         if (patch_interactive)
379                 add_interactive = 1;
380         if (add_interactive)
381                 exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
382
383         if (edit_interactive)
384                 return(edit_patch(argc, argv, prefix));
385         argc--;
386         argv++;
387
388         if (0 <= addremove_explicit)
389                 addremove = addremove_explicit;
390         else if (take_worktree_changes && ADDREMOVE_DEFAULT)
391                 addremove = 0; /* "-u" was given but not "-A" */
392
393         if (addremove && take_worktree_changes)
394                 die(_("-A and -u are mutually incompatible"));
395
396         if (!take_worktree_changes && addremove_explicit < 0 && argc)
397                 /* Turn "git add pathspec..." to "git add -A pathspec..." */
398                 addremove = 1;
399
400         if (!show_only && ignore_missing)
401                 die(_("Option --ignore-missing can only be used together with --dry-run"));
402
403         if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
404                           chmod_arg[1] != 'x' || chmod_arg[2]))
405                 die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
406
407         add_new_files = !take_worktree_changes && !refresh_only;
408         require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
409
410         hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
411
412         flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
413                  (show_only ? ADD_CACHE_PRETEND : 0) |
414                  (intent_to_add ? ADD_CACHE_INTENT : 0) |
415                  (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
416                  (!(addremove || take_worktree_changes)
417                   ? ADD_CACHE_IGNORE_REMOVAL : 0));
418
419         if (require_pathspec && argc == 0) {
420                 fprintf(stderr, _("Nothing specified, nothing added.\n"));
421                 fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
422                 return 0;
423         }
424
425         if (read_cache() < 0)
426                 die(_("index file corrupt"));
427
428         die_in_unpopulated_submodule(&the_index, prefix);
429
430         /*
431          * Check the "pathspec '%s' did not match any files" block
432          * below before enabling new magic.
433          */
434         parse_pathspec(&pathspec, 0,
435                        PATHSPEC_PREFER_FULL |
436                        PATHSPEC_SYMLINK_LEADING_PATH,
437                        prefix, argv);
438
439         die_path_inside_submodule(&the_index, &pathspec);
440
441         if (add_new_files) {
442                 int baselen;
443
444                 /* Set up the default git porcelain excludes */
445                 memset(&dir, 0, sizeof(dir));
446                 if (!ignored_too) {
447                         dir.flags |= DIR_COLLECT_IGNORED;
448                         setup_standard_excludes(&dir);
449                 }
450
451                 /* This picks up the paths that are not tracked */
452                 baselen = fill_directory(&dir, &the_index, &pathspec);
453                 if (pathspec.nr)
454                         seen = prune_directory(&dir, &pathspec, baselen);
455         }
456
457         if (refresh_only) {
458                 refresh(verbose, &pathspec);
459                 goto finish;
460         }
461
462         if (pathspec.nr) {
463                 int i;
464
465                 if (!seen)
466                         seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
467
468                 /*
469                  * file_exists() assumes exact match
470                  */
471                 GUARD_PATHSPEC(&pathspec,
472                                PATHSPEC_FROMTOP |
473                                PATHSPEC_LITERAL |
474                                PATHSPEC_GLOB |
475                                PATHSPEC_ICASE |
476                                PATHSPEC_EXCLUDE);
477
478                 for (i = 0; i < pathspec.nr; i++) {
479                         const char *path = pathspec.items[i].match;
480                         if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
481                                 continue;
482                         if (!seen[i] && path[0] &&
483                             ((pathspec.items[i].magic &
484                               (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
485                              !file_exists(path))) {
486                                 if (ignore_missing) {
487                                         int dtype = DT_UNKNOWN;
488                                         if (is_excluded(&dir, &the_index, path, &dtype))
489                                                 dir_add_ignored(&dir, &the_index,
490                                                                 path, pathspec.items[i].len);
491                                 } else
492                                         die(_("pathspec '%s' did not match any files"),
493                                             pathspec.items[i].original);
494                         }
495                 }
496                 free(seen);
497         }
498
499         plug_bulk_checkin();
500
501         exit_status |= add_files_to_cache(prefix, &pathspec, flags);
502
503         if (add_new_files)
504                 exit_status |= add_files(&dir, flags);
505
506         if (chmod_arg && pathspec.nr)
507                 chmod_pathspec(&pathspec, chmod_arg[0]);
508         unplug_bulk_checkin();
509
510 finish:
511         if (active_cache_changed) {
512                 if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
513                         die(_("Unable to write new index file"));
514         }
515
516         return exit_status;
517 }