bfc6ff3b0a455101f51a0c4a715a831e7b469347
   1/*
   2 * "git add" builtin command
   3 *
   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"
  18
  19static const char * const builtin_add_usage[] = {
  20        N_("git add [options] [--] <pathspec>..."),
  21        NULL
  22};
  23static int patch_interactive, add_interactive, edit_interactive;
  24static int take_worktree_changes;
  25
  26struct update_callback_data {
  27        int flags;
  28        int add_errors;
  29};
  30
  31static const char *option_with_implicit_dot;
  32static const char *short_option_with_implicit_dot;
  33
  34static void warn_pathless_add(void)
  35{
  36        static int shown;
  37        assert(option_with_implicit_dot && short_option_with_implicit_dot);
  38
  39        if (shown)
  40                return;
  41        shown = 1;
  42
  43        /*
  44         * To be consistent with "git add -p" and most Git
  45         * commands, we should default to being tree-wide, but
  46         * this is not the original behavior and can't be
  47         * changed until users trained themselves not to type
  48         * "git add -u" or "git add -A". For now, we warn and
  49         * keep the old behavior. Later, the behavior can be changed
  50         * to tree-wide, keeping the warning for a while, and
  51         * eventually we can drop the warning.
  52         */
  53        warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
  54                  "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
  55                  "To add content for the whole tree, run:\n"
  56                  "\n"
  57                  "  git add %s :/\n"
  58                  "  (or git add %s :/)\n"
  59                  "\n"
  60                  "To restrict the command to the current directory, run:\n"
  61                  "\n"
  62                  "  git add %s .\n"
  63                  "  (or git add %s .)\n"
  64                  "\n"
  65                  "With the current Git version, the command is restricted to "
  66                  "the current directory.\n"
  67                  ""),
  68                option_with_implicit_dot, short_option_with_implicit_dot,
  69                option_with_implicit_dot, short_option_with_implicit_dot,
  70                option_with_implicit_dot, short_option_with_implicit_dot);
  71}
  72
  73static int fix_unmerged_status(struct diff_filepair *p,
  74                               struct update_callback_data *data)
  75{
  76        if (p->status != DIFF_STATUS_UNMERGED)
  77                return p->status;
  78        if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
  79                /*
  80                 * This is not an explicit add request, and the
  81                 * path is missing from the working tree (deleted)
  82                 */
  83                return DIFF_STATUS_DELETED;
  84        else
  85                /*
  86                 * Either an explicit add request, or path exists
  87                 * in the working tree.  An attempt to explicitly
  88                 * add a path that does not exist in the working tree
  89                 * will be caught as an error by the caller immediately.
  90                 */
  91                return DIFF_STATUS_MODIFIED;
  92}
  93
  94static void update_callback(struct diff_queue_struct *q,
  95                            struct diff_options *opt, void *cbdata)
  96{
  97        int i;
  98        struct update_callback_data *data = cbdata;
  99
 100        for (i = 0; i < q->nr; i++) {
 101                struct diff_filepair *p = q->queue[i];
 102                const char *path = p->one->path;
 103                switch (fix_unmerged_status(p, data)) {
 104                default:
 105                        die(_("unexpected diff status %c"), p->status);
 106                case DIFF_STATUS_MODIFIED:
 107                case DIFF_STATUS_TYPE_CHANGED:
 108                        if (add_file_to_index(&the_index, path, data->flags)) {
 109                                if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
 110                                        die(_("updating files failed"));
 111                                data->add_errors++;
 112                        }
 113                        break;
 114                case DIFF_STATUS_DELETED:
 115                        if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
 116                                break;
 117                        if (!(data->flags & ADD_CACHE_PRETEND))
 118                                remove_file_from_index(&the_index, path);
 119                        if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
 120                                printf(_("remove '%s'\n"), path);
 121                        break;
 122                }
 123        }
 124}
 125
 126int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
 127{
 128        struct update_callback_data data;
 129        struct rev_info rev;
 130        init_revisions(&rev, prefix);
 131        setup_revisions(0, NULL, &rev, NULL);
 132        init_pathspec(&rev.prune_data, pathspec);
 133        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
 134        rev.diffopt.format_callback = update_callback;
 135        data.flags = flags;
 136        data.add_errors = 0;
 137        rev.diffopt.format_callback_data = &data;
 138        rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
 139        run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
 140        return !!data.add_errors;
 141}
 142
 143static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
 144{
 145        char *seen;
 146        int i, specs;
 147        struct dir_entry **src, **dst;
 148
 149        for (specs = 0; pathspec[specs];  specs++)
 150                /* nothing */;
 151        seen = xcalloc(specs, 1);
 152
 153        src = dst = dir->entries;
 154        i = dir->nr;
 155        while (--i >= 0) {
 156                struct dir_entry *entry = *src++;
 157                if (match_pathspec(pathspec, entry->name, entry->len,
 158                                   prefix, seen))
 159                        *dst++ = entry;
 160        }
 161        dir->nr = dst - dir->entries;
 162        add_pathspec_matches_against_index(pathspec, seen, specs);
 163        return seen;
 164}
 165
 166/*
 167 * Checks the index to see whether any path in pathspec refers to
 168 * something inside a submodule.  If so, dies with an error message.
 169 */
 170static void treat_gitlinks(const char **pathspec)
 171{
 172        int i;
 173
 174        if (!pathspec || !*pathspec)
 175                return;
 176
 177        for (i = 0; pathspec[i]; i++)
 178                pathspec[i] = check_path_for_gitlink(pathspec[i]);
 179}
 180
 181static void refresh(int verbose, const char **pathspec)
 182{
 183        char *seen;
 184        int i, specs;
 185
 186        for (specs = 0; pathspec[specs];  specs++)
 187                /* nothing */;
 188        seen = xcalloc(specs, 1);
 189        refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
 190                      pathspec, seen, _("Unstaged changes after refreshing the index:"));
 191        for (i = 0; i < specs; i++) {
 192                if (!seen[i])
 193                        die(_("pathspec '%s' did not match any files"), pathspec[i]);
 194        }
 195        free(seen);
 196}
 197
 198/*
 199 * Normalizes argv relative to prefix, via get_pathspec(), and then
 200 * runs die_if_path_beyond_symlink() on each path in the normalized
 201 * list.
 202 */
 203static const char **validate_pathspec(const char **argv, const char *prefix)
 204{
 205        const char **pathspec = get_pathspec(prefix, argv);
 206
 207        if (pathspec) {
 208                const char **p;
 209                for (p = pathspec; *p; p++) {
 210                        die_if_path_beyond_symlink(*p, prefix);
 211                }
 212        }
 213
 214        return pathspec;
 215}
 216
 217int run_add_interactive(const char *revision, const char *patch_mode,
 218                        const char **pathspec)
 219{
 220        int status, ac, pc = 0;
 221        const char **args;
 222
 223        if (pathspec)
 224                while (pathspec[pc])
 225                        pc++;
 226
 227        args = xcalloc(sizeof(const char *), (pc + 5));
 228        ac = 0;
 229        args[ac++] = "add--interactive";
 230        if (patch_mode)
 231                args[ac++] = patch_mode;
 232        if (revision)
 233                args[ac++] = revision;
 234        args[ac++] = "--";
 235        if (pc) {
 236                memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
 237                ac += pc;
 238        }
 239        args[ac] = NULL;
 240
 241        status = run_command_v_opt(args, RUN_GIT_CMD);
 242        free(args);
 243        return status;
 244}
 245
 246int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 247{
 248        const char **pathspec = NULL;
 249
 250        if (argc) {
 251                pathspec = validate_pathspec(argv, prefix);
 252                if (!pathspec)
 253                        return -1;
 254        }
 255
 256        return run_add_interactive(NULL,
 257                                   patch ? "--patch" : NULL,
 258                                   pathspec);
 259}
 260
 261static int edit_patch(int argc, const char **argv, const char *prefix)
 262{
 263        char *file = git_pathdup("ADD_EDIT.patch");
 264        const char *apply_argv[] = { "apply", "--recount", "--cached",
 265                NULL, NULL };
 266        struct child_process child;
 267        struct rev_info rev;
 268        int out;
 269        struct stat st;
 270
 271        apply_argv[3] = file;
 272
 273        git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 274
 275        if (read_cache() < 0)
 276                die (_("Could not read the index"));
 277
 278        init_revisions(&rev, prefix);
 279        rev.diffopt.context = 7;
 280
 281        argc = setup_revisions(argc, argv, &rev, NULL);
 282        rev.diffopt.output_format = DIFF_FORMAT_PATCH;
 283        DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
 284        out = open(file, O_CREAT | O_WRONLY, 0666);
 285        if (out < 0)
 286                die (_("Could not open '%s' for writing."), file);
 287        rev.diffopt.file = xfdopen(out, "w");
 288        rev.diffopt.close_file = 1;
 289        if (run_diff_files(&rev, 0))
 290                die (_("Could not write patch"));
 291
 292        launch_editor(file, NULL, NULL);
 293
 294        if (stat(file, &st))
 295                die_errno(_("Could not stat '%s'"), file);
 296        if (!st.st_size)
 297                die(_("Empty patch. Aborted."));
 298
 299        memset(&child, 0, sizeof(child));
 300        child.git_cmd = 1;
 301        child.argv = apply_argv;
 302        if (run_command(&child))
 303                die (_("Could not apply '%s'"), file);
 304
 305        unlink(file);
 306        free(file);
 307        return 0;
 308}
 309
 310static struct lock_file lock_file;
 311
 312static const char ignore_error[] =
 313N_("The following paths are ignored by one of your .gitignore files:\n");
 314
 315static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
 316static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
 317
 318static struct option builtin_add_options[] = {
 319        OPT__DRY_RUN(&show_only, N_("dry run")),
 320        OPT__VERBOSE(&verbose, N_("be verbose")),
 321        OPT_GROUP(""),
 322        OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
 323        OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
 324        OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
 325        OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
 326        OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
 327        OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
 328        OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
 329        OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
 330        OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
 331        OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
 332        OPT_END(),
 333};
 334
 335static int add_config(const char *var, const char *value, void *cb)
 336{
 337        if (!strcmp(var, "add.ignoreerrors") ||
 338            !strcmp(var, "add.ignore-errors")) {
 339                ignore_add_errors = git_config_bool(var, value);
 340                return 0;
 341        }
 342        return git_default_config(var, value, cb);
 343}
 344
 345static int add_files(struct dir_struct *dir, int flags)
 346{
 347        int i, exit_status = 0;
 348
 349        if (dir->ignored_nr) {
 350                fprintf(stderr, _(ignore_error));
 351                for (i = 0; i < dir->ignored_nr; i++)
 352                        fprintf(stderr, "%s\n", dir->ignored[i]->name);
 353                fprintf(stderr, _("Use -f if you really want to add them.\n"));
 354                die(_("no files added"));
 355        }
 356
 357        for (i = 0; i < dir->nr; i++)
 358                if (add_file_to_cache(dir->entries[i]->name, flags)) {
 359                        if (!ignore_add_errors)
 360                                die(_("adding files failed"));
 361                        exit_status = 1;
 362                }
 363        return exit_status;
 364}
 365
 366int cmd_add(int argc, const char **argv, const char *prefix)
 367{
 368        int exit_status = 0;
 369        int newfd;
 370        const char **pathspec;
 371        struct dir_struct dir;
 372        int flags;
 373        int add_new_files;
 374        int require_pathspec;
 375        char *seen = NULL;
 376
 377        git_config(add_config, NULL);
 378
 379        argc = parse_options(argc, argv, prefix, builtin_add_options,
 380                          builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
 381        if (patch_interactive)
 382                add_interactive = 1;
 383        if (add_interactive)
 384                exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
 385
 386        if (edit_interactive)
 387                return(edit_patch(argc, argv, prefix));
 388        argc--;
 389        argv++;
 390
 391        if (addremove && take_worktree_changes)
 392                die(_("-A and -u are mutually incompatible"));
 393        if (!show_only && ignore_missing)
 394                die(_("Option --ignore-missing can only be used together with --dry-run"));
 395        if (addremove) {
 396                option_with_implicit_dot = "--all";
 397                short_option_with_implicit_dot = "-A";
 398        }
 399        if (take_worktree_changes) {
 400                option_with_implicit_dot = "--update";
 401                short_option_with_implicit_dot = "-u";
 402        }
 403        if (option_with_implicit_dot && !argc) {
 404                static const char *here[2] = { ".", NULL };
 405                if (prefix)
 406                        warn_pathless_add();
 407                argc = 1;
 408                argv = here;
 409        }
 410
 411        add_new_files = !take_worktree_changes && !refresh_only;
 412        require_pathspec = !take_worktree_changes;
 413
 414        newfd = hold_locked_index(&lock_file, 1);
 415
 416        flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
 417                 (show_only ? ADD_CACHE_PRETEND : 0) |
 418                 (intent_to_add ? ADD_CACHE_INTENT : 0) |
 419                 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
 420                 (!(addremove || take_worktree_changes)
 421                  ? ADD_CACHE_IGNORE_REMOVAL : 0));
 422
 423        if (require_pathspec && argc == 0) {
 424                fprintf(stderr, _("Nothing specified, nothing added.\n"));
 425                fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
 426                return 0;
 427        }
 428        pathspec = validate_pathspec(argv, prefix);
 429
 430        if (read_cache() < 0)
 431                die(_("index file corrupt"));
 432        treat_gitlinks(pathspec);
 433
 434        if (add_new_files) {
 435                int baselen;
 436
 437                /* Set up the default git porcelain excludes */
 438                memset(&dir, 0, sizeof(dir));
 439                if (!ignored_too) {
 440                        dir.flags |= DIR_COLLECT_IGNORED;
 441                        setup_standard_excludes(&dir);
 442                }
 443
 444                /* This picks up the paths that are not tracked */
 445                baselen = fill_directory(&dir, pathspec);
 446                if (pathspec)
 447                        seen = prune_directory(&dir, pathspec, baselen);
 448        }
 449
 450        if (refresh_only) {
 451                refresh(verbose, pathspec);
 452                goto finish;
 453        }
 454
 455        if (pathspec) {
 456                int i;
 457                struct path_exclude_check check;
 458
 459                path_exclude_check_init(&check, &dir);
 460                if (!seen)
 461                        seen = find_pathspecs_matching_against_index(pathspec);
 462                for (i = 0; pathspec[i]; i++) {
 463                        if (!seen[i] && pathspec[i][0]
 464                            && !file_exists(pathspec[i])) {
 465                                if (ignore_missing) {
 466                                        int dtype = DT_UNKNOWN;
 467                                        if (is_path_excluded(&check, pathspec[i], -1, &dtype))
 468                                                dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
 469                                } else
 470                                        die(_("pathspec '%s' did not match any files"),
 471                                            pathspec[i]);
 472                        }
 473                }
 474                free(seen);
 475                path_exclude_check_clear(&check);
 476        }
 477
 478        plug_bulk_checkin();
 479
 480        exit_status |= add_files_to_cache(prefix, pathspec, flags);
 481
 482        if (add_new_files)
 483                exit_status |= add_files(&dir, flags);
 484
 485        unplug_bulk_checkin();
 486
 487 finish:
 488        if (active_cache_changed) {
 489                if (write_cache(newfd, active_cache, active_nr) ||
 490                    commit_locked_index(&lock_file))
 491                        die(_("Unable to write new index file"));
 492        }
 493
 494        return exit_status;
 495}