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