builtin / add.con commit add: warn when -u or -A is used without pathspec (0fa2eb5)
   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 "exec_cmd.h"
  10#include "cache-tree.h"
  11#include "run-command.h"
  12#include "parse-options.h"
  13#include "diff.h"
  14#include "diffcore.h"
  15#include "revision.h"
  16#include "bulk-checkin.h"
  17
  18static const char * const builtin_add_usage[] = {
  19        N_("git add [options] [--] <filepattern>..."),
  20        NULL
  21};
  22static int patch_interactive, add_interactive, edit_interactive;
  23static int take_worktree_changes;
  24
  25struct update_callback_data {
  26        int flags;
  27        int add_errors;
  28};
  29
  30static int fix_unmerged_status(struct diff_filepair *p,
  31                               struct update_callback_data *data)
  32{
  33        if (p->status != DIFF_STATUS_UNMERGED)
  34                return p->status;
  35        if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
  36                /*
  37                 * This is not an explicit add request, and the
  38                 * path is missing from the working tree (deleted)
  39                 */
  40                return DIFF_STATUS_DELETED;
  41        else
  42                /*
  43                 * Either an explicit add request, or path exists
  44                 * in the working tree.  An attempt to explicitly
  45                 * add a path that does not exist in the working tree
  46                 * will be caught as an error by the caller immediately.
  47                 */
  48                return DIFF_STATUS_MODIFIED;
  49}
  50
  51static void update_callback(struct diff_queue_struct *q,
  52                            struct diff_options *opt, void *cbdata)
  53{
  54        int i;
  55        struct update_callback_data *data = cbdata;
  56
  57        for (i = 0; i < q->nr; i++) {
  58                struct diff_filepair *p = q->queue[i];
  59                const char *path = p->one->path;
  60                switch (fix_unmerged_status(p, data)) {
  61                default:
  62                        die(_("unexpected diff status %c"), p->status);
  63                case DIFF_STATUS_MODIFIED:
  64                case DIFF_STATUS_TYPE_CHANGED:
  65                        if (add_file_to_index(&the_index, path, data->flags)) {
  66                                if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
  67                                        die(_("updating files failed"));
  68                                data->add_errors++;
  69                        }
  70                        break;
  71                case DIFF_STATUS_DELETED:
  72                        if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
  73                                break;
  74                        if (!(data->flags & ADD_CACHE_PRETEND))
  75                                remove_file_from_index(&the_index, path);
  76                        if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
  77                                printf(_("remove '%s'\n"), path);
  78                        break;
  79                }
  80        }
  81}
  82
  83int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
  84{
  85        struct update_callback_data data;
  86        struct rev_info rev;
  87        init_revisions(&rev, prefix);
  88        setup_revisions(0, NULL, &rev, NULL);
  89        init_pathspec(&rev.prune_data, pathspec);
  90        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
  91        rev.diffopt.format_callback = update_callback;
  92        data.flags = flags;
  93        data.add_errors = 0;
  94        rev.diffopt.format_callback_data = &data;
  95        rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
  96        run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
  97        return !!data.add_errors;
  98}
  99
 100static void fill_pathspec_matches(const char **pathspec, char *seen, int specs)
 101{
 102        int num_unmatched = 0, i;
 103
 104        /*
 105         * Since we are walking the index as if we were walking the directory,
 106         * we have to mark the matched pathspec as seen; otherwise we will
 107         * mistakenly think that the user gave a pathspec that did not match
 108         * anything.
 109         */
 110        for (i = 0; i < specs; i++)
 111                if (!seen[i])
 112                        num_unmatched++;
 113        if (!num_unmatched)
 114                return;
 115        for (i = 0; i < active_nr; i++) {
 116                struct cache_entry *ce = active_cache[i];
 117                match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);
 118        }
 119}
 120
 121static char *find_used_pathspec(const char **pathspec)
 122{
 123        char *seen;
 124        int i;
 125
 126        for (i = 0; pathspec[i];  i++)
 127                ; /* just counting */
 128        seen = xcalloc(i, 1);
 129        fill_pathspec_matches(pathspec, seen, i);
 130        return seen;
 131}
 132
 133static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
 134{
 135        char *seen;
 136        int i, specs;
 137        struct dir_entry **src, **dst;
 138
 139        for (specs = 0; pathspec[specs];  specs++)
 140                /* nothing */;
 141        seen = xcalloc(specs, 1);
 142
 143        src = dst = dir->entries;
 144        i = dir->nr;
 145        while (--i >= 0) {
 146                struct dir_entry *entry = *src++;
 147                if (match_pathspec(pathspec, entry->name, entry->len,
 148                                   prefix, seen))
 149                        *dst++ = entry;
 150        }
 151        dir->nr = dst - dir->entries;
 152        fill_pathspec_matches(pathspec, seen, specs);
 153        return seen;
 154}
 155
 156static void treat_gitlinks(const char **pathspec)
 157{
 158        int i;
 159
 160        if (!pathspec || !*pathspec)
 161                return;
 162
 163        for (i = 0; i < active_nr; i++) {
 164                struct cache_entry *ce = active_cache[i];
 165                if (S_ISGITLINK(ce->ce_mode)) {
 166                        int len = ce_namelen(ce), j;
 167                        for (j = 0; pathspec[j]; j++) {
 168                                int len2 = strlen(pathspec[j]);
 169                                if (len2 <= len || pathspec[j][len] != '/' ||
 170                                    memcmp(ce->name, pathspec[j], len))
 171                                        continue;
 172                                if (len2 == len + 1)
 173                                        /* strip trailing slash */
 174                                        pathspec[j] = xstrndup(ce->name, len);
 175                                else
 176                                        die (_("Path '%s' is in submodule '%.*s'"),
 177                                                pathspec[j], len, ce->name);
 178                        }
 179                }
 180        }
 181}
 182
 183static void refresh(int verbose, const char **pathspec)
 184{
 185        char *seen;
 186        int i, specs;
 187
 188        for (specs = 0; pathspec[specs];  specs++)
 189                /* nothing */;
 190        seen = xcalloc(specs, 1);
 191        refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
 192                      pathspec, seen, _("Unstaged changes after refreshing the index:"));
 193        for (i = 0; i < specs; i++) {
 194                if (!seen[i])
 195                        die(_("pathspec '%s' did not match any files"), pathspec[i]);
 196        }
 197        free(seen);
 198}
 199
 200static const char **validate_pathspec(int argc, const char **argv, const char *prefix)
 201{
 202        const char **pathspec = get_pathspec(prefix, argv);
 203
 204        if (pathspec) {
 205                const char **p;
 206                for (p = pathspec; *p; p++) {
 207                        if (has_symlink_leading_path(*p, strlen(*p))) {
 208                                int len = prefix ? strlen(prefix) : 0;
 209                                die(_("'%s' is beyond a symbolic link"), *p + len);
 210                        }
 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(argc, 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
 366static void warn_pathless_add(const char *option_name, const char *short_name) {
 367        /*
 368         * To be consistent with "git add -p" and most Git
 369         * commands, we should default to being tree-wide, but
 370         * this is not the original behavior and can't be
 371         * changed until users trained themselves not to type
 372         * "git add -u" or "git add -A". For now, we warn and
 373         * keep the old behavior. Later, this warning can be
 374         * turned into a die(...), and eventually we may
 375         * reallow the command with a new behavior.
 376         */
 377        warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
 378                  "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
 379                  "To add content for the whole tree, run:\n"
 380                  "\n"
 381                  "  git add %s :/\n"
 382                  "  (or git add %s :/)\n"
 383                  "\n"
 384                  "To restrict the command to the current directory, run:\n"
 385                  "\n"
 386                  "  git add %s .\n"
 387                  "  (or git add %s .)\n"
 388                  "\n"
 389                  "With the current Git version, the command is restricted to the current directory."),
 390                option_name, short_name,
 391                option_name, short_name,
 392                option_name, short_name);
 393}
 394
 395int cmd_add(int argc, const char **argv, const char *prefix)
 396{
 397        int exit_status = 0;
 398        int newfd;
 399        const char **pathspec;
 400        struct dir_struct dir;
 401        int flags;
 402        int add_new_files;
 403        int require_pathspec;
 404        char *seen = NULL;
 405        const char *option_with_implicit_dot = NULL;
 406        const char *short_option_with_implicit_dot = NULL;
 407
 408        git_config(add_config, NULL);
 409
 410        argc = parse_options(argc, argv, prefix, builtin_add_options,
 411                          builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
 412        if (patch_interactive)
 413                add_interactive = 1;
 414        if (add_interactive)
 415                exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
 416
 417        if (edit_interactive)
 418                return(edit_patch(argc, argv, prefix));
 419        argc--;
 420        argv++;
 421
 422        if (addremove && take_worktree_changes)
 423                die(_("-A and -u are mutually incompatible"));
 424        if (!show_only && ignore_missing)
 425                die(_("Option --ignore-missing can only be used together with --dry-run"));
 426        if (addremove) {
 427                option_with_implicit_dot = "--all";
 428                short_option_with_implicit_dot = "-A";
 429        }
 430        if (take_worktree_changes) {
 431                option_with_implicit_dot = "--update";
 432                short_option_with_implicit_dot = "-u";
 433        }
 434        if (option_with_implicit_dot && !argc) {
 435                static const char *here[2] = { ".", NULL };
 436                if (prefix)
 437                        warn_pathless_add(option_with_implicit_dot,
 438                                          short_option_with_implicit_dot);
 439                argc = 1;
 440                argv = here;
 441        }
 442
 443        add_new_files = !take_worktree_changes && !refresh_only;
 444        require_pathspec = !take_worktree_changes;
 445
 446        newfd = hold_locked_index(&lock_file, 1);
 447
 448        flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
 449                 (show_only ? ADD_CACHE_PRETEND : 0) |
 450                 (intent_to_add ? ADD_CACHE_INTENT : 0) |
 451                 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
 452                 (!(addremove || take_worktree_changes)
 453                  ? ADD_CACHE_IGNORE_REMOVAL : 0));
 454
 455        if (require_pathspec && argc == 0) {
 456                fprintf(stderr, _("Nothing specified, nothing added.\n"));
 457                fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
 458                return 0;
 459        }
 460        pathspec = validate_pathspec(argc, argv, prefix);
 461
 462        if (read_cache() < 0)
 463                die(_("index file corrupt"));
 464        treat_gitlinks(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, pathspec);
 478                if (pathspec)
 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) {
 488                int i;
 489                struct path_exclude_check check;
 490
 491                path_exclude_check_init(&check, &dir);
 492                if (!seen)
 493                        seen = find_used_pathspec(pathspec);
 494                for (i = 0; pathspec[i]; i++) {
 495                        if (!seen[i] && pathspec[i][0]
 496                            && !file_exists(pathspec[i])) {
 497                                if (ignore_missing) {
 498                                        int dtype = DT_UNKNOWN;
 499                                        if (path_excluded(&check, pathspec[i], -1, &dtype))
 500                                                dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
 501                                } else
 502                                        die(_("pathspec '%s' did not match any files"),
 503                                            pathspec[i]);
 504                        }
 505                }
 506                free(seen);
 507                path_exclude_check_clear(&check);
 508        }
 509
 510        plug_bulk_checkin();
 511
 512        exit_status |= add_files_to_cache(prefix, pathspec, flags);
 513
 514        if (add_new_files)
 515                exit_status |= add_files(&dir, flags);
 516
 517        unplug_bulk_checkin();
 518
 519 finish:
 520        if (active_cache_changed) {
 521                if (write_cache(newfd, active_cache, active_nr) ||
 522                    commit_locked_index(&lock_file))
 523                        die(_("Unable to write new index file"));
 524        }
 525
 526        return exit_status;
 527}