threads / patch / 15863

patchcompat/cygwin.c - Use cygwin's stat if core.filemode == true

Subject: [PATCH] compat/cygwin.c - Use cygwin's stat if core.filemode == true

## tl;dr

11 messages between Oct 11, 2008 and Oct 13, 2008. Diffs are folded; open one to read it.

replies: 10people: 3as markdown or json

Mark Levedahl· Oct 11, 2008, 18:54 UTC · lore

Cygwin's POSIX emulation allows use of core.filemode true, unlike native Window's implementation of stat / lstat, and Cygwin/git users who have configured core.filemode true in various repositories will be very unpleasantly surprised to find that git is no longer honoring that option. So, this patch fores use of Cygwin's stat functions if core.filemode is set true, regardless of any other considerations.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 Documentation/config.txt |    4 +++-
 compat/cygwin.c          |   10 +++++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)
Show changes to 2 files +12 −2

Documentation/config.txt, compat/cygwin.c

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7161597..a3a9495 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -124,7 +124,9 @@ core.ignoreCygwinFSTricks::
 	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.
+	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.trustctime::
 	If false, the ctime differences between the index and the
diff --git a/compat/cygwin.c b/compat/cygwin.c
index 423ff20..54028b3 100644
--- a/compat/cygwin.c
+++ b/compat/cygwin.c
@@ -91,13 +91,21 @@ static int cygwin_stat(const char *path, struct stat *buf)
  * functions should be used. The choice is determined by core.ignorecygwinfstricks.
  * Reading this option is not always possible immediately as git_dir may be
  * not be set yet. So until it is set, use cygwin lstat/stat functions.
+ * However, if core.filemode is true, we *must* use the Cygwin posix stat as
+ * the Windows stat fuctions do not determine posix filemode.
  */
 static int native_stat = 1;
+static int core_filemode = 0;
 
 static int git_cygwin_config(const char *var, const char *value, void *cb)
 {
+	if (!strcmp(var, "core.filemode")) {
+			core_filemode = git_config_bool(var, value);
+			native_stat &= !core_filemode;
+	}
 	if (!strcmp(var, "core.ignorecygwinfstricks"))
-		native_stat = git_config_bool(var, value);
+		native_stat = git_config_bool(var, value) &&
+			!core_filemode;
 	return 0;
 }
 
-- 
1.6.0.2.535.g47d45.dirty
Mark Levedahl· Oct 11, 2008, 19:04 UTC · re: Mark Levedahl · lore

Cygwin's POSIX emulation allows use of core.filemode true, unlike native Window's implementation of stat / lstat, and Cygwin/git users who have configured core.filemode true in various repositories will be very unpleasantly surprised to find that git is no longer honoring that option. So, this patch fores use of Cygwin's stat functions if core.filemode is set true, regardless of any other considerations.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
Resend as I mangled Shawn's email address.
 Documentation/config.txt |    4 +++-
 compat/cygwin.c          |   10 +++++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)
Show changes to 2 files +12 −2

Documentation/config.txt, compat/cygwin.c

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7161597..a3a9495 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -124,7 +124,9 @@ core.ignoreCygwinFSTricks::
 	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.
+	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.trustctime::
 	If false, the ctime differences between the index and the
diff --git a/compat/cygwin.c b/compat/cygwin.c
index 423ff20..54028b3 100644
--- a/compat/cygwin.c
+++ b/compat/cygwin.c
@@ -91,13 +91,21 @@ static int cygwin_stat(const char *path, struct stat *buf)
  * functions should be used. The choice is determined by core.ignorecygwinfstricks.
  * Reading this option is not always possible immediately as git_dir may be
  * not be set yet. So until it is set, use cygwin lstat/stat functions.
+ * However, if core.filemode is true, we *must* use the Cygwin posix stat as
+ * the Windows stat fuctions do not determine posix filemode.
  */
 static int native_stat = 1;
+static int core_filemode = 0;
 
 static int git_cygwin_config(const char *var, const char *value, void *cb)
 {
+	if (!strcmp(var, "core.filemode")) {
+			core_filemode = git_config_bool(var, value);
+			native_stat &= !core_filemode;
+	}
 	if (!strcmp(var, "core.ignorecygwinfstricks"))
-		native_stat = git_config_bool(var, value);
+		native_stat = git_config_bool(var, value) &&
+			!core_filemode;
 	return 0;
 }
 
-- 
1.6.0.2.535.g47d45.dirty
Junio C Hamano· Oct 11, 2008, 21:34 UTC · re: Mark Levedahl · lore

Re: [PATCH] compat/cygwin.c - Use cygwin's stat if core.filemode == true

Mark Levedahl <mlevedahl@gmail.com> writes:
Show 5 quoted lines
> Cygwin's POSIX emulation allows use of core.filemode true, unlike native
> Window's implementation of stat / lstat, and Cygwin/git users who have
> configured core.filemode true in various repositories will be very
> unpleasantly surprised to find that git is no longer honoring that option.
> So, this patch fores use of Cygwin's stat functions if core.filemode is
s/fores/forces/;
>  static int native_stat = 1;
> +static int core_filemode = 0;

Makes me wonder why "trust_executable_bit" is unavailable here. Perhaps git_cygwin_config() does not fall back to git_default_config() for a reason?

Show 12 quoted lines
>  static int git_cygwin_config(const char *var, const char *value, void *cb)
>  {
> +	if (!strcmp(var, "core.filemode")) {
> +			core_filemode = git_config_bool(var, value);
> +			native_stat &= !core_filemode;
> +	}
>  	if (!strcmp(var, "core.ignorecygwinfstricks"))
> -		native_stat = git_config_bool(var, value);
> +		native_stat = git_config_bool(var, value) &&
> +			!core_filemode;
>  	return 0;
>  }

If you can safely determine if you would want to use cygwin_stat or not only after you have read both core.filemode and core.ignorecygwinfstricks, perhaps keeping the config reader as is (this includes not falling back to git_default_config()) and instead doing:

	static int init_stat(void)
	{
		...
		git_config(git_sygwin_config, NULL);
		if (!core_filemode && native_stat) {
			cygwin_stat_fn = cygwin_stat;
			cygwin_lstat_fn = cygwin_lstat;
		} else {
			cygwin_stat_fn = stat;
			cygwin_lstat_fn = lstat;
		}
		...
is less yucky?
Mark Levedahl· Oct 11, 2008, 22:56 UTC · re: Junio C Hamano · lore

Cygwin's POSIX emulation allows use of core.filemode true, unlike native Window's implementation of stat / lstat, and Cygwin/git users who have configured core.filemode true in various repositories will be very unpleasantly surprised to find that git is no longer honoring that option. So, this patch forces use of Cygwin's stat functions if core.filemode is set true, regardless of any other considerations.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 Documentation/config.txt |    4 +++-
 compat/cygwin.c          |   18 +++++++++++++++---
 2 files changed, 18 insertions(+), 4 deletions(-)
Show changes to 2 files +18 −4

Documentation/config.txt, compat/cygwin.c

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7161597..a3a9495 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -124,7 +124,9 @@ core.ignoreCygwinFSTricks::
 	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.
+	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.trustctime::
 	If false, the ctime differences between the index and the
diff --git a/compat/cygwin.c b/compat/cygwin.c
index 423ff20..1fed265 100644
--- a/compat/cygwin.c
+++ b/compat/cygwin.c
@@ -91,13 +91,20 @@ static int cygwin_stat(const char *path, struct stat *buf)
  * functions should be used. The choice is determined by core.ignorecygwinfstricks.
  * Reading this option is not always possible immediately as git_dir may be
  * not be set yet. So until it is set, use cygwin lstat/stat functions.
+ * However, if core.filemode is true, we *must* use the Cygwin posix stat as
+ * the Windows stat fuctions do not determine posix filemode.
  */
 static int native_stat = 1;
+static int core_filemode = 0;
 
 static int git_cygwin_config(const char *var, const char *value, void *cb)
 {
-	if (!strcmp(var, "core.ignorecygwinfstricks"))
+	if (!strcmp(var, "core.filemode"))
+		core_filemode = git_config_bool(var, value);
+
+	else if (!strcmp(var, "core.ignorecygwinfstricks"))
 		native_stat = git_config_bool(var, value);
+
 	return 0;
 }
 
@@ -105,8 +112,13 @@ static int init_stat(void)
 {
 	if (have_git_dir()) {
 		git_config(git_cygwin_config, NULL);
-		cygwin_stat_fn = native_stat ? cygwin_stat : stat;
-		cygwin_lstat_fn = native_stat ? cygwin_lstat : lstat;
+		if (!core_filemode && native_stat) {
+			cygwin_stat_fn = cygwin_stat;
+			cygwin_lstat_fn = cygwin_lstat;
+		} else {
+			cygwin_stat_fn = stat;
+			cygwin_lstat_fn = lstat;
+		}
 		return 0;
 	}
 	return 1;
-- 
1.6.0.2.536.ga36e
Dmitry Potapov· Oct 12, 2008, 13:39 UTC · re: Mark Levedahl · lore

Re: [PATCH] compat/cygwin.c - Use cygwin's stat if core.filemode == true

On Sat, Oct 11, 2008 at 06:56:46PM -0400, Mark Levedahl wrote:
Show 13 quoted lines
> diff --git a/compat/cygwin.c b/compat/cygwin.c
> index 423ff20..1fed265 100644
> --- a/compat/cygwin.c
> +++ b/compat/cygwin.c
> @@ -91,13 +91,20 @@ static int cygwin_stat(const char *path, struct stat *buf)
>   * functions should be used. The choice is determined by core.ignorecygwinfstricks.
>   * Reading this option is not always possible immediately as git_dir may be
>   * not be set yet. So until it is set, use cygwin lstat/stat functions.
> + * However, if core.filemode is true, we *must* use the Cygwin posix stat as
> + * the Windows stat fuctions do not determine posix filemode.
>   */
>  static int native_stat = 1;
> +static int core_filemode = 0;

Is it a reason to add a new variable instead of using trust_executable_bit? And if so, why its default value is different? I know that this default does not matter usually, because core.filemode is always stored in .git/config, but still I don't like this discrapency.

Otherwise, I don't have any objection to this patch.
Dmitry
Mark Levedahl· Oct 12, 2008, 18:44 UTC · re: Dmitry Potapov · lore

Cygwin's POSIX emulation allows use of core.filemode true, unlike native Window's implementation of stat / lstat, and Cygwin/git users who have configured core.filemode true in various repositories will be very unpleasantly surprised to find that git is no longer honoring that option. So, this patch forces use of Cygwin's stat functions if core.filemode is set true, regardless of any other considerations.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
Updated to use trust_executable_bit as suggested on the list.
 Documentation/config.txt |    4 +++-
 compat/cygwin.c          |   16 +++++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)
Show changes to 2 files +16 −5

Documentation/config.txt, compat/cygwin.c

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7161597..a3a9495 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -124,7 +124,9 @@ core.ignoreCygwinFSTricks::
 	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.
+	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.trustctime::
 	If false, the ctime differences between the index and the
diff --git a/compat/cygwin.c b/compat/cygwin.c
index 423ff20..221d2f5 100644
--- a/compat/cygwin.c
+++ b/compat/cygwin.c
@@ -91,12 +91,17 @@ static int cygwin_stat(const char *path, struct stat *buf)
  * functions should be used. The choice is determined by core.ignorecygwinfstricks.
  * Reading this option is not always possible immediately as git_dir may be
  * not be set yet. So until it is set, use cygwin lstat/stat functions.
+ * However, if core.filemode is true, we *must* use the Cygwin posix stat as
+ * the Windows stat fuctions do not determine posix filemode.
  */
 static int native_stat = 1;
+extern int trust_executable_bit;

 static int git_cygwin_config(const char *var, const char *value, void *cb)
 {
-	if (!strcmp(var, "core.ignorecygwinfstricks"))
+	if (!strcmp(var, "core.filemode"))
+		trust_executable_bit = git_config_bool(var, value);
+	else if (!strcmp(var, "core.ignorecygwinfstricks"))
 		native_stat = git_config_bool(var, value);
 	return 0;
 }
@@ -105,8 +110,13 @@ static int init_stat(void)
 {
 	if (have_git_dir()) {
 		git_config(git_cygwin_config, NULL);
-		cygwin_stat_fn = native_stat ? cygwin_stat : stat;
-		cygwin_lstat_fn = native_stat ? cygwin_lstat : lstat;
+		if (!trust_executable_bit && native_stat) {
+			cygwin_stat_fn = cygwin_stat;
+			cygwin_lstat_fn = cygwin_lstat;
+		} else {
+			cygwin_stat_fn = stat;
+			cygwin_lstat_fn = lstat;
+		}
 		return 0;
 	}
 	return 1;
--
1.6.0.2.535.g81f8.dirty
Junio C Hamano· Oct 12, 2008, 19:35 UTC · re: Mark Levedahl · lore

Re: [PATCH] compat/cygwin.c - Use cygwin's stat if core.filemode == true

Mark Levedahl <mlevedahl@gmail.com> writes:
Show 10 quoted lines
> Cygwin's POSIX emulation allows use of core.filemode true, unlike native
> Window's implementation of stat / lstat, and Cygwin/git users who have
> configured core.filemode true in various repositories will be very
> unpleasantly surprised to find that git is no longer honoring that option.
> So, this patch forces use of Cygwin's stat functions if core.filemode is
> set true, regardless of any other considerations.
>
> Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
> ---
> Updated to use trust_executable_bit as suggested on the list.

Before you do that, can you explain why git_cygwin_config() should duplicate the setting of that variable instead of using the existing parser for that variable by calling git_default_config()?

Mark Levedahl· Oct 12, 2008, 20:23 UTC · re: Junio C Hamano · lore

Re: [PATCH] compat/cygwin.c - Use cygwin's stat if core.filemode == true

Junio C Hamano wrote:
Show 5 quoted lines
> Before you do that, can you explain why git_cygwin_config() should
> duplicate the setting of that variable instead of using the existing
> parser for that variable by calling git_default_config()?
>
>   

I don't like traversing the same list of configuration variables / files twice, each time looking for a different variable just so that one of those traversals can use a standard function, rather than just traversing once and getting exactly what this routine needs; this seems wasteful to me. However, I am (obviously) not the maintainer of this code so I will do this however it is desired.

Mark
Junio C Hamano· Oct 12, 2008, 23:39 UTC · re: Mark Levedahl · lore

Re: [PATCH] compat/cygwin.c - Use cygwin's stat if core.filemode == true

Mark Levedahl <mlevedahl@gmail.com> writes:
Show 12 quoted lines
> Junio C Hamano wrote:
>
>> Before you do that, can you explain why git_cygwin_config() should
>> duplicate the setting of that variable instead of using the existing
>> parser for that variable by calling git_default_config()?
>
> I don't like traversing the same list of configuration variables /
> files twice, each time looking for a different variable just so that
> one of those traversals can use a standard function, rather than just
> traversing once and getting exactly what this routine needs; this
> seems wasteful to me. However, I am (obviously) not the maintainer of
> this code so I will do this however it is desired.

I am not sure what you meant by "traversing twice"; when the first call to stat or lstat is made, you call init_stat() and read the config file, feeding each and every variable definition to the callback functions. And then whenever the command implementations call git_config() to getting the configuration necessary for their own use, they read the config, again feeding each and every variable definition to the callback functions. This is "traversing twice" which is unfortunate, but that is not something you can control from this codepath.

But in any case, I was worried about something different.

If you call git_default_config() as a fallback from git_cygwin_config(), which is what all the other standard configuration callback functions do, and/or set trust_executable_bit, command implementations that do not call git_default_config() on their own would see different trust_executable_bit value when running on non-Cygwin platform and on Cygwin.

I was wondering if git_cygwin_config() was originally written not to call git_default_config() because some command implementations do not to want to call git_default_core_config() (and/or read trust_executable_bit variable from the configuration) for some reason (which would be just hiding bugs in other parts of the system, I suspect).

If that is the case, we would have to fix such broken parts of the system, but until that happens your original patch to use a separate variable and keeping trust_executable_bit untouched would be much safer than this latest patch. Hence the question.

Mark Levedahl· Oct 13, 2008, 04:31 UTC · re: Junio C Hamano · lore

Re: [PATCH] compat/cygwin.c - Use cygwin's stat if core.filemode == true

Junio C Hamano wrote:
Show 11 quoted lines
> I was wondering if git_cygwin_config() was originally written not to call
> git_default_config() because some command implementations do not to want
> to call git_default_core_config() (and/or read trust_executable_bit
> variable from the configuration) for some reason (which would be just
> hiding bugs in other parts of the system, I suspect).
>
> If that is the case, we would have to fix such broken parts of the system,
> but until that happens your original patch to use a separate variable and
> keeping trust_executable_bit untouched would be much safer than this
> latest patch.  Hence the question.
>   

I was worried about altering the startup code, which is why I tried to introduce as little change as possible. However, having rewritten the patch using git_default_config() everything seems fine (the testsuite passes, or at least as well as it usually does under Cygwin, and I assume that is sufficient as this is Cygiwn specific). So, that patch follows.

Mark
Mark Levedahl· Oct 13, 2008, 04:33 UTC · re: Junio C Hamano · lore

Cygwin's POSIX emulation allows use of core.filemode true, unlike native Window's implementation of stat / lstat, and Cygwin/git users who have configured core.filemode true in various repositories will be very unpleasantly surprised to find that git is no longer honoring that option. So, this patch forces use of Cygwin's stat functions if core.filemode is set true, regardless of any other considerations.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 Documentation/config.txt |    4 +++-
 compat/cygwin.c          |   20 +++++++++++++++-----
 2 files changed, 18 insertions(+), 6 deletions(-)
Show changes to 2 files +18 −6

Documentation/config.txt, compat/cygwin.c

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7161597..a3a9495 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -124,7 +124,9 @@ core.ignoreCygwinFSTricks::
 	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.
+	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.trustctime::
 	If false, the ctime differences between the index and the
diff --git a/compat/cygwin.c b/compat/cygwin.c
index 423ff20..780375e 100644
--- a/compat/cygwin.c
+++ b/compat/cygwin.c
@@ -91,22 +91,32 @@ static int cygwin_stat(const char *path, struct stat *buf)
  * functions should be used. The choice is determined by core.ignorecygwinfstricks.
  * Reading this option is not always possible immediately as git_dir may be
  * not be set yet. So until it is set, use cygwin lstat/stat functions.
+ * However, if the trust_executable_bit is set, we must use the Cygwin posix
+ * stat/lstat as the Windows stat fuctions do not determine posix filemode.
  */
 static int native_stat = 1;
+extern int trust_executable_bit;
 
 static int git_cygwin_config(const char *var, const char *value, void *cb)
 {
-	if (!strcmp(var, "core.ignorecygwinfstricks"))
-		native_stat = git_config_bool(var, value);
-	return 0;
+	if (!strcmp(var, "core.ignorecygwinfstricks")) {
+			native_stat = git_config_bool(var, value);
+			return 0;
+	}
+	return git_default_config(var, value, cb);
 }
 
 static int init_stat(void)
 {
 	if (have_git_dir()) {
 		git_config(git_cygwin_config, NULL);
-		cygwin_stat_fn = native_stat ? cygwin_stat : stat;
-		cygwin_lstat_fn = native_stat ? cygwin_lstat : lstat;
+		if (!trust_executable_bit && native_stat) {
+			cygwin_stat_fn = cygwin_stat;
+			cygwin_lstat_fn = cygwin_lstat;
+		} else {
+			cygwin_stat_fn = stat;
+			cygwin_lstat_fn = lstat;
+		}
 		return 0;
 	}
 	return 1;
-- 
1.6.0.2.535.ga11fa.dirty

← back to recent threads