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"
  22static 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;
  30struct update_callback_data {
  32        int flags;
  33        int add_errors;
  34};
  35static void chmod_pathspec(struct pathspec *pathspec, char flip)
  37{
  38        int i;
  39        for (i = 0; i < active_nr; i++) {
  41                struct cache_entry *ce = active_cache[i];
  42                if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
  44                        continue;
  45                if (chmod_cache_entry(ce, flip) < 0)
  47                        fprintf(stderr, "cannot chmod %cx '%s'\n", flip, ce->name);
  48        }
  49}
  50static 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}
  71static 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        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}
 103int 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        memset(&data, 0, sizeof(data));
 111        data.flags = flags;
 112        repo_init_revisions(the_repository, &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}
 126static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
 128{
 129        int i, retval = 0;
 130        for (i = 0; i < active_nr; i++) {
 132                struct cache_entry *ce = active_cache[i];
 133                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(&the_index, ce, pathspec, NULL))
 139                        continue;
 140                retval |= add_file_to_cache(ce->name, flags | HASH_RENORMALIZE);
 141        }
 142        return retval;
 144}
 145static 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        seen = xcalloc(pathspec->nr, 1);
 153        src = dst = dir->entries;
 155        i = dir->nr;
 156        while (--i >= 0) {
 157                struct dir_entry *entry = *src++;
 158                if (dir_path_match(&the_index, 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}
 165static void refresh(int verbose, const struct pathspec *pathspec)
 167{
 168        char *seen;
 169        int i;
 170        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}
 181int 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        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        status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
 199        argv_array_clear(&argv);
 200        return status;
 201}
 202int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 204{
 205        struct pathspec pathspec;
 206        parse_pathspec(&pathspec, 0,
 208                       PATHSPEC_PREFER_FULL |
 209                       PATHSPEC_SYMLINK_LEADING_PATH |
 210                       PATHSPEC_PREFIX_ORIGIN,
 211                       prefix, argv);
 212        return run_add_interactive(NULL,
 214                                   patch ? "--patch" : NULL,
 215                                   &pathspec);
 216}
 217static 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        apply_argv[3] = file;
 229        git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 231        if (read_cache() < 0)
 233                die(_("Could not read the index"));
 234        repo_init_revisions(the_repository, &rev, prefix);
 236        rev.diffopt.context = 7;
 237        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        if (launch_editor(file, NULL, NULL))
 251                die(_("editing patch failed"));
 252        if (stat(file, &st))
 254                die_errno(_("Could not stat '%s'"), file);
 255        if (!st.st_size)
 256                die(_("Empty patch. Aborted."));
 257        child.git_cmd = 1;
 259        child.argv = apply_argv;
 260        if (run_command(&child))
 261                die(_("Could not apply '%s'"), file);
 262        unlink(file);
 264        free(file);
 265        return 0;
 266}
 267static const char ignore_error[] =
 269N_("The following paths are ignored by one of your .gitignore files:\n");
 270static int verbose, show_only, ignored_too, refresh_only;
 272static int ignore_add_errors, intent_to_add, ignore_missing;
 273static int warn_on_embedded_repo = 1;
 274#define ADDREMOVE_DEFAULT 1
 276static int addremove = ADDREMOVE_DEFAULT;
 277static int addremove_explicit = -1; /* unspecified */
 278static char *chmod_arg;
 280static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
 282{
 283        /* if we are told to ignore, we are not adding removals */
 284        *(int *)opt->value = !unset ? 0 : 1;
 285        return 0;
 286}
 287static struct option builtin_add_options[] = {
 289        OPT__DRY_RUN(&show_only, N_("dry run")),
 290        OPT__VERBOSE(&verbose, N_("be verbose")),
 291        OPT_GROUP(""),
 292        OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
 293        OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
 294        OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
 295        OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
 296        OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
 297        OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
 298        OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
 299        OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
 300        { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
 301          NULL /* takes no arguments */,
 302          N_("ignore paths removed in the working tree (same as --no-all)"),
 303          PARSE_OPT_NOARG, ignore_removal_cb },
 304        OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
 305        OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
 306        OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
 307        OPT_STRING(0, "chmod", &chmod_arg, "(+|-)x",
 308                   N_("override the executable bit of the listed files")),
 309        OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
 310                        N_("warn when adding an embedded repository")),
 311        OPT_END(),
 312};
 313static int add_config(const char *var, const char *value, void *cb)
 315{
 316        if (!strcmp(var, "add.ignoreerrors") ||
 317            !strcmp(var, "add.ignore-errors")) {
 318                ignore_add_errors = git_config_bool(var, value);
 319                return 0;
 320        }
 321        return git_default_config(var, value, cb);
 322}
 323static const char embedded_advice[] = N_(
 325"You've added another git repository inside your current repository.\n"
 326"Clones of the outer repository will not contain the contents of\n"
 327"the embedded repository and will not know how to obtain it.\n"
 328"If you meant to add a submodule, use:\n"
 329"\n"
 330"       git submodule add <url> %s\n"
 331"\n"
 332"If you added this path by mistake, you can remove it from the\n"
 333"index with:\n"
 334"\n"
 335"       git rm --cached %s\n"
 336"\n"
 337"See \"git help submodule\" for more information."
 338);
 339static void check_embedded_repo(const char *path)
 341{
 342        struct strbuf name = STRBUF_INIT;
 343        if (!warn_on_embedded_repo)
 345                return;
 346        if (!ends_with(path, "/"))
 347                return;
 348        /* Drop trailing slash for aesthetics */
 350        strbuf_addstr(&name, path);
 351        strbuf_strip_suffix(&name, "/");
 352        warning(_("adding embedded git repository: %s"), name.buf);
 354        if (advice_add_embedded_repo) {
 355                advise(embedded_advice, name.buf, name.buf);
 356                /* there may be multiple entries; advise only once */
 357                advice_add_embedded_repo = 0;
 358        }
 359        strbuf_release(&name);
 361}
 362static int add_files(struct dir_struct *dir, int flags)
 364{
 365        int i, exit_status = 0;
 366        if (dir->ignored_nr) {
 368                fprintf(stderr, _(ignore_error));
 369                for (i = 0; i < dir->ignored_nr; i++)
 370                        fprintf(stderr, "%s\n", dir->ignored[i]->name);
 371                fprintf(stderr, _("Use -f if you really want to add them.\n"));
 372                exit_status = 1;
 373        }
 374        for (i = 0; i < dir->nr; i++) {
 376                check_embedded_repo(dir->entries[i]->name);
 377                if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
 378                        if (!ignore_add_errors)
 379                                die(_("adding files failed"));
 380                        exit_status = 1;
 381                }
 382        }
 383        return exit_status;
 384}
 385int cmd_add(int argc, const char **argv, const char *prefix)
 387{
 388        int exit_status = 0;
 389        struct pathspec pathspec;
 390        struct dir_struct dir;
 391        int flags;
 392        int add_new_files;
 393        int require_pathspec;
 394        char *seen = NULL;
 395        struct lock_file lock_file = LOCK_INIT;
 396        git_config(add_config, NULL);
 398        argc = parse_options(argc, argv, prefix, builtin_add_options,
 400                          builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
 401        if (patch_interactive)
 402                add_interactive = 1;
 403        if (add_interactive)
 404                exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
 405        if (edit_interactive)
 407                return(edit_patch(argc, argv, prefix));
 408        argc--;
 409        argv++;
 410        if (0 <= addremove_explicit)
 412                addremove = addremove_explicit;
 413        else if (take_worktree_changes && ADDREMOVE_DEFAULT)
 414                addremove = 0; /* "-u" was given but not "-A" */
 415        if (addremove && take_worktree_changes)
 417                die(_("-A and -u are mutually incompatible"));
 418        if (!take_worktree_changes && addremove_explicit < 0 && argc)
 420                /* Turn "git add pathspec..." to "git add -A pathspec..." */
 421                addremove = 1;
 422        if (!show_only && ignore_missing)
 424                die(_("Option --ignore-missing can only be used together with --dry-run"));
 425        if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
 427                          chmod_arg[1] != 'x' || chmod_arg[2]))
 428                die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
 429        add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
 431        require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
 432        hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
 434        flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
 436                 (show_only ? ADD_CACHE_PRETEND : 0) |
 437                 (intent_to_add ? ADD_CACHE_INTENT : 0) |
 438                 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
 439                 (!(addremove || take_worktree_changes)
 440                  ? ADD_CACHE_IGNORE_REMOVAL : 0));
 441        if (require_pathspec && argc == 0) {
 443                fprintf(stderr, _("Nothing specified, nothing added.\n"));
 444                fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
 445                return 0;
 446        }
 447        /*
 449         * Check the "pathspec '%s' did not match any files" block
 450         * below before enabling new magic.
 451         */
 452        parse_pathspec(&pathspec, PATHSPEC_ATTR,
 453                       PATHSPEC_PREFER_FULL |
 454                       PATHSPEC_SYMLINK_LEADING_PATH,
 455                       prefix, argv);
 456        if (read_cache_preload(&pathspec) < 0)
 458                die(_("index file corrupt"));
 459        die_in_unpopulated_submodule(&the_index, prefix);
 461        die_path_inside_submodule(&the_index, &pathspec);
 462        if (add_new_files) {
 464                int baselen;
 465                /* Set up the default git porcelain excludes */
 467                memset(&dir, 0, sizeof(dir));
 468                if (!ignored_too) {
 469                        dir.flags |= DIR_COLLECT_IGNORED;
 470                        setup_standard_excludes(&dir);
 471                }
 472                /* This picks up the paths that are not tracked */
 474                baselen = fill_directory(&dir, &the_index, &pathspec);
 475                if (pathspec.nr)
 476                        seen = prune_directory(&dir, &pathspec, baselen);
 477        }
 478        if (refresh_only) {
 480                refresh(verbose, &pathspec);
 481                goto finish;
 482        }
 483        if (pathspec.nr) {
 485                int i;
 486                if (!seen)
 488                        seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
 489                /*
 491                 * file_exists() assumes exact match
 492                 */
 493                GUARD_PATHSPEC(&pathspec,
 494                               PATHSPEC_FROMTOP |
 495                               PATHSPEC_LITERAL |
 496                               PATHSPEC_GLOB |
 497                               PATHSPEC_ICASE |
 498                               PATHSPEC_EXCLUDE);
 499                for (i = 0; i < pathspec.nr; i++) {
 501                        const char *path = pathspec.items[i].match;
 502                        if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
 503                                continue;
 504                        if (!seen[i] && path[0] &&
 505                            ((pathspec.items[i].magic &
 506                              (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
 507                             !file_exists(path))) {
 508                                if (ignore_missing) {
 509                                        int dtype = DT_UNKNOWN;
 510                                        if (is_excluded(&dir, &the_index, path, &dtype))
 511                                                dir_add_ignored(&dir, &the_index,
 512                                                                path, pathspec.items[i].len);
 513                                } else
 514                                        die(_("pathspec '%s' did not match any files"),
 515                                            pathspec.items[i].original);
 516                        }
 517                }
 518                free(seen);
 519        }
 520        plug_bulk_checkin();
 522        if (add_renormalize)
 524                exit_status |= renormalize_tracked_files(&pathspec, flags);
 525        else
 526                exit_status |= add_files_to_cache(prefix, &pathspec, flags);
 527        if (add_new_files)
 529                exit_status |= add_files(&dir, flags);
 530        if (chmod_arg && pathspec.nr)
 532                chmod_pathspec(&pathspec, chmod_arg[0]);
 533        unplug_bulk_checkin();
 534finish:
 536        if (write_locked_index(&the_index, &lock_file,
 537                               COMMIT_LOCK | SKIP_IF_UNCHANGED))
 538                die(_("Unable to write new index file"));
 539        UNLEAK(pathspec);
 541        UNLEAK(dir);
 542        return exit_status;
 543}