Merge branch 'aa/status-hilite-branch'
authorJunio C Hamano <gitster@pobox.com>
Thu, 16 Dec 2010 20:50:03 +0000 (12:50 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Dec 2010 20:50:03 +0000 (12:50 -0800)
* aa/status-hilite-branch:
  default color.status.branch to "same as header"
  status: show branchname with a configurable color

1  2 
Documentation/config.txt
builtin/commit.c
t/t7508-status.sh
wt-status.c

diff --combined Documentation/config.txt
@@@ -374,15 -374,6 +374,15 @@@ core.warnAmbiguousRefs:
        If true, git will warn you if the ref name you passed it is ambiguous
        and might match multiple refs in the .git/refs/ tree. True by default.
  
 +core.abbrevguard::
 +      Even though git makes sure that it uses enough hexdigits to show
 +      an abbreviated object name unambiguously, as more objects are
 +      added to the repository over time, a short name that used to be
 +      unique will stop being unique.  Git uses this many extra hexdigits
 +      that are more than necessary to make the object name currently
 +      unique, in the hope that its output will stay unique a bit longer.
 +      Defaults to 0.
 +
  core.compression::
        An integer -1..9, indicating a default compression level.
        -1 is the zlib default. 0 means no compression,
@@@ -522,9 -513,6 +522,9 @@@ core.whitespace:
    part of the line terminator, i.e. with it, `trailing-space`
    does not trigger if the character before such a carriage-return
    is not a whitespace (not enabled by default).
 +* `tabwidth=<n>` tells how many character positions a tab occupies; this
 +  is relevant for `indent-with-non-tab` and when git fixes `tab-in-indent`
 +  errors. The default tab width is 8. Allowed values are 1 to 63.
  
  core.fsyncobjectfiles::
        This boolean will enable 'fsync()' when writing object files.
@@@ -566,13 -554,9 +566,13 @@@ core.sparseCheckout:
        linkgit:git-read-tree[1] for more information.
  
  add.ignore-errors::
 +add.ignoreErrors::
        Tells 'git add' to continue adding files when some files cannot be
        added due to indexing errors. Equivalent to the '--ignore-errors'
 -      option of linkgit:git-add[1].
 +      option of linkgit:git-add[1].  Older versions of git accept only
 +      `add.ignore-errors`, which does not follow the usual naming
 +      convention for configuration variables.  Newer versions of git
 +      honor `add.ignoreErrors` as well.
  
  alias.*::
        Command aliases for the linkgit:git[1] command wrapper - e.g.
@@@ -790,7 -774,8 +790,8 @@@ color.status.<slot>:
        one of `header` (the header text of the status message),
        `added` or `updated` (files which are added but not committed),
        `changed` (files which are changed but not added in the index),
-       `untracked` (files which are not tracked by git), or
+       `untracked` (files which are not tracked by git),
+       `branch` (the current branch), or
        `nobranch` (the color the 'no branch' warning is shown in, defaulting
        to red). The values of these variables may be specified as in
        color.branch.<slot>.
@@@ -1548,13 -1533,11 +1549,13 @@@ pack.packSizeLimit:
        supported.
  
  pager.<cmd>::
 -      Allows turning on or off pagination of the output of a
 -      particular git subcommand when writing to a tty.  If
 -      `\--paginate` or `\--no-pager` is specified on the command line,
 -      it takes precedence over this option.  To disable pagination for
 -      all commands, set `core.pager` or `GIT_PAGER` to `cat`.
 +      If the value is boolean, turns on or off pagination of the
 +      output of a particular git subcommand when writing to a tty.
 +      Otherwise, turns on pagination for the subcommand using the
 +      pager specified by the value of `pager.<cmd>`.  If `\--paginate`
 +      or `\--no-pager` is specified on the command line, it takes
 +      precedence over this option.  To disable pagination for all
 +      commands, set `core.pager` or `GIT_PAGER` to `cat`.
  
  pretty.<name>::
        Alias for a --pretty= format string, as specified in
diff --combined builtin/commit.c
@@@ -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;
@@@ -125,8 -124,6 +125,8 @@@ static struct option builtin_commit_opt
        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)
@@@ -1011,6 -984,8 +1011,8 @@@ static int parse_status_slot(const cha
  {
        if (!strcasecmp(var+offset, "header"))
                return WT_STATUS_HEADER;
+       if (!strcasecmp(var+offset, "branch"))
+               return WT_STATUS_ONBRANCH;
        if (!strcasecmp(var+offset, "updated")
                || !strcasecmp(var+offset, "added"))
                return WT_STATUS_UPDATED;
@@@ -1097,9 -1072,6 +1099,9 @@@ int cmd_status(int argc, const char **a
                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;
  
@@@ -1285,9 -1257,6 +1287,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 t/t7508-status.sh
@@@ -7,30 -7,6 +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 &&
@@@ -405,12 -381,13 +405,13 @@@ test_expect_success 'status --porcelai
  
  test_expect_success 'setup unique colors' '
  
-       git config status.color.untracked blue
+       git config status.color.untracked blue &&
+       git config status.color.branch green
  
  '
  
  cat >expect <<\EOF
- # On branch master
+ # On branch <GREEN>master<RESET>
  # Changes to be committed:
  #   (use "git reset HEAD <file>..." to unstage)
  #
diff --combined wt-status.c
@@@ -21,11 -21,15 +21,15 @@@ static char default_wt_status_colors[][
        GIT_COLOR_RED,    /* WT_STATUS_UNMERGED */
        GIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */
        GIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */
+       GIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */
  };
  
  static const char *color(int slot, struct wt_status *s)
  {
-       return s->use_color > 0 ? s->color_palette[slot] : "";
+       const char *c = s->use_color > 0 ? s->color_palette[slot] : "";
+       if (slot == WT_STATUS_ONBRANCH && color_is_nil(c))
+               c = s->color_palette[WT_STATUS_HEADER];
+       return c;
  }
  
  void wt_status_prepare(struct wt_status *s)
@@@ -625,7 -629,8 +629,8 @@@ static void wt_status_print_tracking(st
  
  void wt_status_print(struct wt_status *s)
  {
-       const char *branch_color = color(WT_STATUS_HEADER, s);
+       const char *branch_color = color(WT_STATUS_ONBRANCH, s);
+       const char *branch_status_color = color(WT_STATUS_HEADER, s);
  
        if (s->branch) {
                const char *on_what = "On branch ";
                        branch_name += 11;
                else if (!strcmp(branch_name, "HEAD")) {
                        branch_name = "";
-                       branch_color = color(WT_STATUS_NOBRANCH, s);
+                       branch_status_color = color(WT_STATUS_NOBRANCH, s);
                        on_what = "Not currently on any branch.";
                }
                color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "# ");
-               color_fprintf_ln(s->fp, branch_color, "%s%s", on_what, branch_name);
+               color_fprintf(s->fp, branch_status_color, "%s", on_what);
+               color_fprintf_ln(s->fp, branch_color, "%s", branch_name);
                if (!s->is_initial)
                        wt_status_print_tracking(s);
        }
@@@ -744,20 -750,10 +750,20 @@@ static void wt_shortstatus_status(int n
                const char *one;
                if (d->head_path) {
                        one = quote_path(d->head_path, -1, &onebuf, s->prefix);
 +                      if (*one != '"' && strchr(one, ' ') != NULL) {
 +                              putchar('"');
 +                              strbuf_addch(&onebuf, '"');
 +                              one = onebuf.buf;
 +                      }
                        printf("%s -> ", one);
                        strbuf_release(&onebuf);
                }
                one = quote_path(it->string, -1, &onebuf, s->prefix);
 +              if (*one != '"' && strchr(one, ' ') != NULL) {
 +                      putchar('"');
 +                      strbuf_addch(&onebuf, '"');
 +                      one = onebuf.buf;
 +              }
                printf("%s\n", one);
                strbuf_release(&onebuf);
        }