Merge branch 'jk/colors'
authorJunio C Hamano <gitster@pobox.com>
Mon, 22 Dec 2014 20:27:58 +0000 (12:27 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 22 Dec 2014 20:27:58 +0000 (12:27 -0800)
"diff-highlight" filter (in contrib/) allows its color output
to be customized via configuration variables.

* jk/colors:
parse_color: drop COLOR_BACKGROUND macro
diff-highlight: allow configurable colors
parse_color: recognize "no$foo" to clear the $foo attribute
parse_color: support 24-bit RGB values
parse_color: refactor color storage

1  2 
Documentation/config.txt
contrib/diff-highlight/diff-highlight
diff --combined Documentation/config.txt
index ac781a44d733f672d5b88281a8bea48bc25be226,51947a9e714f84b943a5b27466803b9f15c94f6c..6862e3e30155b7139c960ce2f42f5fba96f11886
@@@ -204,26 -204,13 +204,26 @@@ advice.*:
  --
  
  core.fileMode::
 -      If false, the executable bit differences between the index and
 -      the working tree are ignored; useful on broken filesystems like FAT.
 -      See linkgit:git-update-index[1].
 +      Tells Git if the executable bit of files in the working tree
 +      is to be honored.
  +
 -The default is true, except linkgit:git-clone[1] or linkgit:git-init[1]
 -will probe and set core.fileMode false if appropriate when the
 -repository is created.
 +Some filesystems lose the executable bit when a file that is
 +marked as executable is checked out, or checks out an
 +non-executable file with executable bit on.
 +linkgit:git-clone[1] or linkgit:git-init[1] probe the filesystem
 +to see if it handles the executable bit correctly
 +and this variable is automatically set as necessary.
 ++
 +A repository, however, may be on a filesystem that handles
 +the filemode correctly, and this variable is set to 'true'
 +when created, but later may be made accessible from another
 +environment that loses the filemode (e.g. exporting ext4 via
 +CIFS mount, visiting a Cygwin created repository with
 +Git for Windows or Eclipse).
 +In such a case it may be necessary to set this variable to 'false'.
 +See linkgit:git-update-index[1].
 ++
 +The default is true (when core.filemode is not specified in the config file).
  
  core.ignorecase::
        If true, this option enables various workarounds to enable
@@@ -246,17 -233,6 +246,17 @@@ core.precomposeunicode:
        When false, file names are handled fully transparent by Git,
        which is backward compatible with older versions of Git.
  
 +core.protectHFS::
 +      If set to true, do not allow checkout of paths that would
 +      be considered equivalent to `.git` on an HFS+ filesystem.
 +      Defaults to `true` on Mac OS, and `false` elsewhere.
 +
 +core.protectNTFS::
 +      If set to true, do not allow checkout of paths that would
 +      cause problems with the NTFS filesystem, e.g. conflict with
 +      8.3 "short" names.
 +      Defaults to `true` on Windows, and `false` elsewhere.
 +
  core.trustctime::
        If false, the ctime differences between the index and the
        working tree are ignored; useful when the inode change time
@@@ -523,8 -499,7 +523,8 @@@ core.bigFileThreshold:
        Files larger than this size are stored deflated, without
        attempting delta compression.  Storing large files without
        delta compression avoids excessive memory usage, at the
 -      slight expense of increased disk usage.
 +      slight expense of increased disk usage. Additionally files
 +      larger than this size are always treated as binary.
  +
  Default is 512 MiB on all platforms.  This should be reasonable
  for most projects as source code and other text files can still
@@@ -849,11 -824,13 +849,13 @@@ accepted are `normal`, `black`, `red`, 
  `magenta`, `cyan` and `white`; the attributes are `bold`, `dim`, `ul`,
  `blink` and `reverse`.  The first color given is the foreground; the
  second is the background.  The position of the attribute, if any,
- doesn't matter.
+ doesn't matter. Attributes may be turned off specifically by prefixing
+ them with `no` (e.g., `noreverse`, `noul`, etc).
  +
  Colors (foreground and background) may also be given as numbers between
  0 and 255; these use ANSI 256-color mode (but note that not all
- terminals may support this).
+ terminals may support this).  If your terminal supports it, you may also
+ specify 24-bit RGB values as hex, like `#ff0ab3`.
  
  color.diff::
        Whether to use ANSI escape sequences to add color to patches.
@@@ -900,11 -877,7 +902,11 @@@ color.grep.<slot>:
  `linenumber`;;
        line number prefix (when using `-n`)
  `match`;;
 -      matching text
 +      matching text (same as setting `matchContext` and `matchSelected`)
 +`matchContext`;;
 +      matching text in context lines
 +`matchSelected`;;
 +      matching text in selected lines
  `selected`;;
        non-matching text in selected lines
  `separator`;;
@@@ -1225,7 -1198,7 +1227,7 @@@ gc.autopacklimit:
        default value is 50.  Setting this to 0 disables it.
  
  gc.autodetach::
 -      Make `git gc --auto` return immediately andrun in background
 +      Make `git gc --auto` return immediately and run in background
        if the system supports it. Default is true.
  
  gc.packrefs::
@@@ -1372,7 -1345,7 +1374,7 @@@ gpg.program:
        same command-line interface as GPG, namely, to verify a detached
        signature, "gpg --verify $file - <$signature" is run, and the
        program is expected to signal a good signature by exiting with
 -      code 0, and to generate an ascii-armored detached signature, the
 +      code 0, and to generate an ASCII-armored detached signature, the
        standard input of "gpg -bsau $key" is fed with the contents to be
        signed, and the program is expected to send the result to its
        standard output.
@@@ -1607,7 -1580,7 +1609,7 @@@ http.useragent:
        Can be overridden by the 'GIT_HTTP_USER_AGENT' environment variable.
  
  http.<url>.*::
 -      Any of the http.* options above can be applied selectively to some urls.
 +      Any of the http.* options above can be applied selectively to some URLs.
        For a config key to match a URL, each element of the config key is
        compared to that of the URL, in the following order:
  +
@@@ -1646,8 -1619,8 +1648,8 @@@ if the URL is `https://user@example.com
  +
  All URLs are normalized before attempting any matching (the password part,
  if embedded in the URL, is always ignored for matching purposes) so that
 -equivalent urls that are simply spelled differently will match properly.
 -Environment variable settings always override any matches.  The urls that are
 +equivalent URLs that are simply spelled differently will match properly.
 +Environment variable settings always override any matches.  The URLs that are
  matched against are those given directly to Git commands.  This means any URLs
  visited as a result of a redirection do not participate in matching.
  
@@@ -1809,12 -1782,6 +1811,12 @@@ mergetool.keepTemporaries:
        preserved, otherwise they will be removed after the tool has
        exited. Defaults to `false`.
  
 +mergetool.writeToTemp::
 +      Git writes temporary 'BASE', 'LOCAL', and 'REMOTE' versions of
 +      conflicting files in the worktree by default.  Git will attempt
 +      to use a temporary directory for these files when set `true`.
 +      Defaults to `false`.
 +
  mergetool.prompt::
        Prompt before each invocation of the merge resolution program.
  
@@@ -1875,11 -1842,10 +1877,11 @@@ pack.depth:
        maximum depth is given on the command line. Defaults to 50.
  
  pack.windowMemory::
 -      The window memory size limit used by linkgit:git-pack-objects[1]
 -      when no limit is given on the command line.  The value can be
 -      suffixed with "k", "m", or "g".  Defaults to 0, meaning no
 -      limit.
 +      The maximum size of memory that is consumed by each thread
 +      in linkgit:git-pack-objects[1] for pack window memory when
 +      no limit is given on the command line.  The value can be
 +      suffixed with "k", "m", or "g".  When left unconfigured (or
 +      set explicitly to 0), there will be no limit.
  
  pack.compression::
        An integer -1..9, indicating the compression level for objects
@@@ -2092,25 -2058,6 +2094,25 @@@ receive.autogc:
        receiving data from git-push and updating refs.  You can stop
        it by setting this variable to false.
  
 +receive.certnonceseed::
 +      By setting this variable to a string, `git receive-pack`
 +      will accept a `git push --signed` and verifies it by using
 +      a "nonce" protected by HMAC using this string as a secret
 +      key.
 +
 +receive.certnonceslop::
 +      When a `git push --signed` sent a push certificate with a
 +      "nonce" that was issued by a receive-pack serving the same
 +      repository within this many seconds, export the "nonce"
 +      found in the certificate to `GIT_PUSH_CERT_NONCE` to the
 +      hooks (instead of what the receive-pack asked the sending
 +      side to include).  This may allow writing checks in
 +      `pre-receive` and `post-receive` a bit easier.  Instead of
 +      checking `GIT_PUSH_CERT_NONCE_SLOP` environment variable
 +      that records by how many seconds the nonce is stale to
 +      decide if they want to accept the certificate, they only
 +      can check `GIT_PUSH_CERT_NONCE_STATUS` is `OK`.
 +
  receive.fsckObjects::
        If it is set to true, git-receive-pack will check all received
        objects. It will abort in the case of a malformed object or a
@@@ -2144,13 -2091,6 +2146,13 @@@ receive.denyCurrentBranch:
        print a warning of such a push to stderr, but allow the push to
        proceed. If set to false or "ignore", allow such pushes with no
        message. Defaults to "refuse".
 ++
 +Another option is "updateInstead" which will update the working
 +directory (must be clean) if pushing into the current branch. This option is
 +intended for synchronizing working directories when one side is not easily
 +accessible via interactive ssh (e.g. a live web site, hence the requirement
 +that the working directory be clean). This mode also comes in handy when
 +developing inside a VM to test and fix code on different Operating Systems.
  
  receive.denyNonFastForwards::
        If set to true, git-receive-pack will deny a ref update which is
@@@ -2325,7 -2265,6 +2327,7 @@@ sendemail.smtpserverport:
  sendemail.smtpserveroption::
  sendemail.smtpuser::
  sendemail.thread::
 +sendemail.transferencoding::
  sendemail.validate::
        See linkgit:git-send-email[1] for description.
  
index 69a652e7b2cc4ed2e03ead8aec4b3abeebf20b14,4a5f317b7c5412624a5cc463899a9f743b46cc9a..08c88bbc87e51e25cacc5826b26a223f3bfbd382
@@@ -5,8 -5,18 +5,18 @@@ use strict
  
  # Highlight by reversing foreground and background. You could do
  # other things like bold or underline if you prefer.
- my $HIGHLIGHT   = "\x1b[7m";
- my $UNHIGHLIGHT = "\x1b[27m";
+ my @OLD_HIGHLIGHT = (
+       color_config('color.diff-highlight.oldnormal'),
+       color_config('color.diff-highlight.oldhighlight', "\x1b[7m"),
+       color_config('color.diff-highlight.oldreset', "\x1b[27m")
+ );
+ my @NEW_HIGHLIGHT = (
+       color_config('color.diff-highlight.newnormal', $OLD_HIGHLIGHT[0]),
+       color_config('color.diff-highlight.newhighlight', $OLD_HIGHLIGHT[1]),
+       color_config('color.diff-highlight.newreset', $OLD_HIGHLIGHT[2])
+ );
+ my $RESET = "\x1b[m";
  my $COLOR = qr/\x1b\[[0-9;]*m/;
  my $BORING = qr/$COLOR|\s/;
  
@@@ -14,10 -24,6 +24,10 @@@ my @removed
  my @added;
  my $in_hunk;
  
 +# Some scripts may not realize that SIGPIPE is being ignored when launching the
 +# pager--for instance scripts written in Python.
 +$SIG{PIPE} = 'DEFAULT';
 +
  while (<>) {
        if (!$in_hunk) {
                print;
@@@ -57,6 -63,17 +67,17 @@@ show_hunk(\@removed, \@added)
  
  exit 0;
  
+ # Ideally we would feed the default as a human-readable color to
+ # git-config as the fallback value. But diff-highlight does
+ # not otherwise depend on git at all, and there are reports
+ # of it being used in other settings. Let's handle our own
+ # fallback, which means we will work even if git can't be run.
+ sub color_config {
+       my ($key, $default) = @_;
+       my $s = `git config --get-color $key 2>/dev/null`;
+       return length($s) ? $s : $default;
+ }
  sub show_hunk {
        my ($a, $b) = @_;
  
@@@ -132,8 -149,8 +153,8 @@@ sub highlight_pair 
        }
  
        if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
-               return highlight_line(\@a, $pa, $sa),
-                      highlight_line(\@b, $pb, $sb);
+               return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT),
+                      highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT);
        }
        else {
                return join('', @a),
@@@ -148,15 -165,30 +169,30 @@@ sub split_line 
  }
  
  sub highlight_line {
-       my ($line, $prefix, $suffix) = @_;
-       return join('',
-               @{$line}[0..($prefix-1)],
-               $HIGHLIGHT,
-               @{$line}[$prefix..$suffix],
-               $UNHIGHLIGHT,
-               @{$line}[($suffix+1)..$#$line]
-       );
+       my ($line, $prefix, $suffix, $theme) = @_;
+       my $start = join('', @{$line}[0..($prefix-1)]);
+       my $mid = join('', @{$line}[$prefix..$suffix]);
+       my $end = join('', @{$line}[($suffix+1)..$#$line]);
+       # If we have a "normal" color specified, then take over the whole line.
+       # Otherwise, we try to just manipulate the highlighted bits.
+       if (defined $theme->[0]) {
+               s/$COLOR//g for ($start, $mid, $end);
+               chomp $end;
+               return join('',
+                       $theme->[0], $start, $RESET,
+                       $theme->[1], $mid, $RESET,
+                       $theme->[0], $end, $RESET,
+                       "\n"
+               );
+       } else {
+               return join('',
+                       $start,
+                       $theme->[1], $mid, $theme->[2],
+                       $end
+               );
+       }
  }
  
  # Pairs are interesting to highlight only if we are going to end up