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