Merge branch 'rs/no-no-no-parseopt'
authorJunio C Hamano <gitster@pobox.com>
Fri, 2 Mar 2012 04:59:31 +0000 (20:59 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Mar 2012 04:59:31 +0000 (20:59 -0800)
* rs/no-no-no-parseopt:
parse-options: remove PARSE_OPT_NEGHELP
parse-options: allow positivation of options starting, with no-
test-parse-options: convert to OPT_BOOL()

Conflicts:
builtin/grep.c

1  2 
Documentation/RelNotes/1.7.10.txt
builtin/fast-export.c
builtin/grep.c
index 70d76b5dc0bd79647d78d37cab1367ad1700d62e,0000000000000000000000000000000000000000..071e40c59bf6abbcf18e254d214a723888d2422d
mode 100644,000000..100644
--- /dev/null
@@@ -1,133 -1,0 +1,150 @@@
- O=v1.7.9.2-322-g472fdee
 +Git v1.7.10 Release Notes
 +=========================
 +
 +Updates since v1.7.9
 +--------------------
 +
 +UI, Workflows & Features
 +
++ * Teams for localizing the messages from the Porcelain layer of
++   commands are starting to form, thanks to Jiang Xin who volunteered
++   to be the localization coordinator.  An initial set of translated
++   messages for simplified chinese is available.
++
 + * Improved handling of views, labels and branches in git-p4 (in contrib).
 +
 + * "git-p4" (in contrib) suffered from unnecessary merge conflicts when
 +   p4 expanded the embedded $RCS$-like keywords; it can be now told to
 +   unexpand them.
 +
 + * Some "git-svn" updates.
 +
 + * "vcs-svn"/"svn-fe" learned to read dumps with svn-deltas and
 +   support incremental imports.
 +
 + * The configuration mechanism learned an "include" facility; an
 +   assignment to the include.path pseudo-variable causes the named
 +   file to be included in-place when Git looks up configuration
 +   variables.
 +
 + * A content filter (clean/smudge) used to be just a way to make the
 +   recorded contents "more useful", and allowed to fail; a filter can
 +   new optionally be marked as "required".
 +
 + * "git am" learned to pass "-b" option to underlying "git mailinfo", so
 +   that bracketed string other than "PATCH" at the beginning can be kept.
 +
 + * "git clone" learned "--single-branch" option to limit cloning to a
 +   single branch (surprise!).
 +
 + * "git clone" learned to detach the HEAD in the resulting repository
 +   when the source repository's HEAD does not point to a branch.
 +
 + * When showing a patch while ignoring whitespace changes, the context
 +   lines are taken from the postimage, in order to make it easier to
 +   view the output.
 +
 + * "diff-highlight" filter (in contrib/) was updated to produce more
 +   aesthetically pleasing output.
 +
 + * "git merge" in an interactive session learned to spawn the editor
 +   by default to let the user edit the auto-generated merge message,
 +   to encourage people to explain their merges better. Legacy scripts
 +   can export GIT_MERGE_AUTOEDIT=no to retain the historical behavior.
 +   Both "git merge" and "git pull" can be given --no-edit from the
 +   command line to accept the auto-generated merge message.
 +
 + * "git push" learned the "--prune" option, similar to "git fetch".
 +
 + * "git tag --list" can be given "--points-at <object>" to limit its
 +   output to those that point at the given object.
 +
 + * "gitweb" allows intermediate entries in the directory hierarchy
 +   that leads to a projects to be clicked, which in turn shows the
 +   list of projects inside that directory.
 +
 + * "gitweb" learned to read various pieces of information for the
 +   repositories lazily, instead of reading everything that could be
 +   needed (including the ones that are not necessary for a specific
 +   task).
 +
 +Performance
 +
 + * During "git upload-pack" in response to "git fetch", unnecessary calls
 +   to parse_object() have been eliminated, to help performance in
 +   repositories with excessive number of refs.
 +
 +Internal Implementation (please report possible regressions)
 +
 + * Recursive call chains in "git index-pack" to deal with long delta
 +   chains have been flattened, to reduce the stack footprint.
 +
 + * Use of add_extra_ref() API is now gone, to make it possible to
 +   cleanly restructure the overall refs API.
 +
 + * The command line parser of "git pack-objects" now uses parse-options
 +   API.
 +
 + * The test suite supports the new "test_pause" helper function.
 +
 + * Parallel to the test suite, there is a beginning of performance
 +   benchmarking framework.
 +
 + * t/Makefile is adjusted to prevent newer versions of GNU make from
 +   running tests in seemingly random order.
 +
 +Also contains minor documentation updates and code clean-ups.
 +
 +
 +Fixes since v1.7.9
 +------------------
 +
 +Unless otherwise noted, all the fixes since v1.7.9 in the maintenance
 +releases are contained in this release (see release notes to them for
 +details).
 +
++ * "git branch --with $that" assumed incorrectly that the user will never
++   ask the question with nonsense value in $that.
++   (merge 6c41e97 cn/maint-branch-with-bad later to maint).
++
++ * An invalid regular expression pattern given by an end user made
++   "gitweb" to return garbled response.
++   (merge 36612e4 jn/maint-gitweb-invalid-regexp later to maint).
++
++ * "git rev-list --verify-objects -q" omitted the extra verification
++   it needs to do over "git rev-list --objects -q" by mistake.
++   (merge 9899372 nd/maint-verify-objects later to maint).
++
 + * The bulk check-in codepath streamed contents that needs
 +   smudge/clean filters without running them, instead of punting and
 +   delegating to the codepath to run filters after slurping everything
 +   to core.
 +   (merge 4f22b10 jk/maint-avoid-streaming-filtered-contents later to maint).
 +
 + * When the filter driver exits before reading the content before the
 +   main git process writes the contents to be filtered to the pipe to
 +   it, the latter could be killed with SIGPIPE instead of ignoring
 +   such an event as an error.
 +   (merge 6424c2a jb/filter-ignore-sigpipe later to maint).
 +
 + * When a remote helper exits before reading the blank line from the
 +   main git process to signal the end of commands, the latter could be
 +   killed with SIGPIPE. Instead we should ignore such event as a
 +   non-error.
 +   (merge c34fe63 sp/smart-http-failure-to-push later to maint).
 +
 + * "git bundle create" produced a corrupt bundle file upon seeing
 +   commits with excessively long subject line.
 +   (merge 8a557bb tr/maint-bundle-long-subject later to maint).
 +
 + * "gitweb" used to drop warnings in the log file when "heads" view is
 +   accessed in a repository whose HEAD does not point at a valid
 +   branch.
 +
 +---
 +exec >/var/tmp/1
++O=v1.7.9.2-347-gbfabdfe
 +echo O=$(git describe)
 +git log --first-parent --oneline ^maint $O..
 +echo
 +git shortlog --no-merges ^maint $O..
diff --combined builtin/fast-export.c
index 08fed989a4a611def523aa69a642bc8559bd3f2f,61653466a6e40581a1d755ca1dec97fde0456c2b..19509ea75485083b40d6c7944541a5f628b6049b
@@@ -25,7 -25,7 +25,7 @@@ static const char *fast_export_usage[] 
  
  static int progress;
  static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT;
 -static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ABORT;
 +static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ERROR;
  static int fake_missing_tagger;
  static int use_done_feature;
  static int no_data;
@@@ -51,7 -51,7 +51,7 @@@ static int parse_opt_tag_of_filtered_mo
                                          const char *arg, int unset)
  {
        if (unset || !strcmp(arg, "abort"))
 -              tag_of_filtered_mode = ABORT;
 +              tag_of_filtered_mode = ERROR;
        else if (!strcmp(arg, "drop"))
                tag_of_filtered_mode = DROP;
        else if (!strcmp(arg, "rewrite"))
@@@ -647,9 -647,7 +647,7 @@@ int cmd_fast_export(int argc, const cha
                             "Output full tree for each commit"),
                OPT_BOOLEAN(0, "use-done-feature", &use_done_feature,
                             "Use the done feature to terminate the stream"),
-               { OPTION_NEGBIT, 0, "data", &no_data, NULL,
-                       "Skip output of blob data",
-                       PARSE_OPT_NOARG | PARSE_OPT_NEGHELP, NULL, 1 },
+               OPT_BOOL(0, "no-data", &no_data, "Skip output of blob data"),
                OPT_END()
        };
  
diff --combined builtin/grep.c
index e4ea90078384f198f5985596c64deb5f423e9e45,461d1c24659d6d3f2695c3cbfde0530a351e87a7..643938d905fb134a1e65e3684e8e5feb06b01a59
@@@ -17,6 -17,7 +17,6 @@@
  #include "grep.h"
  #include "quote.h"
  #include "dir.h"
 -#include "thread-utils.h"
  
  static char const * const grep_usage[] = {
        "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]",
@@@ -29,12 -30,25 +29,12 @@@ static int use_threads = 1
  #define THREADS 8
  static pthread_t threads[THREADS];
  
 -static void *load_sha1(const unsigned char *sha1, unsigned long *size,
 -                     const char *name);
 -static void *load_file(const char *filename, size_t *sz);
 -
 -enum work_type {WORK_SHA1, WORK_FILE};
 -
  /* We use one producer thread and THREADS consumer
   * threads. The producer adds struct work_items to 'todo' and the
   * consumers pick work items from the same array.
   */
  struct work_item {
 -      enum work_type type;
 -      char *name;
 -
 -      /* if type == WORK_SHA1, then 'identifier' is a SHA1,
 -       * otherwise type == WORK_FILE, and 'identifier' is a NUL
 -       * terminated filename.
 -       */
 -      void *identifier;
 +      struct grep_source source;
        char done;
        struct strbuf out;
  };
@@@ -60,17 -74,13 +60,17 @@@ static int all_work_added
  /* This lock protects all the variables above. */
  static pthread_mutex_t grep_mutex;
  
 -/* Used to serialize calls to read_sha1_file. */
 -static pthread_mutex_t read_sha1_mutex;
 +static inline void grep_lock(void)
 +{
 +      if (use_threads)
 +              pthread_mutex_lock(&grep_mutex);
 +}
  
 -#define grep_lock() pthread_mutex_lock(&grep_mutex)
 -#define grep_unlock() pthread_mutex_unlock(&grep_mutex)
 -#define read_sha1_lock() pthread_mutex_lock(&read_sha1_mutex)
 -#define read_sha1_unlock() pthread_mutex_unlock(&read_sha1_mutex)
 +static inline void grep_unlock(void)
 +{
 +      if (use_threads)
 +              pthread_mutex_unlock(&grep_mutex);
 +}
  
  /* Signalled when a new work_item is added to todo. */
  static pthread_cond_t cond_add;
@@@ -85,8 -95,7 +85,8 @@@ static pthread_cond_t cond_result
  
  static int skip_first_line;
  
 -static void add_work(enum work_type type, char *name, void *id)
 +static void add_work(struct grep_opt *opt, enum grep_source_type type,
 +                   const char *name, const void *id)
  {
        grep_lock();
  
                pthread_cond_wait(&cond_write, &grep_mutex);
        }
  
 -      todo[todo_end].type = type;
 -      todo[todo_end].name = name;
 -      todo[todo_end].identifier = id;
 +      grep_source_init(&todo[todo_end].source, type, name, id);
 +      if (opt->binary != GREP_BINARY_TEXT)
 +              grep_source_load_driver(&todo[todo_end].source);
        todo[todo_end].done = 0;
        strbuf_reset(&todo[todo_end].out);
        todo_end = (todo_end + 1) % ARRAY_SIZE(todo);
@@@ -124,6 -133,21 +124,6 @@@ static struct work_item *get_work(void
        return ret;
  }
  
 -static void grep_sha1_async(struct grep_opt *opt, char *name,
 -                          const unsigned char *sha1)
 -{
 -      unsigned char *s;
 -      s = xmalloc(20);
 -      memcpy(s, sha1, 20);
 -      add_work(WORK_SHA1, name, s);
 -}
 -
 -static void grep_file_async(struct grep_opt *opt, char *name,
 -                          const char *filename)
 -{
 -      add_work(WORK_FILE, name, xstrdup(filename));
 -}
 -
  static void work_done(struct work_item *w)
  {
        int old_done;
  
                        write_or_die(1, p, len);
                }
 -              free(w->name);
 -              free(w->identifier);
 +              grep_source_clear(&w->source);
        }
  
        if (old_done != todo_done)
@@@ -173,8 -198,25 +173,8 @@@ static void *run(void *arg
                        break;
  
                opt->output_priv = w;
 -              if (w->type == WORK_SHA1) {
 -                      unsigned long sz;
 -                      void* data = load_sha1(w->identifier, &sz, w->name);
 -
 -                      if (data) {
 -                              hit |= grep_buffer(opt, w->name, data, sz);
 -                              free(data);
 -                      }
 -              } else if (w->type == WORK_FILE) {
 -                      size_t sz;
 -                      void* data = load_file(w->identifier, &sz);
 -                      if (data) {
 -                              hit |= grep_buffer(opt, w->name, data, sz);
 -                              free(data);
 -                      }
 -              } else {
 -                      assert(0);
 -              }
 -
 +              hit |= grep_source(opt, &w->source);
 +              grep_source_clear_data(&w->source);
                work_done(w);
        }
        free_grep_patterns(arg);
@@@ -194,12 -236,10 +194,12 @@@ static void start_threads(struct grep_o
        int i;
  
        pthread_mutex_init(&grep_mutex, NULL);
 -      pthread_mutex_init(&read_sha1_mutex, NULL);
 +      pthread_mutex_init(&grep_read_mutex, NULL);
 +      pthread_mutex_init(&grep_attr_mutex, NULL);
        pthread_cond_init(&cond_add, NULL);
        pthread_cond_init(&cond_write, NULL);
        pthread_cond_init(&cond_result, NULL);
 +      grep_use_locks = 1;
  
        for (i = 0; i < ARRAY_SIZE(todo); i++) {
                strbuf_init(&todo[i].out, 0);
@@@ -243,16 -283,16 +243,16 @@@ static int wait_all(void
        }
  
        pthread_mutex_destroy(&grep_mutex);
 -      pthread_mutex_destroy(&read_sha1_mutex);
 +      pthread_mutex_destroy(&grep_read_mutex);
 +      pthread_mutex_destroy(&grep_attr_mutex);
        pthread_cond_destroy(&cond_add);
        pthread_cond_destroy(&cond_write);
        pthread_cond_destroy(&cond_result);
 +      grep_use_locks = 0;
  
        return hit;
  }
  #else /* !NO_PTHREADS */
 -#define read_sha1_lock()
 -#define read_sha1_unlock()
  
  static int wait_all(void)
  {
@@@ -265,8 -305,11 +265,8 @@@ static int grep_config(const char *var
        struct grep_opt *opt = cb;
        char *color = NULL;
  
 -      switch (userdiff_config(var, value)) {
 -      case 0: break;
 -      case -1: return -1;
 -      default: return 0;
 -      }
 +      if (userdiff_config(var, value) < 0)
 +              return -1;
  
        if (!strcmp(var, "grep.extendedregexp")) {
                if (git_config_bool(var, value))
@@@ -311,9 -354,25 +311,9 @@@ static void *lock_and_read_sha1_file(co
  {
        void *data;
  
 -      if (use_threads) {
 -              read_sha1_lock();
 -              data = read_sha1_file(sha1, type, size);
 -              read_sha1_unlock();
 -      } else {
 -              data = read_sha1_file(sha1, type, size);
 -      }
 -      return data;
 -}
 -
 -static void *load_sha1(const unsigned char *sha1, unsigned long *size,
 -                     const char *name)
 -{
 -      enum object_type type;
 -      void *data = lock_and_read_sha1_file(sha1, &type, size);
 -
 -      if (!data)
 -              error(_("'%s': unable to read %s"), name, sha1_to_hex(sha1));
 -
 +      grep_read_lock();
 +      data = read_sha1_file(sha1, type, size);
 +      grep_read_unlock();
        return data;
  }
  
@@@ -321,6 -380,7 +321,6 @@@ static int grep_sha1(struct grep_opt *o
                     const char *filename, int tree_name_len)
  {
        struct strbuf pathbuf = STRBUF_INIT;
 -      char *name;
  
        if (opt->relative && opt->prefix_length) {
                quote_path_relative(filename + tree_name_len, -1, &pathbuf,
                strbuf_addstr(&pathbuf, filename);
        }
  
 -      name = strbuf_detach(&pathbuf, NULL);
 -
  #ifndef NO_PTHREADS
        if (use_threads) {
 -              grep_sha1_async(opt, name, sha1);
 +              add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, sha1);
 +              strbuf_release(&pathbuf);
                return 0;
        } else
  #endif
        {
 +              struct grep_source gs;
                int hit;
 -              unsigned long sz;
 -              void *data = load_sha1(sha1, &sz, name);
 -              if (!data)
 -                      hit = 0;
 -              else
 -                      hit = grep_buffer(opt, name, data, sz);
  
 -              free(data);
 -              free(name);
 -              return hit;
 -      }
 -}
 +              grep_source_init(&gs, GREP_SOURCE_SHA1, pathbuf.buf, sha1);
 +              strbuf_release(&pathbuf);
 +              hit = grep_source(opt, &gs);
  
 -static void *load_file(const char *filename, size_t *sz)
 -{
 -      struct stat st;
 -      char *data;
 -      int i;
 -
 -      if (lstat(filename, &st) < 0) {
 -      err_ret:
 -              if (errno != ENOENT)
 -                      error(_("'%s': %s"), filename, strerror(errno));
 -              return NULL;
 -      }
 -      if (!S_ISREG(st.st_mode))
 -              return NULL;
 -      *sz = xsize_t(st.st_size);
 -      i = open(filename, O_RDONLY);
 -      if (i < 0)
 -              goto err_ret;
 -      data = xmalloc(*sz + 1);
 -      if (st.st_size != read_in_full(i, data, *sz)) {
 -              error(_("'%s': short read %s"), filename, strerror(errno));
 -              close(i);
 -              free(data);
 -              return NULL;
 +              grep_source_clear(&gs);
 +              return hit;
        }
 -      close(i);
 -      data[*sz] = 0;
 -      return data;
  }
  
  static int grep_file(struct grep_opt *opt, const char *filename)
  {
        struct strbuf buf = STRBUF_INIT;
 -      char *name;
  
        if (opt->relative && opt->prefix_length)
                quote_path_relative(filename, -1, &buf, opt->prefix);
        else
                strbuf_addstr(&buf, filename);
 -      name = strbuf_detach(&buf, NULL);
  
  #ifndef NO_PTHREADS
        if (use_threads) {
 -              grep_file_async(opt, name, filename);
 +              add_work(opt, GREP_SOURCE_FILE, buf.buf, filename);
 +              strbuf_release(&buf);
                return 0;
        } else
  #endif
        {
 +              struct grep_source gs;
                int hit;
 -              size_t sz;
 -              void *data = load_file(filename, &sz);
 -              if (!data)
 -                      hit = 0;
 -              else
 -                      hit = grep_buffer(opt, name, data, sz);
  
 -              free(data);
 -              free(name);
 +              grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename);
 +              strbuf_release(&buf);
 +              hit = grep_source(opt, &gs);
 +
 +              grep_source_clear(&gs);
                return hit;
        }
  }
@@@ -446,19 -542,18 +446,19 @@@ static int grep_cache(struct grep_opt *
  static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
                     struct tree_desc *tree, struct strbuf *base, int tn_len)
  {
 -      int hit = 0, match = 0;
 +      int hit = 0;
 +      enum interesting match = entry_not_interesting;
        struct name_entry entry;
        int old_baselen = base->len;
  
        while (tree_entry(tree, &entry)) {
 -              int te_len = tree_entry_len(entry.path, entry.sha1);
 +              int te_len = tree_entry_len(&entry);
  
 -              if (match != 2) {
 +              if (match != all_entries_interesting) {
                        match = tree_entry_interesting(&entry, base, tn_len, pathspec);
 -                      if (match < 0)
 +                      if (match == all_entries_not_interesting)
                                break;
 -                      if (match == 0)
 +                      if (match == entry_not_interesting)
                                continue;
                }
  
@@@ -503,10 -598,10 +503,10 @@@ static int grep_object(struct grep_opt 
                struct strbuf base;
                int hit, len;
  
 -              read_sha1_lock();
 +              grep_read_lock();
                data = read_object_with_reference(obj->sha1, tree_type,
                                                  &size, NULL);
 -              read_sha1_unlock();
 +              grep_read_unlock();
  
                if (!data)
                        die(_("unable to read tree (%s)"), sha1_to_hex(obj->sha1));
@@@ -545,15 -640,13 +545,15 @@@ static int grep_objects(struct grep_op
        return hit;
  }
  
 -static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec)
 +static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
 +                        int exc_std)
  {
        struct dir_struct dir;
        int i, hit = 0;
  
        memset(&dir, 0, sizeof(dir));
 -      setup_standard_excludes(&dir);
 +      if (exc_std)
 +              setup_standard_excludes(&dir);
  
        fill_directory(&dir, pathspec->raw);
        for (i = 0; i < dir.nr; i++) {
@@@ -660,7 -753,7 +660,7 @@@ static int help_callback(const struct o
  int cmd_grep(int argc, const char **argv, const char *prefix)
  {
        int hit = 0;
 -      int cached = 0;
 +      int cached = 0, untracked = 0, opt_exclude = -1;
        int seen_dashdash = 0;
        int external_grep_allowed__ignored;
        const char *show_in_pager = NULL, *default_pager = "dummy";
        struct option options[] = {
                OPT_BOOLEAN(0, "cached", &cached,
                        "search in index instead of in the work tree"),
-               { OPTION_BOOLEAN, 0, "index", &use_index, NULL,
-                       "finds in contents not managed by git",
-                       PARSE_OPT_NOARG | PARSE_OPT_NEGHELP },
+               OPT_NEGBIT(0, "no-index", &use_index,
+                        "finds in contents not managed by git", 1),
 +              OPT_BOOLEAN(0, "untracked", &untracked,
 +                      "search in both tracked and untracked files"),
 +              OPT_SET_INT(0, "exclude-standard", &opt_exclude,
 +                          "search also in ignored files", 1),
                OPT_GROUP(""),
                OPT_BOOLEAN('v', "invert-match", &opt.invert,
                        "show non-matching lines"),
        if (!opt.fixed && opt.ignore_case)
                opt.regflags |= REG_ICASE;
  
 -#ifndef NO_PTHREADS
 -      if (online_cpus() == 1 || !grep_threads_ok(&opt))
 -              use_threads = 0;
 -
 -      if (use_threads) {
 -              if (opt.pre_context || opt.post_context || opt.file_break ||
 -                  opt.funcbody)
 -                      skip_first_line = 1;
 -              start_threads(&opt);
 -      }
 -#else
 -      use_threads = 0;
 -#endif
 -
        compile_grep_patterns(&opt);
  
        /* Check revs and then paths */
                break;
        }
  
 +#ifndef NO_PTHREADS
 +      if (list.nr || cached || online_cpus() == 1)
 +              use_threads = 0;
 +#else
 +      use_threads = 0;
 +#endif
 +
 +#ifndef NO_PTHREADS
 +      if (use_threads) {
 +              if (!(opt.name_only || opt.unmatch_name_only || opt.count)
 +                  && (opt.pre_context || opt.post_context ||
 +                      opt.file_break || opt.funcbody))
 +                      skip_first_line = 1;
 +              start_threads(&opt);
 +      }
 +#endif
 +
        /* The rest are paths */
        if (!seen_dashdash) {
                int j;
        if (!show_in_pager)
                setup_pager();
  
 +      if (!use_index && (untracked || cached))
 +              die(_("--cached or --untracked cannot be used with --no-index."));
  
 -      if (!use_index) {
 -              if (cached)
 -                      die(_("--cached cannot be used with --no-index."));
 +      if (!use_index || untracked) {
 +              int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude;
                if (list.nr)
 -                      die(_("--no-index cannot be used with revs."));
 -              hit = grep_directory(&opt, &pathspec);
 +                      die(_("--no-index or --untracked cannot be used with revs."));
 +              hit = grep_directory(&opt, &pathspec, use_exclude);
 +      } else if (0 <= opt_exclude) {
 +              die(_("--[no-]exclude-standard cannot be used for tracked contents."));
        } else if (!list.nr) {
                if (!cached)
                        setup_work_tree();