Code

Merge branch 'mh/show-branch-color' into sb/show-branch-parse-options
authorJunio C Hamano <gitster@pobox.com>
Thu, 21 May 2009 15:55:02 +0000 (08:55 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 23 May 2009 05:47:47 +0000 (22:47 -0700)
* branch 'mh/show-branch-color':
  bash completion: show-branch color support
  show-branch: color the commit status signs

1  2 
Documentation/config.txt
Documentation/git-show-branch.txt
builtin-show-branch.c
contrib/completion/git-completion.bash

diff --combined Documentation/config.txt
index 5dcad94f841c395beb21961ebdacd341d76b25c9,1383a29b0007c01b297ce62ddb84c524d2248fd5..2c031620c50f8e3eaaa652aaf43ee261eab8f957
@@@ -2,15 -2,15 +2,15 @@@ CONFIGURATION FIL
  ------------------
  
  The git configuration file contains a number of variables that affect
 -the git command's behavior. `.git/config` file for each repository
 -is used to store the information for that repository, and
 -`$HOME/.gitconfig` is used to store per user information to give
 -fallback values for `.git/config` file. The file `/etc/gitconfig`
 -can be used to store system-wide defaults.
 -
 -They can be used by both the git plumbing
 -and the porcelains. The variables are divided into sections, where
 -in the fully qualified variable name the variable itself is the last
 +the git command's behavior. The `.git/config` file in each repository
 +is used to store the configuration for that repository, and
 +`$HOME/.gitconfig` is used to store a per-user configuration as
 +fallback values for the `.git/config` file. The file `/etc/gitconfig`
 +can be used to store a system-wide default configuration.
 +
 +The configuration variables are used by both the git plumbing
 +and the porcelains. The variables are divided into sections, wherein
 +the fully qualified variable name of the variable itself is the last
  dot-separated segment and the section name is everything before the last
  dot. The variable names are case-insensitive and only alphanumeric
  characters are allowed. Some variables may appear multiple times.
@@@ -26,28 -26,28 +26,28 @@@ The file consists of sections and varia
  the name of the section in square brackets and continues until the next
  section begins.  Section names are not case sensitive.  Only alphanumeric
  characters, `-` and `.` are allowed in section names.  Each variable
 -must belong to some section, which means that there must be section
 -header before first setting of a variable.
 +must belong to some section, which means that there must be section
 +header before the first setting of a variable.
  
  Sections can be further divided into subsections.  To begin a subsection
  put its name in double quotes, separated by space from the section name,
 -in the section header, like in example below:
 +in the section header, like in the example below:
  
  --------
        [section "subsection"]
  
  --------
  
 -Subsection names can contain any characters except newline (doublequote
 -`"` and backslash have to be escaped as `\"` and `\\`,
 -respectively) and are case sensitive.  Section header cannot span multiple
 +Subsection names are case sensitive and can contain any characters except
 +newline (doublequote `"` and backslash have to be escaped as `\"` and `\\`,
 +respectively).  Section headers cannot span multiple
  lines.  Variables may belong directly to a section or to a given subsection.
  You can have `[section]` if you have `[section "subsection"]`, but you
  don't need to.
  
 -There is also (case insensitive) alternative `[section.subsection]` syntax.
 -In this syntax subsection names follow the same restrictions as for section
 -name.
 +There is also a case insensitive alternative `[section.subsection]` syntax.
 +In this syntax, subsection names follow the same restrictions as for section
 +names.
  
  All the other lines are recognized as setting variables, in the form
  'name = value'.  If there is no equal sign on the line, the entire line
@@@ -66,10 -66,10 +66,10 @@@ converting value to the canonical form 
  'git-config' will ensure that the output is "true" or "false".
  
  String values may be entirely or partially enclosed in double quotes.
 -You need to enclose variable value in double quotes if you want to
 -preserve leading or trailing whitespace, or if variable value contains
 -beginning of comment characters (if it contains '#' or ';').
 -Double quote `"` and backslash `\` characters in variable value must
 +You need to enclose variable values in double quotes if you want to
 +preserve leading or trailing whitespace, or if the variable value contains
 +comment characters (i.e. it contains '#' or ';').
 +Double quote `"` and backslash `\` characters in variable values must
  be escaped: use `\"` for `"` and `\\` for `\`.
  
  The following escape sequences (beside `\"` and `\\`) are recognized:
  and `\b` for backspace (BS).  No other char escape sequence, nor octal
  char sequences are valid.
  
 -Variable value ending in a `\` is continued on the next line in the
 +Variable values ending in a `\` are continued on the next line in the
  customary UNIX fashion.
  
 -Some variables may require special value format.
 +Some variables may require special value format.
  
  Example
  ~~~~~~~
@@@ -429,15 -429,6 +429,15 @@@ relatively high IO latencies.  With thi
  index comparison to the filesystem data in parallel, allowing
  overlapping IO's.
  
 +core.createObject::
 +      You can set this to 'link', in which case a hardlink followed by
 +      a delete of the source are used to make sure that object creation
 +      will not overwrite existing objects.
 ++
 +On some file system/operating system combinations, this is unreliable.
 +Set this config setting to 'rename' there; However, This will remove the
 +check that makes sure that existing object files will not get overwritten.
 +
  alias.*::
        Command aliases for the linkgit:git[1] command wrapper - e.g.
        after defining "alias.last = cat-file commit HEAD", the invocation
@@@ -604,6 -595,12 +604,12 @@@ color.pager:
        A boolean to enable/disable colored output when the pager is in
        use (default is true).
  
+ color.showbranch::
+       A boolean to enable/disable color in the output of
+       linkgit:git-show-branch[1]. May be set to `always`,
+       `false` (or `never`) or `auto` (or `true`), in which case colors are used
+       only when the output is to a terminal. Defaults to false.
  color.status::
        A boolean to enable/disable color in the output of
        linkgit:git-status[1]. May be set to `always`,
@@@ -716,13 -713,6 +722,13 @@@ fetch.unpackLimit:
        especially on slow filesystems.  If not set, the value of
        `transfer.unpackLimit` is used instead.
  
 +format.attach::
 +      Enable multipart/mixed attachments as the default for
 +      'format-patch'.  The value can also be a double quoted string
 +      which will enable attachments as the default and set the
 +      value as the boundary.  See the --attach option in
 +      linkgit:git-format-patch[1].
 +
  format.numbered::
        A boolean which can enable or disable sequence numbers in patch
        subjects.  It defaults to "auto" which enables it only if there
@@@ -734,14 -724,6 +740,14 @@@ format.headers:
        Additional email headers to include in a patch to be submitted
        by mail.  See linkgit:git-format-patch[1].
  
 +format.cc::
 +      Additional "Cc:" headers to include in a patch to be submitted
 +      by mail.  See the --cc option in linkgit:git-format-patch[1].
 +
 +format.subjectprefix::
 +      The default for format-patch is to output files with the '[PATCH]'
 +      subject prefix. Use this variable to change that prefix.
 +
  format.suffix::
        The default for format-patch is to output files with the suffix
        `.patch`. Use this variable to change that suffix (make sure to
@@@ -754,11 -736,11 +760,11 @@@ format.pretty:
  
  format.thread::
        The default threading style for 'git-format-patch'.  Can be
 -      either a boolean value, `shallow` or `deep`.  'Shallow'
 +      either a boolean value, `shallow` or `deep`.  `shallow`
        threading makes every mail a reply to the head of the series,
        where the head is chosen from the cover letter, the
        `\--in-reply-to`, and the first patch mail, in this order.
 -      'Deep' threading makes every mail a reply to the previous one.
 +      `deep` threading makes every mail a reply to the previous one.
        A true boolean value is the same as `shallow`, and a false
        value disables threading.
  
index 51a4e9d6d767f34205f418ec86a6281dbf4c7b2c,05868b68f62afa3f8c06def305e6acaf0bba7c14..edd8f6463ebab38f950db634e28fe5f06cf3915a
@@@ -10,6 -10,7 +10,7 @@@ SYNOPSI
  [verse]
  'git show-branch' [--all] [--remotes] [--topo-order] [--current]
                [--more=<n> | --list | --independent | --merge-base]
+               [--color | --no-color]
                [--no-name | --sha1-name] [--topics] [<rev> | <glob>]...
  'git show-branch' (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]
  
@@@ -107,6 -108,14 +108,14 @@@ OPTION
        When no explicit <ref> parameter is given, it defaults to the
        current branch (or `HEAD` if it is detached).
  
+ --color::
+       Color the status sign (one of these: `*` `!` `+` `-`) of each commit
+       corresponding to the branch it's in.
+ --no-color::
+       Turn off colored output, even when the configuration file gives the
+       default to color output.
  Note that --more, --list, --independent and --merge-base options
  are mutually exclusive.
  
@@@ -148,10 -157,9 +157,10 @@@ $ git show-branch master fixes mh
  ------------------------------------------------
  
  These three branches all forked from a common commit, [master],
 -whose commit message is "Add 'git show-branch'.  "fixes" branch
 -adds one commit 'Introduce "reset type"'.  "mhf" branch has many
 -other commits.  The current branch is "master".
 +whose commit message is "Add \'git show-branch\'". The "fixes"
 +branch adds one commit "Introduce "reset type" flag to "git reset"".
 +The "mhf" branch adds many other commits. The current branch
 +is "master".
  
  
  EXAMPLE
diff --combined builtin-show-branch.c
index c3afabbe914d699a8e0c80bdb5063ca51506167e,fc38f5e005557396af507d4b3b934ec97b32d0e2..c8e9b3c723cb733e1d6b4cd2036f165f0a088970
@@@ -2,12 -2,25 +2,25 @@@
  #include "commit.h"
  #include "refs.h"
  #include "builtin.h"
+ #include "color.h"
  
  static const char show_branch_usage[] =
  "git show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n[,b]] <branch>";
  static const char show_branch_usage_reflog[] =
  "--reflog is incompatible with --all, --remotes, --independent or --merge-base";
  
+ static int showbranch_use_color = -1;
+ static char column_colors[][COLOR_MAXLEN] = {
+       GIT_COLOR_RED,
+       GIT_COLOR_GREEN,
+       GIT_COLOR_YELLOW,
+       GIT_COLOR_BLUE,
+       GIT_COLOR_MAGENTA,
+       GIT_COLOR_CYAN,
+ };
+ #define COLUMN_COLORS_MAX (ARRAY_SIZE(column_colors))
  static int default_num;
  static int default_alloc;
  static const char **default_arg;
  
  #define DEFAULT_REFLOG        4
  
+ static const char *get_color_code(int idx)
+ {
+       if (showbranch_use_color)
+               return column_colors[idx];
+       return "";
+ }
+ static const char *get_color_reset_code(void)
+ {
+       if (showbranch_use_color)
+               return GIT_COLOR_RESET;
+       return "";
+ }
  static struct commit *interesting(struct commit_list *list)
  {
        while (list) {
@@@ -545,7 -572,12 +572,12 @@@ static int git_show_branch_config(cons
                return 0;
        }
  
-       return git_default_config(var, value, cb);
+       if (!strcmp(var, "color.showbranch")) {
+               showbranch_use_color = git_config_colorbool(var, value, -1);
+               return 0;
+       }
+       return git_color_default_config(var, value, cb);
  }
  
  static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
@@@ -576,7 -608,7 +608,7 @@@ static void parse_reflog_param(const ch
        if (*ep == ',')
                *base = ep + 1;
        else if (*ep)
 -              die("unrecognized reflog param '%s'", arg + 9);
 +              die("unrecognized reflog param '%s'", arg);
        else
                *base = NULL;
        if (*cnt <= 0)
@@@ -611,6 -643,9 +643,9 @@@ int cmd_show_branch(int ac, const char 
  
        git_config(git_show_branch_config, NULL);
  
+       if (showbranch_use_color == -1)
+               showbranch_use_color = git_use_color_default;
        /* If nothing is specified, try the default first */
        if (ac == 1 && default_num) {
                ac = default_num + 1;
                        parse_reflog_param(arg + 9, &reflog, &reflog_base);
                else if (!prefixcmp(arg, "-g="))
                        parse_reflog_param(arg + 3, &reflog, &reflog_base);
+               else if (!strcmp(arg, "--color"))
+                       showbranch_use_color = 1;
+               else if (!strcmp(arg, "--no-color"))
+                       showbranch_use_color = 0;
                else
                        usage(show_branch_usage);
                ac--; av++;
                        else {
                                for (j = 0; j < i; j++)
                                        putchar(' ');
-                               printf("%c [%s] ",
-                                      is_head ? '*' : '!', ref_name[i]);
+                               printf("%s%c%s [%s] ",
+                                      get_color_code(i % COLUMN_COLORS_MAX),
+                                      is_head ? '*' : '!',
+                                      get_color_reset_code(), ref_name[i]);
                        }
  
                        if (!reflog) {
                                        mark = '*';
                                else
                                        mark = '+';
-                               putchar(mark);
+                               printf("%s%c%s",
+                                      get_color_code(i % COLUMN_COLORS_MAX),
+                                      mark, get_color_reset_code());
                        }
                        putchar(' ');
                }
index a0c5794828a6ed00a3608d9ec22046478da83e96,b5883872628f8ffa3972e7a082d0a62c12037845..451a97f0788a195e186ad114edb895267a093143
@@@ -99,32 -99,20 +99,32 @@@ __git_ps1 (
                elif [ -d "$g/rebase-merge" ]; then
                        r="|REBASE-m"
                        b="$(cat "$g/rebase-merge/head-name")"
 -              elif [ -f "$g/MERGE_HEAD" ]; then
 -                      r="|MERGING"
 -                      b="$(git symbolic-ref HEAD 2>/dev/null)"
                else
 +                      if [ -f "$g/MERGE_HEAD" ]; then
 +                              r="|MERGING"
 +                      fi
                        if [ -f "$g/BISECT_LOG" ]; then
                                r="|BISECTING"
                        fi
 -                      if ! b="$(git symbolic-ref HEAD 2>/dev/null)"; then
 -                              if ! b="$(git describe --exact-match HEAD 2>/dev/null)"; then
 -                                      if [ -r "$g/HEAD" ]; then
 -                                              b="$(cut -c1-7 "$g/HEAD")..."
 -                                      fi
 -                              fi
 -                      fi
 +
 +                      b="$(git symbolic-ref HEAD 2>/dev/null)" || {
 +
 +                              b="$(
 +                              case "${GIT_PS1_DESCRIBE_STYLE-}" in
 +                              (contains)
 +                                      git describe --contains HEAD ;;
 +                              (branch)
 +                                      git describe --contains --all HEAD ;;
 +                              (describe)
 +                                      git describe HEAD ;;
 +                              (* | default)
 +                                      git describe --exact-match HEAD ;;
 +                              esac 2>/dev/null)" ||
 +
 +                              b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
 +                              b="unknown"
 +                              b="($b)"
 +                      }
                fi
  
                local w
@@@ -1128,7 -1116,6 +1128,7 @@@ __git_log_shortlog_options=
  "
  
  __git_log_pretty_formats="oneline short medium full fuller email raw format:"
 +__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
  
  _git_log ()
  {
                return
                ;;
        --date=*)
 -              __gitcomp "
 -                      relative iso8601 rfc2822 short local default
 -              " "" "${cur##--date=}"
 +              __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
                return
                ;;
        --*)
@@@ -1294,39 -1283,18 +1294,39 @@@ _git_rebase (
        __gitcomp "$(__git_refs)"
  }
  
 +__git_send_email_confirm_options="always never auto cc compose"
 +__git_send_email_suppresscc_options="author self cc ccbody sob cccmd body all"
 +
  _git_send_email ()
  {
        local cur="${COMP_WORDS[COMP_CWORD]}"
        case "$cur" in
 +      --confirm=*)
 +              __gitcomp "
 +                      $__git_send_email_confirm_options
 +                      " "" "${cur##--confirm=}"
 +              return
 +              ;;
 +      --suppress-cc=*)
 +              __gitcomp "
 +                      $__git_send_email_suppresscc_options
 +                      " "" "${cur##--suppress-cc=}"
 +
 +              return
 +              ;;
 +      --smtp-encryption=*)
 +              __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
 +              return
 +              ;;
        --*)
                __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
 -                      --compose --dry-run --envelope-sender --from --identity
 +                      --compose --confirm= --dry-run --envelope-sender
 +                      --from --identity
                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
                        --no-suppress-from --no-thread --quiet
                        --signed-off-by-cc --smtp-pass --smtp-server
 -                      --smtp-server-port --smtp-ssl --smtp-user --subject
 -                      --suppress-cc --suppress-from --thread --to
 +                      --smtp-server-port --smtp-encryption= --smtp-user
 +                      --subject --suppress-cc= --suppress-from --thread --to
                        --validate --no-validate"
                return
                ;;
@@@ -1365,7 -1333,8 +1365,8 @@@ _git_config (
                __gitcomp "$(__git_merge_strategies)"
                return
                ;;
-       color.branch|color.diff|color.interactive|color.status|color.ui)
+       color.branch|color.diff|color.interactive|\
+       color.showbranch|color.status|color.ui)
                __gitcomp "always never auto"
                return
                ;;
                        "
                return
                ;;
 +      help.format)
 +              __gitcomp "man info web html"
 +              return
 +              ;;
 +      log.date)
 +              __gitcomp "$__git_log_date_formats"
 +              return
 +              ;;
 +      sendemail.aliasesfiletype)
 +              __gitcomp "mutt mailrc pine elm gnus"
 +              return
 +              ;;
 +      sendemail.confirm)
 +              __gitcomp "$__git_send_email_confirm_options"
 +              return
 +              ;;
 +      sendemail.suppresscc)
 +              __gitcomp "$__git_send_email_suppresscc_options"
 +              return
 +              ;;
        *.*)
                COMPREPLY=()
                return
                __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
                return
                ;;
 +      guitool.*.*)
 +              local pfx="${cur%.*}."
 +              cur="${cur##*.}"
 +              __gitcomp "
 +                      argprompt cmd confirm needsfile noconsole norescan
 +                      prompt revprompt revunmerged title
 +                      " "$pfx" "$cur"
 +              return
 +              ;;
 +      difftool.*.*)
 +              local pfx="${cur%.*}."
 +              cur="${cur##*.}"
 +              __gitcomp "cmd path" "$pfx" "$cur"
 +              return
 +              ;;
 +      man.*.*)
 +              local pfx="${cur%.*}."
 +              cur="${cur##*.}"
 +              __gitcomp "cmd path" "$pfx" "$cur"
 +              return
 +              ;;
 +      mergetool.*.*)
 +              local pfx="${cur%.*}."
 +              cur="${cur##*.}"
 +              __gitcomp "cmd path trustExitCode" "$pfx" "$cur"
 +              return
 +              ;;
 +      pager.*)
 +              local pfx="${cur%.*}."
 +              cur="${cur#*.}"
 +              __gitcomp "$(__git_all_commands)" "$pfx" "$cur"
 +              return
 +              ;;
        remote.*.*)
                local pfx="${cur%.*}."
                cur="${cur##*.}"
                __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
                return
                ;;
 +      url.*.*)
 +              local pfx="${cur%.*}."
 +              cur="${cur##*.}"
 +              __gitcomp "insteadof" "$pfx" "$cur"
 +              return
 +              ;;
        esac
        __gitcomp "
 +              alias.
                apply.whitespace
                branch.autosetupmerge
                branch.autosetuprebase
                color.diff.old
                color.diff.plain
                color.diff.whitespace
 +              color.grep
 +              color.grep.external
 +              color.grep.match
                color.interactive
                color.interactive.header
                color.interactive.help
                color.interactive.prompt
                color.pager
+               color.showbranch
                color.status
                color.status.added
                color.status.changed
                core.autocrlf
                core.bare
                core.compression
 +              core.createObject
                core.deltaBaseCacheLimit
                core.editor
                core.excludesfile
                diff.renameLimit
                diff.renameLimit.
                diff.renames
 +              diff.suppressBlankEmpty
 +              diff.tool
 +              diff.wordRegex
 +              difftool.
 +              difftool.prompt
                fetch.unpackLimit
 +              format.attach
 +              format.cc
                format.headers
                format.numbered
                format.pretty
 +              format.signoff
 +              format.subjectprefix
                format.suffix
 +              format.thread
                gc.aggressiveWindow
                gc.auto
                gc.autopacklimit
                gc.rerereresolved
                gc.rerereunresolved
                gitcvs.allbinary
 +              gitcvs.commitmsgannotation
                gitcvs.dbTableNamePrefix
                gitcvs.dbdriver
                gitcvs.dbname
                gitcvs.enabled
                gitcvs.logfile
                gitcvs.usecrlfattr
 +              guitool.
                gui.blamehistoryctx
                gui.commitmsgwidth
                gui.copyblamethreshold
                http.sslVerify
                i18n.commitEncoding
                i18n.logOutputEncoding
 +              imap.folder
 +              imap.host
 +              imap.pass
 +              imap.port
 +              imap.preformattedHTML
 +              imap.sslverify
 +              imap.tunnel
 +              imap.user
                instaweb.browser
                instaweb.httpd
                instaweb.local
                instaweb.modulepath
                instaweb.port
 +              interactive.singlekey
                log.date
                log.showroot
 +              mailmap.file
 +              man.
                man.viewer
                merge.conflictstyle
                merge.log
                merge.stat
                merge.tool
                merge.verbosity
 +              mergetool.
                mergetool.keepBackup
 +              mergetool.prompt
                pack.compression
                pack.deltaCacheLimit
                pack.deltaCacheSize
                pack.threads
                pack.window
                pack.windowMemory
 +              pager.
                pull.octopus
                pull.twohead
 +              push.default
 +              rebase.stat
                receive.denyCurrentBranch
                receive.denyDeletes
                receive.denyNonFastForwards
                repack.usedeltabaseoffset
                rerere.autoupdate
                rerere.enabled
 +              sendemail.aliasesfile
 +              sendemail.aliasesfiletype
 +              sendemail.bcc
 +              sendemail.cc
 +              sendemail.cccmd
 +              sendemail.chainreplyto
 +              sendemail.confirm
 +              sendemail.envelopesender
 +              sendemail.multiedit
 +              sendemail.signedoffbycc
 +              sendemail.smtpencryption
 +              sendemail.smtppass
 +              sendemail.smtpserver
 +              sendemail.smtpserverport
 +              sendemail.smtpuser
 +              sendemail.suppresscc
 +              sendemail.suppressfrom
 +              sendemail.thread
 +              sendemail.to
 +              sendemail.validate
                showbranch.default
                status.relativePaths
                status.showUntrackedFiles
                tar.umask
                transfer.unpackLimit
 +              url.
                user.email
                user.name
                user.signingkey
@@@ -1804,7 -1661,7 +1806,7 @@@ _git_show (
                return
                ;;
        --*)
 -              __gitcomp "--pretty= --format=
 +              __gitcomp "--pretty= --format= --abbrev-commit --oneline
                        $__git_diff_common_options
                        "
                return
@@@ -1821,7 -1678,8 +1823,8 @@@ _git_show_branch (
                __gitcomp "
                        --all --remotes --topo-order --current --more=
                        --list --independent --merge-base --no-name
 -                      --sha1-name --topics --reflog
+                       --color --no-color
 +                      --sha1-name --sparse --topics --reflog
                        "
                return
                ;;