f8f6c9ed34541a3ed3426c0922dfc70704efff65
   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 int fix_unmerged_status(struct diff_filepair *p,
  32                               struct update_callback_data *data)
  33{
  34        if (p->status != DIFF_STATUS_UNMERGED)
  35                return p->status;
  36        if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
  37                /*
  38                 * This is not an explicit add request, and the
  39                 * path is missing from the working tree (deleted)
  40                 */
  41                return DIFF_STATUS_DELETED;
  42        else
  43                /*
  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.
  48                 */
  49                return DIFF_STATUS_MODIFIED;
  50}
  51
  52static void update_callback(struct diff_queue_struct *q,
  53                            struct diff_options *opt, void *cbdata)
  54{
  55        int i;
  56        struct update_callback_data *data = cbdata;
  57
  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++;
  70                        }
  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;
  80                }
  81        }
  82}
  83
  84int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
  85{
  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;
  99}
 100
 101static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
 102{
 103        char *seen;
 104        int i, specs;
 105        struct dir_entry **src, **dst;
 106
 107        for (specs = 0; pathspec[specs];  specs++)
 108                /* nothing */;
 109        seen = xcalloc(specs, 1);
 110
 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;
 118        }
 119        dir->nr = dst - dir->entries;
 120        add_pathspec_matches_against_index(pathspec, seen, specs);
 121        return seen;
 122}
 123
 124/*
 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.
 127 */
 128static void treat_gitlinks(const char **pathspec)
 129{
 130        int i;
 131
 132        if (!pathspec || !*pathspec)
 133                return;
 134
 135        for (i = 0; pathspec[i]; i++)
 136                pathspec[i] = check_path_for_gitlink(pathspec[i]);
 137}
 138
 139static void refresh(int verbose, const char **pathspec)
 140{
 141        char *seen;
 142        int i, specs;
 143
 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]);
 152        }
 153        free(seen);
 154}
 155
 156/*
 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.
 160 */
 161static const char **validate_pathspec(const char **argv, const char *prefix)
 162{
 163        const char **pathspec = get_pathspec(prefix, argv);
 164
 165        if (pathspec) {
 166                const char **p;
 167                for (p = pathspec; *p; p++) {
 168                        die_if_path_beyond_symlink(*p, prefix);
 169                }
 170        }
 171
 172        return pathspec;
 173}
 174
 175int run_add_interactive(const char *revision, const char *patch_mode,
 176                        const char **pathspec)
 177{
 178        int status, ac, pc = 0;
 179        const char **args;
 180
 181        if (pathspec)
 182                while (pathspec[pc])
 183                        pc++;
 184
 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;
 196        }
 197        args[ac] = NULL;
 198
 199        status = run_command_v_opt(args, RUN_GIT_CMD);
 200        free(args);
 201        return status;
 202}
 203
 204int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 205{
 206        const char **pathspec = NULL;
 207
 208        if (argc) {
 209                pathspec = validate_pathspec(argv, prefix);
 210                if (!pathspec)
 211                        return -1;
 212        }
 213
 214        return run_add_interactive(NULL,
 215                                   patch ? "--patch" : NULL,
 216                                   pathspec);
 217}
 218
 219static int edit_patch(int argc, const char **argv, const char *prefix)
 220{
 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;
 228
 229        apply_argv[3] = file;
 230
 231        git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 232
 233        if (read_cache() < 0)
 234                die (_("Could not read the index"));
 235
 236        init_revisions(&rev, prefix);
 237        rev.diffopt.context = 7;
 238
 239        argc = setup_revisions(argc, argv, &rev, NULL);
 240        rev.diffopt.output_format = DIFF_FORMAT_PATCH;
 241        DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
 242        out = open(file, O_CREAT | O_WRONLY, 0666);
 243        if (out < 0)
 244                die (_("Could not open '%s' for writing."), file);
 245        rev.diffopt.file = xfdopen(out, "w");
 246        rev.diffopt.close_file = 1;
 247        if (run_diff_files(&rev, 0))
 248                die (_("Could not write patch"));
 249
 250        launch_editor(file, NULL, NULL);
 251
 252        if (stat(file, &st))
 253                die_errno(_("Could not stat '%s'"), file);
 254        if (!st.st_size)
 255                die(_("Empty patch. Aborted."));
 256
 257        memset(&child, 0, sizeof(child));
 258        child.git_cmd = 1;
 259        child.argv = apply_argv;
 260        if (run_command(&child))
 261                die (_("Could not apply '%s'"), file);
 262
 263        unlink(file);
 264        free(file);
 265        return 0;
 266}
 267
 268static struct lock_file lock_file;
 269
 270static const char ignore_error[] =
 271N_("The following paths are ignored by one of your .gitignore files:\n");
 272
 273static int verbose, show_only, ignored_too, refresh_only;
 274static int ignore_add_errors, intent_to_add, ignore_missing;
 275
 276#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
 277static int addremove = ADDREMOVE_DEFAULT;
 278static int addremove_explicit = -1; /* unspecified */
 279
 280static struct option builtin_add_options[] = {
 281        OPT__DRY_RUN(&show_only, N_("dry run")),
 282        OPT__VERBOSE(&verbose, N_("be verbose")),
 283        OPT_GROUP(""),
 284        OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
 285        OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
 286        OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
 287        OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
 288        OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
 289        OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
 290        OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
 291        OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
 292        OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
 293        OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
 294        OPT_END(),
 295};
 296
 297static int add_config(const char *var, const char *value, void *cb)
 298{
 299        if (!strcmp(var, "add.ignoreerrors") ||
 300            !strcmp(var, "add.ignore-errors")) {
 301                ignore_add_errors = git_config_bool(var, value);
 302                return 0;
 303        }
 304        return git_default_config(var, value, cb);
 305}
 306
 307static int add_files(struct dir_struct *dir, int flags)
 308{
 309        int i, exit_status = 0;
 310
 311        if (dir->ignored_nr) {
 312                fprintf(stderr, _(ignore_error));
 313                for (i = 0; i < dir->ignored_nr; i++)
 314                        fprintf(stderr, "%s\n", dir->ignored[i]->name);
 315                fprintf(stderr, _("Use -f if you really want to add them.\n"));
 316                die(_("no files added"));
 317        }
 318
 319        for (i = 0; i < dir->nr; i++)
 320                if (add_file_to_cache(dir->entries[i]->name, flags)) {
 321                        if (!ignore_add_errors)
 322                                die(_("adding files failed"));
 323                        exit_status = 1;
 324                }
 325        return exit_status;
 326}
 327
 328static void warn_pathless_add(const char *option_name, const char *short_name) {
 329        /*
 330         * To be consistent with "git add -p" and most Git
 331         * commands, we should default to being tree-wide, but
 332         * this is not the original behavior and can't be
 333         * changed until users trained themselves not to type
 334         * "git add -u" or "git add -A". For now, we warn and
 335         * keep the old behavior. Later, this warning can be
 336         * turned into a die(...), and eventually we may
 337         * reallow the command with a new behavior.
 338         */
 339        warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
 340                  "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
 341                  "To add content for the whole tree, run:\n"
 342                  "\n"
 343                  "  git add %s :/\n"
 344                  "  (or git add %s :/)\n"
 345                  "\n"
 346                  "To restrict the command to the current directory, run:\n"
 347                  "\n"
 348                  "  git add %s .\n"
 349                  "  (or git add %s .)\n"
 350                  "\n"
 351                  "With the current Git version, the command is restricted to the current directory."),
 352                option_name, short_name,
 353                option_name, short_name,
 354                option_name, short_name);
 355}
 356
 357static int directory_given(int argc, const char **argv)
 358{
 359        struct stat st;
 360
 361        while (argc--) {
 362                if (!lstat(*argv, &st) && S_ISDIR(st.st_mode))
 363                        return 1;
 364                argv++;
 365        }
 366        return 0;
 367}
 368
 369int cmd_add(int argc, const char **argv, const char *prefix)
 370{
 371        int exit_status = 0;
 372        int newfd;
 373        const char **pathspec;
 374        struct dir_struct dir;
 375        int flags;
 376        int add_new_files;
 377        int require_pathspec;
 378        char *seen = NULL;
 379        const char *option_with_implicit_dot = NULL;
 380        const char *short_option_with_implicit_dot = NULL;
 381
 382        git_config(add_config, NULL);
 383
 384        argc = parse_options(argc, argv, prefix, builtin_add_options,
 385                          builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
 386        if (patch_interactive)
 387                add_interactive = 1;
 388        if (add_interactive)
 389                exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
 390
 391        if (edit_interactive)
 392                return(edit_patch(argc, argv, prefix));
 393        argc--;
 394        argv++;
 395
 396        if (0 <= addremove_explicit)
 397                addremove = addremove_explicit;
 398        else if (take_worktree_changes && ADDREMOVE_DEFAULT)
 399                addremove = 0; /* "-u" was given but not "-A" */
 400
 401        if (addremove && take_worktree_changes)
 402                die(_("-A and -u are mutually incompatible"));
 403
 404        /*
 405         * Warn when "git add pathspec..." was given without "-u" or "-A"
 406         * and pathspec... contains a directory name.
 407         */
 408        if (!take_worktree_changes && addremove_explicit < 0 &&
 409            directory_given(argc, argv))
 410                warning(_("In Git 2.0, 'git add <pathspec>...' will also update the\n"
 411                          "index for paths removed from the working tree that match\n"
 412                          "the given pathspec. If you want to 'add' only changed\n"
 413                          "or newly created paths, say 'git add --no-all <pathspec>...'"
 414                          " instead."));
 415
 416        if (!take_worktree_changes && addremove_explicit < 0 && argc)
 417                /*
 418                 * Turn "git add pathspec..." to "git add -A pathspec..."
 419                 * in Git 2.0 but not yet
 420                 */
 421                ; /* addremove = 1; */
 422
 423        if (!show_only && ignore_missing)
 424                die(_("Option --ignore-missing can only be used together with --dry-run"));
 425        if (addremove) {
 426                option_with_implicit_dot = "--all";
 427                short_option_with_implicit_dot = "-A";
 428        }
 429        if (take_worktree_changes) {
 430                option_with_implicit_dot = "--update";
 431                short_option_with_implicit_dot = "-u";
 432        }
 433        if (option_with_implicit_dot && !argc) {
 434                static const char *here[2] = { ".", NULL };
 435                if (prefix)
 436                        warn_pathless_add(option_with_implicit_dot,
 437                                          short_option_with_implicit_dot);
 438                argc = 1;
 439                argv = here;
 440        }
 441
 442        add_new_files = !take_worktree_changes && !refresh_only;
 443        require_pathspec = !take_worktree_changes;
 444
 445        newfd = hold_locked_index(&lock_file, 1);
 446
 447        flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
 448                 (show_only ? ADD_CACHE_PRETEND : 0) |
 449                 (intent_to_add ? ADD_CACHE_INTENT : 0) |
 450                 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
 451                 (!(addremove || take_worktree_changes)
 452                  ? ADD_CACHE_IGNORE_REMOVAL : 0));
 453
 454        if (require_pathspec && argc == 0) {
 455                fprintf(stderr, _("Nothing specified, nothing added.\n"));
 456                fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
 457                return 0;
 458        }
 459        pathspec = validate_pathspec(argv, prefix);
 460
 461        if (read_cache() < 0)
 462                die(_("index file corrupt"));
 463        treat_gitlinks(pathspec);
 464
 465        if (add_new_files) {
 466                int baselen;
 467
 468                /* Set up the default git porcelain excludes */
 469                memset(&dir, 0, sizeof(dir));
 470                if (!ignored_too) {
 471                        dir.flags |= DIR_COLLECT_IGNORED;
 472                        setup_standard_excludes(&dir);
 473                }
 474
 475                /* This picks up the paths that are not tracked */
 476                baselen = fill_directory(&dir, pathspec);
 477                if (pathspec)
 478                        seen = prune_directory(&dir, pathspec, baselen);
 479        }
 480
 481        if (refresh_only) {
 482                refresh(verbose, pathspec);
 483                goto finish;
 484        }
 485
 486        if (pathspec) {
 487                int i;
 488                struct path_exclude_check check;
 489
 490                path_exclude_check_init(&check, &dir);
 491                if (!seen)
 492                        seen = find_pathspecs_matching_against_index(pathspec);
 493                for (i = 0; pathspec[i]; i++) {
 494                        if (!seen[i] && pathspec[i][0]
 495                            && !file_exists(pathspec[i])) {
 496                                if (ignore_missing) {
 497                                        int dtype = DT_UNKNOWN;
 498                                        if (is_path_excluded(&check, pathspec[i], -1, &dtype))
 499                                                dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
 500                                } else
 501                                        die(_("pathspec '%s' did not match any files"),
 502                                            pathspec[i]);
 503                        }
 504                }
 505                free(seen);
 506                path_exclude_check_clear(&check);
 507        }
 508
 509        plug_bulk_checkin();
 510
 511        exit_status |= add_files_to_cache(prefix, pathspec, flags);
 512
 513        if (add_new_files)
 514                exit_status |= add_files(&dir, flags);
 515
 516        unplug_bulk_checkin();
 517
 518 finish:
 519        if (active_cache_changed) {
 520                if (write_cache(newfd, active_cache, active_nr) ||
 521                    commit_locked_index(&lock_file))
 522                        die(_("Unable to write new index file"));
 523        }
 524
 525        return exit_status;
 526}