Merge branch 'jn/git-cmd-h-bypass-setup'
authorJunio C Hamano <gitster@pobox.com>
Mon, 13 Dec 2010 05:49:50 +0000 (21:49 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 13 Dec 2010 05:49:50 +0000 (21:49 -0800)
* jn/git-cmd-h-bypass-setup:
update-index -h: show usage even with corrupt index
merge -h: show usage even with corrupt index
ls-files -h: show usage even with corrupt index
gc -h: show usage even with broken configuration
commit/status -h: show usage even with broken configuration
checkout-index -h: show usage even in an invalid repository
branch -h: show usage even in an invalid repository

Conflicts:
builtin/merge.c

1  2 
builtin/branch.c
builtin/checkout-index.c
builtin/commit.c
builtin/gc.c
builtin/ls-files.c
builtin/merge.c
builtin/update-index.c
t/t7508-status.sh
diff --combined builtin/branch.c
index 807355a1982f0f91e9acea66c360903fc3714495,0e50556a151c186429e13d03fc8e279fa6ddecd5..0cad20bb5a8bd0054761861aada7f1077260dbd5
@@@ -621,8 -621,7 +621,8 @@@ int cmd_branch(int argc, const char **a
  
        struct option options[] = {
                OPT_GROUP("Generic options"),
 -              OPT__VERBOSE(&verbose),
 +              OPT__VERBOSE(&verbose,
 +                      "show hash and subject, give twice for upstream branch"),
                OPT_SET_INT('t', "track",  &track, "set up tracking mode (see git-pull(1))",
                        BRANCH_TRACK_EXPLICIT),
                OPT_SET_INT( 0, "set-upstream",  &track, "change upstream info",
                OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
                OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
                OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
 -              OPT_BOOLEAN('f', "force", &force_create, "force creation (when already exists)"),
 +              OPT__FORCE(&force_create, "force creation (when already exists)"),
                {
                        OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
                        "commit", "print only not merged branches",
                OPT_END(),
        };
  
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(builtin_branch_usage, options);
        git_config(git_branch_config, NULL);
  
        if (branch_use_color == -1)
diff --combined builtin/checkout-index.c
index 1ee30443074bbae67a402c5397b939a716f2a191,3bf342232b74011e627d3cf6f5bea1a159f5ead9..f1fec24745a854e77555a1b4bea3bc8d7ab04367
@@@ -155,7 -155,7 +155,7 @@@ static void checkout_all(const char *pr
  }
  
  static const char * const builtin_checkout_index_usage[] = {
 -      "git checkout-index [options] [--] <file>...",
 +      "git checkout-index [options] [--] [<file>...]",
        NULL
  };
  
@@@ -217,9 -217,9 +217,9 @@@ int cmd_checkout_index(int argc, const 
        struct option builtin_checkout_index_options[] = {
                OPT_BOOLEAN('a', "all", &all,
                        "checks out all files in the index"),
 -              OPT_BOOLEAN('f', "force", &force,
 -                      "forces overwrite of existing files"),
 -              OPT__QUIET(&quiet),
 +              OPT__FORCE(&force, "forces overwrite of existing files"),
 +              OPT__QUIET(&quiet,
 +                      "no warning for existing files and files not in index"),
                OPT_BOOLEAN('n', "no-create", &not_new,
                        "don't checkout new files"),
                { OPTION_CALLBACK, 'u', "index", &newfd, NULL,
                OPT_END()
        };
  
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(builtin_checkout_index_usage,
+                                  builtin_checkout_index_options);
        git_config(git_default_config, NULL);
        state.base_dir = "";
        prefix_length = prefix ? strlen(prefix) : 0;
diff --combined builtin/commit.c
index 6d867d4018b38cbb6ba36d963ee5af10721bab0e,0abb4302529d40a342217d5c594d27da63d50876..c045c9ef8cf19b5458c279cd46250c839285a4a4
@@@ -69,7 -69,6 +69,7 @@@ static enum 
  static const char *logfile, *force_author;
  static const char *template_file;
  static char *edit_message, *use_message;
 +static char *fixup_message, *squash_message;
  static char *author_name, *author_email, *author_date;
  static int all, edit_flag, also, interactive, only, amend, signoff;
  static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
@@@ -115,8 -114,8 +115,8 @@@ static int opt_parse_m(const struct opt
  }
  
  static struct option builtin_commit_options[] = {
 -      OPT__QUIET(&quiet),
 -      OPT__VERBOSE(&verbose),
 +      OPT__QUIET(&quiet, "suppress summary after successful commit"),
 +      OPT__VERBOSE(&verbose, "show diff in commit message template"),
  
        OPT_GROUP("Commit message options"),
        OPT_FILENAME('F', "file", &logfile, "read log from file"),
        OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m),
        OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit"),
        OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
 +      OPT_STRING(0, "fixup", &fixup_message, "COMMIT", "use autosquash formatted message to fixup specified commit"),
 +      OPT_STRING(0, "squash", &squash_message, "COMMIT", "use autosquash formatted message to squash specified commit"),
        OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
        OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
        OPT_FILENAME('t', "template", &template_file, "use specified template file"),
@@@ -568,25 -565,6 +568,25 @@@ static int prepare_to_commit(const cha
        if (!no_verify && run_hook(index_file, "pre-commit", NULL))
                return 0;
  
 +      if (squash_message) {
 +              /*
 +               * Insert the proper subject line before other commit
 +               * message options add their content.
 +               */
 +              if (use_message && !strcmp(use_message, squash_message))
 +                      strbuf_addstr(&sb, "squash! ");
 +              else {
 +                      struct pretty_print_context ctx = {0};
 +                      struct commit *c;
 +                      c = lookup_commit_reference_by_name(squash_message);
 +                      if (!c)
 +                              die("could not lookup commit %s", squash_message);
 +                      ctx.output_encoding = get_commit_output_encoding();
 +                      format_commit_message(c, "squash! %s\n\n", &sb,
 +                                            &ctx);
 +              }
 +      }
 +
        if (message.len) {
                strbuf_addbuf(&sb, &message);
                hook_arg1 = "message";
                strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
                hook_arg1 = "commit";
                hook_arg2 = use_message;
 +      } else if (fixup_message) {
 +              struct pretty_print_context ctx = {0};
 +              struct commit *commit;
 +              commit = lookup_commit_reference_by_name(fixup_message);
 +              if (!commit)
 +                      die("could not lookup commit %s", fixup_message);
 +              ctx.output_encoding = get_commit_output_encoding();
 +              format_commit_message(commit, "fixup! %s\n\n",
 +                                    &sb, &ctx);
 +              hook_arg1 = "message";
        } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
                if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
                        die_errno("could not read MERGE_MSG");
        else if (in_merge)
                hook_arg1 = "merge";
  
 +      if (squash_message) {
 +              /*
 +               * If squash_commit was used for the commit subject,
 +               * then we're possibly hijacking other commit log options.
 +               * Reset the hook args to tell the real story.
 +               */
 +              hook_arg1 = "message";
 +              hook_arg2 = "";
 +      }
 +
        fp = fopen(git_path(commit_editmsg), "w");
        if (fp == NULL)
                die_errno("could not open '%s'", git_path(commit_editmsg));
@@@ -905,7 -863,7 +905,7 @@@ static int parse_and_validate_options(i
        if (force_author && renew_authorship)
                die("Using both --reset-author and --author does not make sense");
  
 -      if (logfile || message.len || use_message)
 +      if (logfile || message.len || use_message || fixup_message)
                use_editor = 0;
        if (edit_flag)
                use_editor = 1;
                die("You have nothing to amend.");
        if (amend && in_merge)
                die("You are in the middle of a merge -- cannot amend.");
 -
 +      if (fixup_message && squash_message)
 +              die("Options --squash and --fixup cannot be used together");
        if (use_message)
                f++;
        if (edit_message)
                f++;
 +      if (fixup_message)
 +              f++;
        if (logfile)
                f++;
        if (f > 1)
 -              die("Only one of -c/-C/-F can be used.");
 +              die("Only one of -c/-C/-F/--fixup can be used.");
        if (message.len && f > 0)
 -              die("Option -m cannot be combined with -c/-C/-F.");
 +              die("Option -m cannot be combined with -c/-C/-F/--fixup.");
        if (edit_message)
                use_message = edit_message;
 -      if (amend && !use_message)
 +      if (amend && !use_message && !fixup_message)
                use_message = "HEAD";
        if (!use_message && renew_authorship)
                die("--reset-author can be used only with -C, -c or --amend.");
        if (use_message) {
 -              unsigned char sha1[20];
 -              static char utf8[] = "UTF-8";
                const char *out_enc;
 -              char *enc, *end;
                struct commit *commit;
  
 -              if (get_sha1(use_message, sha1))
 +              commit = lookup_commit_reference_by_name(use_message);
 +              if (!commit)
                        die("could not lookup commit %s", use_message);
 -              commit = lookup_commit_reference(sha1);
 -              if (!commit || parse_commit(commit))
 -                      die("could not parse commit %s", use_message);
 -
 -              enc = strstr(commit->buffer, "\nencoding");
 -              if (enc) {
 -                      end = strchr(enc + 10, '\n');
 -                      enc = xstrndup(enc + 10, end - (enc + 10));
 -              } else {
 -                      enc = utf8;
 -              }
 -              out_enc = git_commit_encoding ? git_commit_encoding : utf8;
 -
 -              if (strcmp(out_enc, enc))
 -                      use_message_buffer =
 -                              reencode_string(commit->buffer, out_enc, enc);
 +              out_enc = get_commit_output_encoding();
 +              use_message_buffer = logmsg_reencode(commit, out_enc);
  
                /*
                 * If we failed to reencode the buffer, just copy it
                 */
                if (use_message_buffer == NULL)
                        use_message_buffer = xstrdup(commit->buffer);
 -              if (enc != utf8)
 -                      free(enc);
        }
  
        if (!!also + !!only + !!all + !!interactive > 1)
@@@ -1075,7 -1048,7 +1075,7 @@@ int cmd_status(int argc, const char **a
        int fd;
        unsigned char sha1[20];
        static struct option builtin_status_options[] = {
 -              OPT__VERBOSE(&verbose),
 +              OPT__VERBOSE(&verbose, "be verbose"),
                OPT_SET_INT('s', "short", &status_format,
                            "show status concisely", STATUS_FORMAT_SHORT),
                OPT_BOOLEAN('b', "branch", &status_show_branch,
                OPT_END(),
        };
  
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(builtin_status_usage, builtin_status_options);
        if (null_termination && status_format == STATUS_FORMAT_LONG)
                status_format = STATUS_FORMAT_PORCELAIN;
  
@@@ -1282,6 -1258,9 +1285,9 @@@ int cmd_commit(int argc, const char **a
        int allow_fast_forward = 1;
        struct wt_status s;
  
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(builtin_commit_usage, builtin_commit_options);
        wt_status_prepare(&s);
        git_config(git_commit_config, &s);
        in_merge = file_exists(git_path("MERGE_HEAD"));
diff --combined builtin/gc.c
index 397a1e6eb3ae8ec0e367a8faa2ca823586d26e6a,93deed5153d6a11d15d90353950eae3a837a7074..1a80702b3d1c86b55af24be3b3396f17e9d4a21c
@@@ -180,7 -180,7 +180,7 @@@ int cmd_gc(int argc, const char **argv
        char buf[80];
  
        struct option builtin_gc_options[] = {
 -              OPT__QUIET(&quiet),
 +              OPT__QUIET(&quiet, "suppress progress reporting"),
                { OPTION_STRING, 0, "prune", &prune_expire, "date",
                        "prune unreferenced objects",
                        PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
                OPT_END()
        };
  
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(builtin_gc_usage, builtin_gc_options);
        git_config(gc_config, NULL);
  
        if (pack_refs < 0)
diff --combined builtin/ls-files.c
index 6a307ab784a25c9f8d201392f79c7146a4a8eece,87f0b8ac1d84f13402621ffdef25e0a6231f83b2..fb2d5f4b1fb0ce9ef2fb0c4099b5fea6d07b6838
@@@ -424,7 -424,7 +424,7 @@@ int report_path_error(const char *ps_ma
  }
  
  static const char * const ls_files_usage[] = {
 -      "git ls-files [options] [<file>]*",
 +      "git ls-files [options] [<file>...]",
        NULL
  };
  
@@@ -530,6 -530,9 +530,9 @@@ int cmd_ls_files(int argc, const char *
                OPT_END()
        };
  
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(ls_files_usage, builtin_ls_files_options);
        memset(&dir, 0, sizeof(dir));
        prefix = cmd_prefix;
        if (prefix)
diff --combined builtin/merge.c
index 3921cd304086cbc2edff0e1481f7c7395df8b00a,584c94f6fbc6bc474ac2b2bf35f0048ea58943e4..42fff387e69d9b5412e8e776aed3272b78ebe758
@@@ -42,7 -42,7 +42,7 @@@ static const char * const builtin_merge
        NULL
  };
  
 -static int show_diffstat = 1, option_log, squash;
 +static int show_diffstat = 1, shortlog_len, squash;
  static int option_commit = 1, allow_fast_forward = 1;
  static int fast_forward_only;
  static int allow_trivial = 1, have_message;
@@@ -57,7 -57,6 +57,7 @@@ static const char *branch
  static int option_renormalize;
  static int verbosity;
  static int allow_rerere_auto;
 +static int abort_current_merge;
  
  static struct strategy all_strategy[] = {
        { "recursive",  DEFAULT_TWOHEAD | NO_TRIVIAL },
@@@ -178,9 -177,8 +178,9 @@@ static struct option builtin_merge_opti
        OPT_BOOLEAN(0, "stat", &show_diffstat,
                "show a diffstat at the end of the merge"),
        OPT_BOOLEAN(0, "summary", &show_diffstat, "(synonym to --stat)"),
 -      OPT_BOOLEAN(0, "log", &option_log,
 -              "add list of one-line log to merge commit message"),
 +      { OPTION_INTEGER, 0, "log", &shortlog_len, "n",
 +        "add (at most <n>) entries from shortlog to merge commit message",
 +        PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN },
        OPT_BOOLEAN(0, "squash", &squash,
                "create a single commit instead of doing a merge"),
        OPT_BOOLEAN(0, "commit", &option_commit,
                "message to be used for the merge commit (if any)",
                option_parse_message),
        OPT__VERBOSITY(&verbosity),
 +      OPT_BOOLEAN(0, "abort", &abort_current_merge,
 +              "abort the current in-progress merge"),
        OPT_END()
  };
  
@@@ -237,24 -233,6 +237,24 @@@ static void save_state(void
                die("not a valid object: %s", buffer.buf);
  }
  
 +static void read_empty(unsigned const char *sha1, int verbose)
 +{
 +      int i = 0;
 +      const char *args[7];
 +
 +      args[i++] = "read-tree";
 +      if (verbose)
 +              args[i++] = "-v";
 +      args[i++] = "-m";
 +      args[i++] = "-u";
 +      args[i++] = EMPTY_TREE_SHA1_HEX;
 +      args[i++] = sha1_to_hex(sha1);
 +      args[i] = NULL;
 +
 +      if (run_command_v_opt(args, RUN_GIT_CMD))
 +              die("read-tree failed");
 +}
 +
  static void reset_hard(unsigned const char *sha1, int verbose)
  {
        int i = 0;
@@@ -424,7 -402,7 +424,7 @@@ static void merge_name(const char *remo
                        goto cleanup;
                }
                if (!prefixcmp(found_ref, "refs/remotes/")) {
 -                      strbuf_addf(msg, "%s\t\tremote branch '%s' of .\n",
 +                      strbuf_addf(msg, "%s\t\tremote-tracking branch '%s' of .\n",
                                    sha1_to_hex(branch_head), remote);
                        goto cleanup;
                }
@@@ -526,17 -504,10 +526,17 @@@ static int git_merge_config(const char 
                return git_config_string(&pull_twohead, k, v);
        else if (!strcmp(k, "pull.octopus"))
                return git_config_string(&pull_octopus, k, v);
 -      else if (!strcmp(k, "merge.log") || !strcmp(k, "merge.summary"))
 -              option_log = git_config_bool(k, v);
        else if (!strcmp(k, "merge.renormalize"))
                option_renormalize = git_config_bool(k, v);
 +      else if (!strcmp(k, "merge.log") || !strcmp(k, "merge.summary")) {
 +              int is_bool;
 +              shortlog_len = git_config_bool_or_int(k, v, &is_bool);
 +              if (!is_bool && shortlog_len < 0)
 +                      return error("%s: negative length %s", k, v);
 +              if (is_bool && shortlog_len)
 +                      shortlog_len = DEFAULT_MERGE_LOG_LEN;
 +              return 0;
 +      }
        return git_diff_ui_config(k, v, cb);
  }
  
@@@ -660,9 -631,25 +660,9 @@@ static int try_merge_strategy(const cha
  
                o.renormalize = option_renormalize;
  
 -              /*
 -               * NEEDSWORK: merge with table in builtin/merge-recursive
 -               */
 -              for (x = 0; x < xopts_nr; x++) {
 -                      if (!strcmp(xopts[x], "ours"))
 -                              o.recursive_variant = MERGE_RECURSIVE_OURS;
 -                      else if (!strcmp(xopts[x], "theirs"))
 -                              o.recursive_variant = MERGE_RECURSIVE_THEIRS;
 -                      else if (!strcmp(xopts[x], "subtree"))
 -                              o.subtree_shift = "";
 -                      else if (!prefixcmp(xopts[x], "subtree="))
 -                              o.subtree_shift = xopts[x]+8;
 -                      else if (!strcmp(xopts[x], "renormalize"))
 -                              o.renormalize = 1;
 -                      else if (!strcmp(xopts[x], "no-renormalize"))
 -                              o.renormalize = 0;
 -                      else
 +              for (x = 0; x < xopts_nr; x++)
 +                      if (parse_merge_opt(&o, xopts[x]))
                                die("Unknown option for merge-recursive: -X%s", xopts[x]);
 -              }
  
                o.branch1 = head_arg;
                o.branch2 = remoteheads->item->util;
@@@ -922,6 -909,24 +922,9 @@@ int cmd_merge(int argc, const char **ar
        const char *best_strategy = NULL, *wt_strategy = NULL;
        struct commit_list **remotes = &remoteheads;
  
 -      if (read_cache_unmerged()) {
 -              die_resolve_conflict("merge");
 -      }
 -      if (file_exists(git_path("MERGE_HEAD"))) {
 -              /*
 -               * There is no unmerged entry, don't advise 'git
 -               * add/rm <file>', just 'git commit'.
 -               */
 -              if (advice_resolve_conflict)
 -                      die("You have not concluded your merge (MERGE_HEAD exists).\n"
 -                          "Please, commit your changes before you can merge.");
 -              else
 -                      die("You have not concluded your merge (MERGE_HEAD exists).");
 -      }
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(builtin_merge_usage, builtin_merge_options);
 -      resolve_undo_clear();
        /*
         * Check if we are _not_ on a detached HEAD, i.e. if there is a
         * current branch.
  
        argc = parse_options(argc, argv, prefix, builtin_merge_options,
                        builtin_merge_usage, 0);
 +
 +      if (abort_current_merge) {
 +              int nargc = 2;
 +              const char *nargv[] = {"reset", "--merge", NULL};
 +
 +              if (!file_exists(git_path("MERGE_HEAD")))
 +                      die("There is no merge to abort (MERGE_HEAD missing).");
 +
 +              /* Invoke 'git reset --merge' */
 +              return cmd_reset(nargc, nargv, prefix);
 +      }
 +
 +      if (read_cache_unmerged())
 +              die_resolve_conflict("merge");
 +
 +      if (file_exists(git_path("MERGE_HEAD"))) {
 +              /*
 +               * There is no unmerged entry, don't advise 'git
 +               * add/rm <file>', just 'git commit'.
 +               */
 +              if (advice_resolve_conflict)
 +                      die("You have not concluded your merge (MERGE_HEAD exists).\n"
 +                          "Please, commit your changes before you can merge.");
 +              else
 +                      die("You have not concluded your merge (MERGE_HEAD exists).");
 +      }
 +      resolve_undo_clear();
 +
        if (verbosity < 0)
                show_diffstat = 0;
  
                        die("%s - not something we can merge", argv[0]);
                update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
                                DIE_ON_ERR);
 -              reset_hard(remote_head->sha1, 0);
 +              read_empty(remote_head->sha1, 0);
                return 0;
        } else {
                struct strbuf merge_names = STRBUF_INIT;
                for (i = 0; i < argc; i++)
                        merge_name(argv[i], &merge_names);
  
 -              if (have_message && option_log)
 -                      fmt_merge_msg_shortlog(&merge_names, &merge_msg);
 -              else if (!have_message)
 -                      fmt_merge_msg(option_log, &merge_names, &merge_msg);
 -
 -
 -              if (!(have_message && !option_log) && merge_msg.len)
 -                      strbuf_setlen(&merge_msg, merge_msg.len-1);
 +              if (!have_message || shortlog_len) {
 +                      fmt_merge_msg(&merge_names, &merge_msg, !have_message,
 +                                    shortlog_len);
 +                      if (merge_msg.len)
 +                              strbuf_setlen(&merge_msg, merge_msg.len - 1);
 +              }
        }
  
        if (head_invalid || !argc)
diff --combined builtin/update-index.c
index 62d9f3f0fa358058fcf54e4fcbd4c3101b1279db,a41d6d74f3c5b1175b7e81090363e5a6164ad88e..200c7efed18ebba7088f2b56d942084be280a578
@@@ -398,7 -398,7 +398,7 @@@ static void read_index_info(int line_te
  }
  
  static const char update_index_usage[] =
 -"git update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--skip-worktree|--no-skip-worktree] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
 +"git update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--skip-worktree|--no-skip-worktree] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] [<file>...]";
  
  static unsigned char head_sha1[20];
  static unsigned char merge_head_sha1[20];
@@@ -589,6 -589,9 +589,9 @@@ int cmd_update_index(int argc, const ch
        int lock_error = 0;
        struct lock_file *lock_file;
  
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage(update_index_usage);
        git_config(git_default_config, NULL);
  
        /* We can't free this memory, it becomes part of a linked list parsed atexit() */
diff --combined t/t7508-status.sh
index 4de3e27950ca34ffe3f5e72052108ce9d74b0227,beaae9430659f617fa7a3c8553ba6494497837c6..b73ab42936a8ea10dcdf40a6ad8b83d4a1d10056
@@@ -7,6 -7,30 +7,30 @@@ test_description='git status
  
  . ./test-lib.sh
  
+ test_expect_success 'status -h in broken repository' '
+       mkdir broken &&
+       test_when_finished "rm -fr broken" &&
+       (
+               cd broken &&
+               git init &&
+               echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
+               test_expect_code 129 git status -h >usage 2>&1
+       ) &&
+       grep "[Uu]sage" broken/usage
+ '
+ test_expect_success 'commit -h in broken repository' '
+       mkdir broken &&
+       test_when_finished "rm -fr broken" &&
+       (
+               cd broken &&
+               git init &&
+               echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
+               test_expect_code 129 git commit -h >usage 2>&1
+       ) &&
+       grep "[Uu]sage" broken/usage
+ '
  test_expect_success 'setup' '
        : >tracked &&
        : >modified &&
@@@ -44,7 -68,7 +68,7 @@@ cat >expect <<\EO
  #
  #     new file:   dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -73,7 -97,7 +97,7 @@@ cat >expect <<\EO
  # Changes to be committed:
  #     new file:   dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #     modified:   dir1/modified
  #
  # Untracked files:
@@@ -140,7 -164,7 +164,7 @@@ cat >expect <<EO
  #
  #     new file:   dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -167,7 -191,7 +191,7 @@@ cat >expect <<EO
  # Changes to be committed:
  #     new file:   dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #     modified:   dir1/modified
  #
  # Untracked files not listed
@@@ -202,7 -226,7 +226,7 @@@ cat >expect <<EO
  #
  #     new file:   dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -260,7 -284,7 +284,7 @@@ cat >expect <<EO
  #
  #     new file:   dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -320,7 -344,7 +344,7 @@@ cat >expect <<\EO
  #
  #     new file:   ../dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -392,7 -416,7 +416,7 @@@ cat >expect <<\EO
  #
  #     <GREEN>new file:   dir2/added<RESET>
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -521,7 -545,7 +545,7 @@@ cat >expect <<\EO
  #
  #     new file:   dir2/added
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -614,7 -638,7 +638,7 @@@ cat >expect <<EO
  #     new file:   dir2/added
  #     new file:   sm
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -673,7 -697,7 +697,7 @@@ cat >expect <<EO
  #     new file:   dir2/added
  #     new file:   sm
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -718,7 -742,7 +742,7 @@@ test_expect_success 'status -s submodul
  
  cat >expect <<EOF
  # On branch master
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -766,7 -790,7 +790,7 @@@ cat >expect <<EO
  #     new file:   dir2/added
  #     new file:   sm
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -819,7 -843,7 +843,7 @@@ cat > expect << EO
  #
  #     modified:   sm
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -931,7 -955,7 +955,7 @@@ cat > expect << EO
  #
  #     modified:   sm
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #   (commit or discard the untracked or modified content in submodules)
@@@ -989,7 -1013,7 +1013,7 @@@ cat > expect << EO
  #
  #     modified:   sm
  #
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
@@@ -1067,7 -1091,7 +1091,7 @@@ test_expect_success ".git/config ignore
  
  cat > expect << EOF
  # On branch master
 -# Changed but not updated:
 +# Changes not staged for commit:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #