Merge branch 'rj/cygwin-clarify-use-of-cheating-lstat'
authorJunio C Hamano <gitster@pobox.com>
Fri, 2 Aug 2013 18:01:00 +0000 (11:01 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Aug 2013 18:01:01 +0000 (11:01 -0700)
Cygwin port added a "not quite correct but a lot faster and good
enough for many lstat() calls that are only used to see if the
working tree entity matches the index entry" lstat() emulation some
time ago, and it started biting us in places. This removes it and
uses the standard lstat() that comes with Cygwin.

Recent topic that uses lstat on packed-refs file is broken when
this cheating lstat is used, and this is a simplest fix that is
also the cleanest direction to go in the long run.

* rj/cygwin-clarify-use-of-cheating-lstat:
cygwin: Remove the Win32 l/stat() implementation

1  2 
Documentation/config.txt
Makefile
config.mak.uname
contrib/completion/git-completion.bash
git-compat-util.h
path.c
diff --combined Documentation/config.txt
index e0b923f428094f1303084778bee7ab9e502709a4,fe49cb9d47e596c7e1b39cd355c52906244d9d4e..ec57a15ac5da284f35ced4441e2315fec9b05e2d
@@@ -213,17 -213,6 +213,6 @@@ The default is true, except linkgit:git
  will probe and set core.fileMode false if appropriate when the
  repository is created.
  
- core.ignoreCygwinFSTricks::
-       This option is only used by Cygwin implementation of Git. If false,
-       the Cygwin stat() and lstat() functions are used. This may be useful
-       if your repository consists of a few separate directories joined in
-       one hierarchy using Cygwin mount. If true, Git uses native Win32 API
-       whenever it is possible and falls back to Cygwin functions only to
-       handle symbol links. The native mode is more than twice faster than
-       normal Cygwin l/stat() functions. True by default, unless core.filemode
-       is true, in which case ignoreCygwinFSTricks is ignored as Cygwin's
-       POSIX emulation is required to support core.filemode.
  core.ignorecase::
        If true, this option enables various workarounds to enable
        Git to work better on filesystems that are not case sensitive,
@@@ -879,17 -868,16 +868,17 @@@ The values of these variables may be sp
  
  color.interactive::
        When set to `always`, always use colors for interactive prompts
 -      and displays (such as those used by "git-add --interactive").
 -      When false (or `never`), never.  When set to `true` or `auto`, use
 -      colors only when the output is to the terminal. Defaults to false.
 +      and displays (such as those used by "git-add --interactive" and
 +      "git-clean --interactive"). When false (or `never`), never.
 +      When set to `true` or `auto`, use colors only when the output is
 +      to the terminal. Defaults to false.
  
  color.interactive.<slot>::
 -      Use customized color for 'git add --interactive'
 -      output. `<slot>` may be `prompt`, `header`, `help` or `error`, for
 -      four distinct types of normal output from interactive
 -      commands.  The values of these variables may be specified as
 -      in color.branch.<slot>.
 +      Use customized color for 'git add --interactive' and 'git clean
 +      --interactive' output. `<slot>` may be `prompt`, `header`, `help`
 +      or `error`, for four distinct types of normal output from
 +      interactive commands.  The values of these variables may be
 +      specified as in color.branch.<slot>.
  
  color.pager::
        A boolean to enable/disable colored output when the pager is in
@@@ -974,10 -962,6 +963,10 @@@ column.branch:
        Specify whether to output branch listing in `git branch` in columns.
        See `column.ui` for details.
  
 +column.clean::
 +      Specify the layout when list items in `git clean -i`, which always
 +      shows files and directories in columns. See `column.ui` for details.
 +
  column.status::
        Specify whether to output untracked files in `git status` in columns.
        See `column.ui` for details.
@@@ -2073,10 -2057,6 +2062,10 @@@ sendemail.smtpencryption:
  sendemail.smtpssl::
        Deprecated alias for 'sendemail.smtpencryption = ssl'.
  
 +sendemail.smtpsslcertpath::
 +      Path to ca-certificates (either a directory or a single file).
 +      Set it to an empty string to disable certificate verification.
 +
  sendemail.<identity>.*::
        Identity-specific versions of the 'sendemail.*' parameters
        found below, taking precedence over those when the this
diff --combined Makefile
index ef442ebad097a47bb19ea75037e62c51d9bb5d8b,9c0da06e4abb30c5524377fe7affa63a4cd97850..3588ca1b6a575e8bb732dcc04b7c59dcb7f15cf4
+++ b/Makefile
@@@ -654,7 -654,6 +654,6 @@@ LIB_H += color.
  LIB_H += column.h
  LIB_H += commit.h
  LIB_H += compat/bswap.h
- LIB_H += compat/cygwin.h
  LIB_H += compat/mingw.h
  LIB_H += compat/obstack.h
  LIB_H += compat/poll/poll.h
@@@ -912,7 -911,6 +911,7 @@@ BUILTIN_OBJS += builtin/bundle.
  BUILTIN_OBJS += builtin/cat-file.o
  BUILTIN_OBJS += builtin/check-attr.o
  BUILTIN_OBJS += builtin/check-ignore.o
 +BUILTIN_OBJS += builtin/check-mailmap.o
  BUILTIN_OBJS += builtin/check-ref-format.o
  BUILTIN_OBJS += builtin/checkout-index.o
  BUILTIN_OBJS += builtin/checkout.o
diff --combined config.mak.uname
index b45b91075966f450e221bb373ab79a311093284d,1666551f61dd8a54e97b437f86f3c89854241ef6..b27f51d4862c67f2dcc61c93f9e2db46f8e44bf6
@@@ -159,19 -159,17 +159,18 @@@ ifeq ($(uname_O),Cygwin
                NO_SYMLINK_HEAD = YesPlease
                NO_IPV6 = YesPlease
                OLD_ICONV = UnfortunatelyYes
 +              NO_THREAD_SAFE_PREAD = YesPlease
 +              # There are conflicting reports about this.
 +              # On some boxes NO_MMAP is needed, and not so elsewhere.
 +              # Try commenting this out if you suspect MMAP is more efficient
 +              NO_MMAP = YesPlease
 +      else
 +              NO_REGEX = UnfortunatelyYes
        endif
 -      NO_THREAD_SAFE_PREAD = YesPlease
        NEEDS_LIBICONV = YesPlease
        NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
 -      NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
 -      # There are conflicting reports about this.
 -      # On some boxes NO_MMAP is needed, and not so elsewhere.
 -      # Try commenting this out if you suspect MMAP is more efficient
 -      NO_MMAP = YesPlease
        X = .exe
-       COMPAT_OBJS += compat/cygwin.o
        UNRELIABLE_FSTAT = UnfortunatelyYes
        SPARSE_FLAGS = -isystem /usr/include/w32api -Wno-one-bit-signed-bitfield
  endif
index 32d1b45c7e9bbfc721581f97ae4ca88bc2e0b6e9,eacba2ff69abb636e883c7c8d0bbaf3efd34b424..5da920ecd9ec1b64760db863d266fdc9c47502de
@@@ -648,7 -648,6 +648,7 @@@ __git_list_porcelain_commands (
                cat-file)         : plumbing;;
                check-attr)       : plumbing;;
                check-ignore)     : plumbing;;
 +              check-mailmap)    : plumbing;;
                check-ref-format) : plumbing;;
                checkout-index)   : plumbing;;
                commit-tree)      : plumbing;;
@@@ -1958,7 -1957,6 +1958,6 @@@ _git_config (
                core.fileMode
                core.fsyncobjectfiles
                core.gitProxy
-               core.ignoreCygwinFSTricks
                core.ignoreStat
                core.ignorecase
                core.logAllRefUpdates
@@@ -2581,7 -2579,7 +2580,7 @@@ if [[ -n ${ZSH_VERSION-} ]]; the
                                --*=*|*.) ;;
                                *) c="$c " ;;
                                esac
 -                              array+=("$c")
 +                              array[$#array+1]="$c"
                        done
                        compset -P '*[=:]'
                        compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
diff --combined git-compat-util.h
index cc4ba4d18f15f72a7e7d2d12e2fa7b51f6a2a3e1,9f1eacaaae8d85f6391457143b74797a4d62a1f4..115cb1da42cc314f75a5b032d90798e5a2ce68c5
  #include <poll.h>
  #endif
  
- extern int get_st_mode_bits(const char *path, int *mode);
  #if defined(__MINGW32__)
  /* pull in Windows compatibility stuff */
  #include "compat/mingw.h"
@@@ -171,7 -169,6 +169,6 @@@ typedef unsigned long uintptr_t
  #undef _XOPEN_SOURCE
  #include <grp.h>
  #define _XOPEN_SOURCE 600
- #include "compat/cygwin.h"
  #else
  #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
  #include <grp.h>
@@@ -303,13 -300,6 +300,13 @@@ extern char *gitbasename(char *)
  #endif
  #endif
  
 +/* The sentinel attribute is valid from gcc version 4.0 */
 +#if defined(__GNUC__) && (__GNUC__ >= 4)
 +#define LAST_ARG_MUST_BE_NULL __attribute__((sentinel))
 +#else
 +#define LAST_ARG_MUST_BE_NULL
 +#endif
 +
  #include "compat/bswap.h"
  
  #ifdef USE_WILDMATCH
diff --combined path.c
index 7f3324aeea8050c082f9bb52d769301cdede4805,4e7fae411f48d4f2d95b83f0517954d76450c0d7..3d244d3e03ae5c3d5afe452f903ba204849ad03b
--- 1/path.c
--- 2/path.c
+++ b/path.c
@@@ -5,13 -5,7 +5,7 @@@
  #include "strbuf.h"
  #include "string-list.h"
  
- #ifndef get_st_mode_bits
- /*
-  * The replacement lstat(2) we use on Cygwin is incomplete and
-  * may return wrong permission bits. Most of the time we do not care,
-  * but the callsites of this wrapper do care.
-  */
- int get_st_mode_bits(const char *path, int *mode)
+ static int get_st_mode_bits(const char *path, int *mode)
  {
        struct stat st;
        if (lstat(path, &st) < 0)
@@@ -19,7 -13,6 +13,6 @@@
        *mode = st.st_mode;
        return 0;
  }
- #endif
  
  static char bad_path[] = "/bad-path/";
  
@@@ -441,100 -434,42 +434,100 @@@ int adjust_shared_perm(const char *path
        return 0;
  }
  
 -const char *relative_path(const char *abs, const char *base)
 +/*
 + * Give path as relative to prefix.
 + *
 + * The strbuf may or may not be used, so do not assume it contains the
 + * returned path.
 + */
 +const char *relative_path(const char *in, const char *prefix,
 +                        struct strbuf *sb)
  {
 -      static char buf[PATH_MAX + 1];
 +      int in_len = in ? strlen(in) : 0;
 +      int prefix_len = prefix ? strlen(prefix) : 0;
 +      int in_off = 0;
 +      int prefix_off = 0;
        int i = 0, j = 0;
  
 -      if (!base || !base[0])
 -              return abs;
 -      while (base[i]) {
 -              if (is_dir_sep(base[i])) {
 -                      if (!is_dir_sep(abs[j]))
 -                              return abs;
 -                      while (is_dir_sep(base[i]))
 +      if (!in_len)
 +              return "./";
 +      else if (!prefix_len)
 +              return in;
 +
 +      while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
 +              if (is_dir_sep(prefix[i])) {
 +                      while (is_dir_sep(prefix[i]))
                                i++;
 -                      while (is_dir_sep(abs[j]))
 +                      while (is_dir_sep(in[j]))
 +                              j++;
 +                      prefix_off = i;
 +                      in_off = j;
 +              } else {
 +                      i++;
 +                      j++;
 +              }
 +      }
 +
 +      if (
 +          /* "prefix" seems like prefix of "in" */
 +          i >= prefix_len &&
 +          /*
 +           * but "/foo" is not a prefix of "/foobar"
 +           * (i.e. prefix not end with '/')
 +           */
 +          prefix_off < prefix_len) {
 +              if (j >= in_len) {
 +                      /* in="/a/b", prefix="/a/b" */
 +                      in_off = in_len;
 +              } else if (is_dir_sep(in[j])) {
 +                      /* in="/a/b/c", prefix="/a/b" */
 +                      while (is_dir_sep(in[j]))
                                j++;
 +                      in_off = j;
 +              } else {
 +                      /* in="/a/bbb/c", prefix="/a/b" */
 +                      i = prefix_off;
 +              }
 +      } else if (
 +                 /* "in" is short than "prefix" */
 +                 j >= in_len &&
 +                 /* "in" not end with '/' */
 +                 in_off < in_len) {
 +              if (is_dir_sep(prefix[i])) {
 +                      /* in="/a/b", prefix="/a/b/c/" */
 +                      while (is_dir_sep(prefix[i]))
 +                              i++;
 +                      in_off = in_len;
 +              }
 +      }
 +      in += in_off;
 +      in_len -= in_off;
 +
 +      if (i >= prefix_len) {
 +              if (!in_len)
 +                      return "./";
 +              else
 +                      return in;
 +      }
 +
 +      strbuf_reset(sb);
 +      strbuf_grow(sb, in_len);
 +
 +      while (i < prefix_len) {
 +              if (is_dir_sep(prefix[i])) {
 +                      strbuf_addstr(sb, "../");
 +                      while (is_dir_sep(prefix[i]))
 +                              i++;
                        continue;
 -              } else if (abs[j] != base[i]) {
 -                      return abs;
                }
                i++;
 -              j++;
        }
 -      if (
 -          /* "/foo" is a prefix of "/foo" */
 -          abs[j] &&
 -          /* "/foo" is not a prefix of "/foobar" */
 -          !is_dir_sep(base[i-1]) && !is_dir_sep(abs[j])
 -         )
 -              return abs;
 -      while (is_dir_sep(abs[j]))
 -              j++;
 -      if (!abs[j])
 -              strcpy(buf, ".");
 -      else
 -              strcpy(buf, abs + j);
 -      return buf;
 +      if (!is_dir_sep(prefix[prefix_len - 1]))
 +              strbuf_addstr(sb, "../");
 +
 +      strbuf_addstr(sb, in);
 +
 +      return sb->buf;
  }
  
  /*