Git development
 help / color / mirror / Atom feed
* [PATCH 7/8] Docs: send-email: Added all config variables to man end
From: Michael Witten @ 2008-09-28  1:09 UTC (permalink / raw)
  To: gitster; +Cc: git
In-Reply-To: <1222564196-84202-6-git-send-email-mfwitten@mit.edu>

Admittedly, I didn't take much pride in my work, but
I'm not trying to solve this problem.

Signed-off-by: Michael Witten <mfwitten@mit.edu>
---
 Documentation/git-send-email.txt |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 8aa5098..ee89e03 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -207,6 +207,9 @@ sendemail.aliasfiletype::
 sendemail.bcc::
 	Email address (or alias) to always bcc.
 
+sendemail.cc::
+    Default for --cc
+
 sendemail.cccmd::
 	Command to execute to generate per patch file specific "Cc:"s.
 
@@ -214,6 +217,9 @@ sendemail.chainreplyto::
 	Boolean value specifying the default to the '--[no-]chain-reply-to'
 	parameter.
 
+sendemail.envelopesender
+    Default for --envelope-sender.
+
 sendemail.identity::
 	The default configuration identity. When specified,
 	'sendemail.<identity>.<item>' will have higher precedence than
@@ -221,6 +227,9 @@ sendemail.identity::
 	identities and to hoist sensitive authentication information
 	out of the repository and into the global configuration file.
 
+sendemail.signedoffcc::
+    Default for --[no-]signed-off-by-cc.
+
 sendemail.smtpencryption::
 	Default encryption method.  Use 'ssl' for SSL (and specify an
 	appropriate port), or 'tls' for TLS.  Takes precedence over
@@ -241,6 +250,15 @@ sendemail.smtpssl::
 sendemail.smtpuser::
 	Default SMTP-AUTH username.
 
+sendemail.suppresscc::
+    Default for --supress-cc.
+
+sendemail.suppressfrom::
+    Default for --[no-]suppress-from
+
+sendemail.thread::
+    Default for --[no-]thread
+
 sendemail.to::
 	Email address (or alias) to always send to.
 
-- 
1.6.0.2.304.g577ee

^ permalink raw reply related

* [PATCH 6/8] Docs: Arranged config options in man page
From: Michael Witten @ 2008-09-28  1:09 UTC (permalink / raw)
  To: gitster; +Cc: git
In-Reply-To: <1222564196-84202-5-git-send-email-mfwitten@mit.edu>

Signed-off-by: Michael Witten <mfwitten@mit.edu>
---
 Documentation/git-send-email.txt |   44 +++++++++++++++++++-------------------
 1 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 6b62032..8aa5098 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -196,13 +196,6 @@ This option can be set with sendemail[.<identity>].validate; default to --valida
 
 CONFIGURATION
 -------------
-sendemail.identity::
-	The default configuration identity. When specified,
-	'sendemail.<identity>.<item>' will have higher precedence than
-	'sendemail.<item>'. This is useful to declare multiple SMTP
-	identities and to hoist sensitive authentication information
-	out of the repository and into the global configuration file.
-
 sendemail.aliasesfile::
 	To avoid typing long email addresses, point this to one or more
 	email aliases files.  You must also supply 'sendemail.aliasfiletype'.
@@ -211,38 +204,45 @@ sendemail.aliasfiletype::
 	Format of the file(s) specified in sendemail.aliasesfile. Must be
 	one of 'mutt', 'mailrc', 'pine', or 'gnus'.
 
-sendemail.to::
-	Email address (or alias) to always send to.
+sendemail.bcc::
+	Email address (or alias) to always bcc.
 
 sendemail.cccmd::
 	Command to execute to generate per patch file specific "Cc:"s.
 
-sendemail.bcc::
-	Email address (or alias) to always bcc.
-
 sendemail.chainreplyto::
 	Boolean value specifying the default to the '--[no-]chain-reply-to'
 	parameter.
 
+sendemail.identity::
+	The default configuration identity. When specified,
+	'sendemail.<identity>.<item>' will have higher precedence than
+	'sendemail.<item>'. This is useful to declare multiple SMTP
+	identities and to hoist sensitive authentication information
+	out of the repository and into the global configuration file.
+
+sendemail.smtpencryption::
+	Default encryption method.  Use 'ssl' for SSL (and specify an
+	appropriate port), or 'tls' for TLS.  Takes precedence over
+	'smtpssl' if both are specified.
+
+sendemail.smtppass::
+	Default SMTP-AUTH password.
+
 sendemail.smtpserver::
 	Default SMTP server to use.
 
 sendemail.smtpserverport::
 	Default SMTP server port to use.
 
+sendemail.smtpssl::
+	Legacy boolean that sets 'smtpencryption=ssl' if enabled.
+
 sendemail.smtpuser::
 	Default SMTP-AUTH username.
 
-sendemail.smtppass::
-	Default SMTP-AUTH password.
-
-sendemail.smtpencryption::
-	Default encryption method.  Use 'ssl' for SSL (and specify an
-	appropriate port), or 'tls' for TLS.  Takes precedence over
-	'smtpssl' if both are specified.
-
-sendemail.smtpssl::
-	Legacy boolean that sets 'smtpencryption=ssl' if enabled.
+sendemail.to::
+	Email address (or alias) to always send to.
 
 sendemail.validate::
     Boolean override for --[no-]validate.
-- 
1.6.0.2.304.g577ee

^ permalink raw reply related

* [PATCH 3/8] Docs: send-email: Man page option ordering
From: Michael Witten @ 2008-09-28  1:09 UTC (permalink / raw)
  To: gitster; +Cc: git
In-Reply-To: <1222564196-84202-2-git-send-email-mfwitten@mit.edu>

Now the man page lists the options in alphabetical
order (in terms of the 'main' part of an option's
name).

Signed-off-by: Michael Witten <mfwitten@mit.edu>
---
 Documentation/git-send-email.txt |  138 ++++++++++++++++++--------------------
 1 files changed, 66 insertions(+), 72 deletions(-)

diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 9b31626..0c6dbf6 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -11,7 +11,6 @@ SYNOPSIS
 'git send-email' [options] <file|directory> [... file|directory]
 
 
-
 DESCRIPTION
 -----------
 Takes the patches given on the command line and emails them out.
@@ -45,19 +44,35 @@ The --cc option must be repeated for each user you want on the cc list.
 	email sent.  If disabled with "--no-chain-reply-to", all emails after
 	the first will be sent as replies to the first email sent.  When using
 	this, it is recommended that the first file given be an overview of the
-	entire patch series.
-	Default is the value of the 'sendemail.chainreplyto' configuration
-	value; if that is unspecified, default to --chain-reply-to.
+	entire patch series. Default is the value of the 'sendemail.chainreplyto'
+	configuration value; if that is unspecified, default to --chain-reply-to.
 
 --compose::
 	Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
 	introductory message for the patch series.
 
+--dry-run::
+	Do everything except actually send the emails.
+
+--envelope-sender::
+	Specify the envelope sender used to send the emails.
+	This is useful if your default address is not the address that is
+	subscribed to a list. If you use the sendmail binary, you must have
+	suitable privileges for the -f parameter. Default is the value of
+	the 'sendemail.envelopesender' configuration variable; if that is
+	unspecified, choosing the envelope sender is left to your MTA.
+
 --from::
 	Specify the sender of the emails.  This will default to
 	the value GIT_COMMITTER_IDENT, as returned by "git var -l".
 	The user will still be prompted to confirm this entry.
 
+--identity::
+	A configuration identity. When given, causes values in the
+	'sendemail.<identity>' subsection to take precedence over
+	values in the 'sendemail' section. The default identity is
+	the value of 'sendemail.identity'.
+
 --in-reply-to::
 	Specify the contents of the first In-Reply-To header.
 	Subsequent emails will refer to the previous email
@@ -65,21 +80,40 @@ The --cc option must be repeated for each user you want on the cc list.
 	Only necessary if --compose is also set.  If --compose
 	is not set, this will be prompted for.
 
---[no-]signed-off-by-cc::
-        If this is set, add emails found in Signed-off-by: or Cc: lines to the
-        cc list.
-        Default is the value of 'sendemail.signedoffcc' configuration value;
-        if that is unspecified, default to --signed-off-by-cc.
-
 --quiet::
 	Make git-send-email less verbose.  One line per email should be
 	all that is output.
 
---identity::
-	A configuration identity. When given, causes values in the
-	'sendemail.<identity>' subsection to take precedence over
-	values in the 'sendemail' section. The default identity is
-	the value of 'sendemail.identity'.
+--[no-]signed-off-by-cc::
+        If this is set, add emails found in Signed-off-by: or Cc: lines to the
+        cc list. Default is the value of 'sendemail.signedoffcc' configuration
+        value; if that is unspecified, default to --signed-off-by-cc.
+
+--smtp-encryption::
+	Specify the encryption to use, either 'ssl' or 'tls'.  Any other
+	value reverts to plain SMTP.  Default is the value of
+	'sendemail.smtpencryption'.
+
+--smtp-pass::
+	Password for SMTP-AUTH. The argument is optional: If no
+	argument is specified, then the empty string is used as
+	the password.
++
+In place of this option, the following configuration variables
+can be specified:
++
+--
+		* sendemail.smtppass
+		* sendemail.<identity>.smtppass (see sendemail.identity).
+--
++
+However, --smtp-pass always overrides these variables.
++
+Furthermore, passwords need not be specified in configuration files
+or on the command line. If a username has been specified (with
+--smtp-user or a configuration variable), but no password has been
+specified (with --smtp-pass or a configuration variable), then the
+user is prompted for a password while the input is masked for privacy.
 
 --smtp-server::
 	If set, specifies the outgoing SMTP server to use (e.g.
@@ -96,6 +130,9 @@ The --cc option must be repeated for each user you want on the cc list.
 	servers typically listen to smtp port 25 and ssmtp port
 	465).
 
+--smtp-ssl::
+	Legacy alias for '--smtp-encryption=ssl'.
+
 --smtp-user::
 	Username for SMTP-AUTH. In place of this option, the following
 	configuration variables can be specified:
@@ -110,45 +147,11 @@ However, --smtp-user always overrides these variables.
 If a username is not specified (with --smtp-user or a
 configuration variable), then authentication is not attempted.
 
---smtp-pass::
-	Password for SMTP-AUTH. The argument is optional: If no
-	argument is specified, then the empty string is used as
-	the password.
-+
-In place of this option, the following configuration variables
-can be specified:
-+
---
-		* sendemail.smtppass
-		* sendemail.<identity>.smtppass (see sendemail.identity).
---
-+
-However, --smtp-pass always overrides these variables.
-+
-Furthermore, passwords need not be specified in configuration files
-or on the command line. If a username has been specified (with
---smtp-user or a configuration variable), but no password has been
-specified (with --smtp-pass or a configuration variable), then the
-user is prompted for a password while the input is masked for privacy.
-
---smtp-encryption::
-	Specify the encryption to use, either 'ssl' or 'tls'.  Any other
-	value reverts to plain SMTP.  Default is the value of
-	'sendemail.smtpencryption'.
-
---smtp-ssl::
-	Legacy alias for '--smtp-encryption=ssl'.
-
 --subject::
 	Specify the initial subject of the email thread.
 	Only necessary if --compose is also set.  If --compose
 	is not set, this will be prompted for.
 
---[no-]suppress-from::
-        If this is set, do not add the From: address to the cc: list.
-        Default is the value of 'sendemail.suppressfrom' configuration value;
-        if that is unspecified, default to --no-suppress-from.
-
 --suppress-cc::
 	Specify an additional category of recipients to suppress the
 	auto-cc of.  'self' will avoid including the sender, 'author' will
@@ -160,24 +163,24 @@ user is prompted for a password while the input is masked for privacy.
 	if that is unspecified, default to 'self' if --suppress-from is
 	specified, as well as 'sob' if --no-signed-off-cc is specified.
 
+--[no-]suppress-from::
+	If this is set, do not add the From: address to the cc: list.
+	Default is the value of 'sendemail.suppressfrom' configuration
+	value; if that is unspecified, default to --no-suppress-from.
+
 --[no-]thread::
 	If this is set, the In-Reply-To header will be set on each email sent.
 	If disabled with "--no-thread", no emails will have the In-Reply-To
-	header set.
-	Default is the value of the 'sendemail.thread' configuration value;
-	if that is unspecified, default to --thread.
+	header set. Default is the value of the 'sendemail.thread' configuration
+	value; if that is unspecified, default to --thread.
 
---dry-run::
-	Do everything except actually send the emails.
-
---envelope-sender::
-	Specify the envelope sender used to send the emails.
-	This is useful if your default address is not the address that is
-	subscribed to a list. If you use the sendmail binary, you must have
-	suitable privileges for the -f parameter.
-	Default is the value of the 'sendemail.envelopesender' configuration
-	variable; if that is unspecified, choosing the envelope sender is left
-	to your MTA.
+--to::
+	Specify the primary recipient of the emails generated. Generally, this
+	will be the upstream maintainer of the project involved. Default is the
+	value of the 'sendemail.to' configuration value; if that is unspecified,
+	this will be prompted for.
++
+The --to option must be repeated for each user you want on the to list.
 
 --no-validate::
 	Don't perform any sanity checks on patches.
@@ -188,15 +191,6 @@ user is prompted for a password while the input is masked for privacy.
 			is due to SMTP limits as described by http://www.ietf.org/rfc/rfc2821.txt.
 --
 
---to::
-	Specify the primary recipient of the emails generated.
-	Generally, this will be the upstream maintainer of the
-	project involved.
-	Default is the value of the 'sendemail.to' configuration value;
-	if that is unspecified, this will be prompted for.
-+
-The --to option must be repeated for each user you want on the to list.
-
 
 CONFIGURATION
 -------------
-- 
1.6.0.2.304.g577ee

^ permalink raw reply related

* [PATCH] Use strchrnul() instead of strchr() plus manual workaround
From: Johan Herland @ 2008-09-27 22:24 UTC (permalink / raw)
  To: Nanako Shiraishi, Shawn O. Pearce; +Cc: git
In-Reply-To: <20080928070858.6117@nanako3.lavabit.com>

Also gets rid of a C++ comment.

Signed-off-by: Johan Herland <johan@herland.net>
---

On Sunday 28 September 2008, Nanako Shiraishi wrote:
> Why does this C++ style comment talk about "simulate"?
>
> Don't other parts of git already use strchrnul()?

Oops. Sorry about that. The man page for strchrnul() says that it is
a GNU extension, so I stayed away from it. Of course, I should have
grepped the git source instead...

This should fix it.


...Johan

 builtin-for-each-ref.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index e59bd80..fa6c1ed 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -320,9 +320,7 @@ static const char *find_wholine(const char *who, int wholen, const char *buf, un
 
 static const char *copy_line(const char *buf)
 {
-	const char *eol = strchr(buf, '\n');
-	if (!eol) // simulate strchrnul()
-		eol = buf + strlen(buf);
+	const char *eol = strchrnul(buf, '\n');
 	return xmemdupz(buf, eol - buf);
 }
 
-- 
1.6.0.2.471.g47a76

^ permalink raw reply related

* Re: [PATCH] for-each-ref: Fix --format=%(subject) for log message without newlines
From: Nanako Shiraishi @ 2008-09-27 22:08 UTC (permalink / raw)
  To: Johan Herland; +Cc: git, Shawn O. Pearce

Johan Herland <johan@herland.net> writes:

>  builtin-for-each-ref.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
> index 9b44092..e59bd80 100644
> --- a/builtin-for-each-ref.c
> +++ b/builtin-for-each-ref.c
> @@ -321,8 +321,8 @@ static const char *find_wholine(const char *who, int wholen, const char *buf, un
>  static const char *copy_line(const char *buf)
>  {
>  	const char *eol = strchr(buf, '\n');
> -	if (!eol)
> -		return "";
> +	if (!eol) // simulate strchrnul()
> +		eol = buf + strlen(buf);
>  	return xmemdupz(buf, eol - buf);
>  }

Why does this C++ style comment talk about "simulate"?

Don't other parts of git already use strchrnul()?

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/

^ permalink raw reply

* Re: [PATCH 4/4] cygwin: Use native Win32 API for stat
From: Dmitry Potapov @ 2008-09-27 21:54 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: git, Junio C Hamano, Shawn O. Pearce, Alex Riesen, Marcus Griep
In-Reply-To: <200809272035.03833.johannes.sixt@telecom.at>

On Sat, Sep 27, 2008 at 08:35:03PM +0200, Johannes Sixt wrote:
> 
> > +core.cygwinNativeStat::
> 
> This name is *really* odd, for two reasons:
> 
> - If I read "native" in connection with Windows, I would understand Windows's 
> implementation as "native". Cygwin is not native - it's a bolted-on feature.
> 
> - This name talks about the implementation, not about its effect.
> 
> Perhaps a better name would be core.ignoreCygwinFSFeatures, and the 
> description would only mention that setting this to true (the default) makes 
> many operations much faster, but makes it impossible to use File System 
> Features A and B and C in the repository. "If you need one of these features, 
> set this to false."
> 
> (And after writing above paragraphs I notice, that you actually really meant 
> Windows's "native" stat; see how confusing the name is?)

It was Shawn's suggestion. I don't care much about the name as long as
it is explained in the documentation... Therefore, I accepted what Shawn
said without giving it any thought. Now, when you bring this name to my
attention, I believe core.useCygwinStat (in the opposite to the current
core.cygwinNativeStat) would be a better name. Your name is okay too,
but a bit too long for my taste and not specific enough (I suppose
Cygwin does many FS related tricks). Anyway, I don't have a strong
opinion here, so just whatever most people like is fine with me :)

> 
> > +static inline void filetime_to_timespec(const FILETIME *ft, struct
> > timespec *ts) +{
> > +	long long winTime = ((long long)ft->dwHighDateTime << 32) +
> > ft->dwLowDateTime; +	winTime -= 116444736000000000LL; /* Windows to Unix
> > Epoch conversion */ +	ts->tv_sec = (time_t)(winTime/10000000); /*
> > 100-nanosecond interval to seconds */ +	ts->tv_nsec = (long)(winTime -
> > ts->tv_sec*10000000LL) * 100; /* nanoseconds */ +}
> 
> Shorter lines in this function would be appreciated (and not just because my 
> MUA can't deal with them ;).

I am sorry, I did not notice that the line got longer than 80 columns.
I will resent the patch once the issue with the name of the option is
resolved.

Dmitry

^ permalink raw reply

* Re: [PATCH 3/4] mingw: move common functionality to win32.h
From: Dmitry Potapov @ 2008-09-27 21:51 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: git, Junio C Hamano, Shawn O. Pearce, Alex Riesen, Marcus Griep
In-Reply-To: <200809272034.04931.johannes.sixt@telecom.at>

On Sat, Sep 27, 2008 at 08:34:04PM +0200, Johannes Sixt wrote:
> On Samstag, 27. September 2008, Dmitry Potapov wrote:
> > +static inline int get_file_attr(const char *fname,
> > WIN32_FILE_ATTRIBUTE_DATA *fdata) +{
> > +	if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata))
> > +		return 0;
> > +
> > +	switch (GetLastError()) {
> > +	case ERROR_ACCESS_DENIED:
> > +	case ERROR_SHARING_VIOLATION:
> > +	case ERROR_LOCK_VIOLATION:
> > +	case ERROR_SHARING_BUFFER_EXCEEDED:
> > +		return EACCES;
> > +	case ERROR_BUFFER_OVERFLOW:
> > +		return ENAMETOOLONG;
> > +	case ERROR_NOT_ENOUGH_MEMORY:
> > +		return ENOMEM;
> > +	default:
> > +		return ENOENT;
> > +	}
> > +}
> 
> I've long wished for a function that translates Win32 error codes to errno 
> codes. It would be useful in a number of other places, too.
> 
> Here you introduce a new function get_file_attr() that is nothing but 
> GetFileAttributesExA() followed by such an error code translation.
> 
> I suggest that we leave the original call to GetFileAttributesExA() alone and 
> have a function win32_to_errno(void) that is just the switch statement above.

win32_to_errno was the first thing that implemented but then released
that translation of Win32 errors to errno cannot be in general case.
For instance, ERROR_BUFFER_OVERFLOW means ENAMETOOLONG here, but it
can be translated to ETOOSMALL in other cases. How do you propose to
deal with that?

So I have not found a better solution than to add get_file_attr(), which
calls GetFileAttributesExA() and translates Win32 error.


Dmitry

^ permalink raw reply

* Re: [PATCH 1/4] mingw: remove use of _getdrive() from lstat/fstat
From: Johannes Sixt @ 2008-09-27 19:38 UTC (permalink / raw)
  To: Dmitry Potapov
  Cc: git, Junio C Hamano, Shawn O. Pearce, Alex Riesen, Marcus Griep
In-Reply-To: <20080927083945.GZ21650@dpotapov.dyndns.org>

On Samstag, 27. September 2008, Dmitry Potapov wrote:
> The field device is not used by Git, and putting the number of the
> current device is meaningless anyway.

Acked-by: Johannes Sixt <johannes.sixt@telecom.at>

-- Hannes

^ permalink raw reply

* Re: [PATCH 1/3] Prepare for non-interactive merge-preserving rebase
From: Stephen Haberman @ 2008-09-27 19:20 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Git Mailing List, Junio C Hamano, Shawn Pearce
In-Reply-To: <48DE7386.2080808@op5.se>


> Stephen, are you using this in production?

Kind of--I have not distributed a patched version of pull. But I have
written test cases on our side and manually executing `GIT_EDITOR=:
git rebase -i -p` works very well.

Past occurrences aside, no one has needed to rebase a local merge yet.

> How's it turning out?

I think it's great, but the primary problem will be getting devs to
actually remember to use it. E.g. I don't think they will type out:

    git pull --rebase --preserve-rebase

Every time they pull. And they definitely don't do our current hack:

    git fetch
    GIT_EDITOR=: git rebase -i -p

I do have a wrapper shell script for people to use, but it hasn't seen
wide adoption yet. We have a draconian hook script that tries to
detect merges that should have been rebases and reject them, but
it's disabled for tweaking right now--when it gets turned back on,
I think more people will use the script.

In the long term, having "branch.name.preservemerges" and
"branch.autosetuppreservemerges" config options to parallel the
"branch.name.rebase" option and get us back to just "git pull"
would be great.

I've been meaning to submit patches for these two config options--I
figure I can hunt down how "branch.name.rebase" works and do the
appropriate copy/paste, but I haven't dedicated any time to it yet.

Thanks,
Stephen

^ permalink raw reply

* Re: [PATCH 4/4] cygwin: Use native Win32 API for stat
From: Johannes Sixt @ 2008-09-27 18:35 UTC (permalink / raw)
  To: Dmitry Potapov
  Cc: git, Junio C Hamano, Shawn O. Pearce, Alex Riesen, Marcus Griep
In-Reply-To: <20080927084349.GC21650@dpotapov.dyndns.org>

On Samstag, 27. September 2008, Dmitry Potapov wrote:
> lstat/stat functions in Cygwin are very slow, because they try to emulate
> some *nix things that Git does not actually need. This patch adds Win32
> specific implementation of these functions for Cygwin.
>
> This implementation handles most situation directly but in some rare cases
> it falls back on the implementation provided for Cygwin.

Even though I was concerned about code duplication earlier, with the 
factorization that you do in this series this is acceptable, in particular, 
since working out at a solution that deals with the time_t vs. timespec 
difference we would need dirty tricks that are not worth it.

(But see my comment about get_file_attr() in a separate mail.)

> +core.cygwinNativeStat::

This name is *really* odd, for two reasons:

- If I read "native" in connection with Windows, I would understand Windows's 
implementation as "native". Cygwin is not native - it's a bolted-on feature.

- This name talks about the implementation, not about its effect.

Perhaps a better name would be core.ignoreCygwinFSFeatures, and the 
description would only mention that setting this to true (the default) makes 
many operations much faster, but makes it impossible to use File System 
Features A and B and C in the repository. "If you need one of these features, 
set this to false."

(And after writing above paragraphs I notice, that you actually really meant 
Windows's "native" stat; see how confusing the name is?)

> +static inline void filetime_to_timespec(const FILETIME *ft, struct
> timespec *ts) +{
> +	long long winTime = ((long long)ft->dwHighDateTime << 32) +
> ft->dwLowDateTime; +	winTime -= 116444736000000000LL; /* Windows to Unix
> Epoch conversion */ +	ts->tv_sec = (time_t)(winTime/10000000); /*
> 100-nanosecond interval to seconds */ +	ts->tv_nsec = (long)(winTime -
> ts->tv_sec*10000000LL) * 100; /* nanoseconds */ +}

Shorter lines in this function would be appreciated (and not just because my 
MUA can't deal with them ;).

-- Hannes

^ permalink raw reply

* Re: [PATCH 3/4] mingw: move common functionality to win32.h
From: Johannes Sixt @ 2008-09-27 18:34 UTC (permalink / raw)
  To: Dmitry Potapov
  Cc: git, Junio C Hamano, Shawn O. Pearce, Alex Riesen, Marcus Griep
In-Reply-To: <20080927084301.GB21650@dpotapov.dyndns.org>

On Samstag, 27. September 2008, Dmitry Potapov wrote:
> +static inline int get_file_attr(const char *fname,
> WIN32_FILE_ATTRIBUTE_DATA *fdata) +{
> +	if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata))
> +		return 0;
> +
> +	switch (GetLastError()) {
> +	case ERROR_ACCESS_DENIED:
> +	case ERROR_SHARING_VIOLATION:
> +	case ERROR_LOCK_VIOLATION:
> +	case ERROR_SHARING_BUFFER_EXCEEDED:
> +		return EACCES;
> +	case ERROR_BUFFER_OVERFLOW:
> +		return ENAMETOOLONG;
> +	case ERROR_NOT_ENOUGH_MEMORY:
> +		return ENOMEM;
> +	default:
> +		return ENOENT;
> +	}
> +}

I've long wished for a function that translates Win32 error codes to errno 
codes. It would be useful in a number of other places, too.

Here you introduce a new function get_file_attr() that is nothing but 
GetFileAttributesExA() followed by such an error code translation.

I suggest that we leave the original call to GetFileAttributesExA() alone and 
have a function win32_to_errno(void) that is just the switch statement above.

-- Hannes

^ permalink raw reply

* Re: [PATCH 1/3] Prepare for non-interactive merge-preserving rebase
From: Andreas Ericsson @ 2008-09-27 17:55 UTC (permalink / raw)
  To: Stephen Haberman; +Cc: Git Mailing List, Junio C Hamano, Shawn Pearce
In-Reply-To: <20080923162211.d4b15373.stephen@exigencecorp.com>

Stephen Haberman wrote:
>> Stephen, I had to modify the tests a bit to get them to work with how
>> I implemented the merge-preserving rebase, and also to remove a lot of
>> the cruft that was previously in there. Hope you're ok with the
>> attribution in the commit message.
> 
> No problem, it looks great.
> 
> This is awesome. Thanks for the insanely short turnaround. The
> GIT_EDITOR=: hack is neat. I did not think it would be that simple.
> 

Stephen, are you using this in production? How's it turning out?

Shawn, I haven't seen this in any of your branches. Overlooked or
dropped? I think 1-2 are probably master material, while I'm not
so sure about 3/3. Would you prefer a re-send that turns it into
a 2-patch series, adding each test with the functionality it tests?

Let me know how you want it and I'll work something up tomorrow
morning, gmt + 1.

Thanks

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: [PATCH 4/4] cygwin: Use native Win32 API for stat
From: Dmitry Potapov @ 2008-09-27 16:33 UTC (permalink / raw)
  To: Marcus Griep
  Cc: Git Mailing List, Junio C Hamano, Shawn O. Pearce, Alex Riesen,
	Johannes Sixt
In-Reply-To: <347507080809270851y79764dbcgba1ef5a1d58bdd3e@mail.gmail.com>

On Sat, Sep 27, 2008 at 11:51:24AM -0400, Marcus Griep wrote:
> 
> Overall, looks good, though Alex's comment of using "cygwin.nativestat" may
> be a better descriptor for the config flag.

Perhaps... but I am not sure about policy for options in config file.
core.cygwinnativestat was proposed by Shawn, so I would like to hear
his opinion.

> I also think there is more refactoring that could be done, with there being
> common code paths still existing in MinGW and Cygwin.

I am not sure that there is much common code left: stat structures are
different in MinGW and Cygwin (different fields and their types), and I
do not think having one function with a lot of #ifdef __CYGWIN__ in it
is actual improvement. But you can send a patch on top of mine and let
other people decide if it is a worty goal.

Dmitry

^ permalink raw reply

* Re: having to pull twice
From: Thomas Rast @ 2008-09-27 14:16 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: Shawn O. Pearce, Michael P. Soulier, git
In-Reply-To: <20080925232525.GP23137@genesis.frugalware.org>

[-- Attachment #1: Type: text/plain, Size: 1422 bytes --]

Miklos Vajna wrote:
> On Thu, Sep 25, 2008 at 09:05:02AM +0200, Thomas Rast <trast@student.ethz.ch> wrote:
> > On the other hand, as near as I can tell this is a regression in
> > builtin-merge.  Miklos, do you know if/how this can be fixed?
> 
> I think Junio already fixed this in 446247d (merge: fix numerus bugs
> around "trivial merge" area, 2008-08-23), so 1.6.0.1 or 1.6.0.2 should
> not have this bug.
> 
> Michael, could you please upgrade frm 1.6.0 and confirm your problem
> goes away?

That won't help.  I decided this was a good opportunity to learn about
'git bisect run', and bisected it to 1c7b76b (Build in merge,
2008-07-07).  This was with bad = 47a765d (pulled from Shawn's repo
this week) and good = v1.5.6.

In case you want to check my logic, the commands are below.

- Thomas


* Setup:

  mkdir $temp_repo
  cd $temp_repo
  git init
  echo foo > foo
  git add foo
  git commit -m initial
  echo a > foo
  git commit -m a foo
  git checkout -b side HEAD^
  echo b > foo
  git commit -m b foo
  git checkout master

* Bisection script:

-- 8< --
#!/bin/sh

rm -rf $temp_repo/{bin,libexec}
make -j3 prefix=$temp_repo install

PATH=$temp_repo/bin:$PATH
cd $temp_repo
touch foo
git merge side
test -f .git/MERGE_HEAD
s=$?
git reset --hard
if test $s != 0; then
    echo did not work
    exit 1
else
    echo worked
    exit 0
fi
-- >8 --



[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [QGit] [PATCH] Modify Highlight Color at File Context View.
From: Marco Costalba @ 2008-09-27 12:47 UTC (permalink / raw)
  To: Li Frank-B20596; +Cc: git
In-Reply-To: <7FD1F85C96D70C4A89DA1DF7667EAE9607A217@zch01exm23.fsl.freescale.net>

On Sat, Sep 27, 2008 at 4:44 AM, Li Frank-B20596 <Frank.Li@freescale.com> wrote:
> From 3507b3f0b13287c5a25a31b238527b5920555c5c Mon Sep 17 00:00:00 2001
> From: Frank Li <Frank.li@freescale.com>
> Date: Sat, 27 Sep 2008 11:41:03 +0800
> Subject: [PATCH] Modify Highlight Color at File Context View.
> Author and line number can be easily found when choose special commit.
>
> Signed-off-by: Frank Li <Frank.li@freescale.com>
> ---

Patch applied.

Thanks
Marco

^ permalink raw reply

* [PATCH] Add contrib/rerere-train script
From: Nanako Shiraishi @ 2008-09-27 11:44 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git

This script takes a range of commits (e.g. maint..next) as its arguments,
recreates merge commits in the range to prime rr-cache database.

Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
---
 contrib/rerere-train.sh |   52 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)
 create mode 100755 contrib/rerere-train.sh

diff --git a/contrib/rerere-train.sh b/contrib/rerere-train.sh
new file mode 100755
index 0000000..2cfe1b9
--- /dev/null
+++ b/contrib/rerere-train.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# Copyright (c) 2008, Nanako Shiraishi
+# Prime rerere database from existing merge commits
+
+me=rerere-train
+USAGE="$me rev-list-args"
+
+SUBDIRECTORY_OK=Yes
+OPTIONS_SPEC=
+. git-sh-setup
+require_work_tree
+cd_to_toplevel
+
+# Remember original branch
+branch=$(git symbolic-ref -q HEAD) ||
+original_HEAD=$(git rev-parse --verify HEAD) || {
+	echo >&2 "Not on any branch and no commit yet?"
+	exit 1
+}
+
+mkdir -p "$GIT_DIR/rr-cache" || exit
+
+git rev-list --parents "$@" |
+while read commit parent1 other_parents
+do
+	if test -z "$other_parents"
+	then
+		# Skip non-merges
+		continue
+	fi
+	git checkout -q "$parent1^0"
+	if git merge $other_parents >/dev/null 2>&1
+	then
+		# Cleanly merges
+		continue
+	fi
+	if test -s "$GIT_DIR/MERGE_RR"
+	then
+		git show -s --pretty=format:"Learning from %h %s" "$commit"
+		git rerere
+		git checkout -q $commit -- .
+		git rerere
+	fi
+	git reset -q --hard
+done
+
+if test -z "$branch"
+then
+	git checkout "$original_HEAD"
+else
+	git checkout "${branch#refs/heads/}"
+fi
-- 
1.6.0.2

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/

^ permalink raw reply related

* Re: [PATCH v2] Add a "fast stat" mode for Cygwin
From: Dmitry Potapov @ 2008-09-27 10:39 UTC (permalink / raw)
  To: Marcus Griep
  Cc: Git Mailing List, Junio C Hamano, Shawn O. Pearce, Alex Riesen,
	Johannes Sixt
In-Reply-To: <1222498926-30635-1-git-send-email-marcus@griep.us>

Hi Marcus,

On Sat, Sep 27, 2008 at 03:02:06AM -0400, Marcus Griep wrote:
> 
>  This is a substitute patch that takes care of many of the concerns already
>  posted to this thread regarding the patch.  Sorry if it steps on your toes,
>  Dmitry.  You began scratching my itch, so I wanted to jump in and scratch
>  some more.

I am sorry I was not able to send my patches earlier. I had them ready
by the end of the day when we had the discussion, but I have not had an
opportunity to test it on Windows till today.

I have only skimmed over your patch, but there are a few changes that
I really dislike about your patch. You changed the semantic of _choice
functions. While I use it as stubs to choose what implementation to use,
you make them part of implementation, which is always called. So I do
not understand why you left the comment saying that they are only stubs
and then why you need function pointers at all then.

Also, you made some changes to MinGW (I don't know if you tested it),
but any change like removing _getdrive() from MinGW version is better
to move into separately patch (or, at least, clearly state them in the
commit comment).

Anyway, thanks for your efforts, but if you want to go ahead with some
other match of mine (especially Windows related), please, let me know,
so we can avoid stepping on each other toes.

Dmitry

^ permalink raw reply

* Re: [PATCH] Add OS X support to the pre-auto-gc example hook
From: Jonathan del Strother @ 2008-09-27  9:53 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: git
In-Reply-To: <20080925232008.GO23137@genesis.frugalware.org>

On Fri, Sep 26, 2008 at 12:20 AM, Miklos Vajna <vmiklos@frugalware.org> wrote:
> On Tue, Sep 23, 2008 at 11:43:23PM +0100, Jonathan del Strother <jon.delStrother@bestbefore.tv> wrote:
>> Shell scripting isn't my fortĂŠ, suggestions for improvements would be
>> welcome.
>>
>> +elif test -x /usr/bin/pmset && (! /usr/bin/pmset -g batt | grep -q 'Battery Power' )
>
> What about
>
> +elif test -x /usr/bin/pmset && /usr/bin/pmset -g batt | grep -q 'AC Power'
>
> ?
I was trying to handle pmset reporting anything other than Battery
Power (currently it reports either Battery, UPS, or AC), but thinking
about it, if you're on UPS, you probably don't want git gc eating into
your remaining power...
I'll post an updated version on Monday.

^ permalink raw reply

* [PATCH 4/4] cygwin: Use native Win32 API for stat
From: Dmitry Potapov @ 2008-09-27  8:43 UTC (permalink / raw)
  To: Git Mailing List
  Cc: Junio C Hamano, Shawn O. Pearce, Alex Riesen, Dmitry Potapov,
	Johannes Sixt, Marcus Griep

lstat/stat functions in Cygwin are very slow, because they try to emulate
some *nix things that Git does not actually need. This patch adds Win32
specific implementation of these functions for Cygwin.

This implementation handles most situation directly but in some rare cases
it falls back on the implementation provided for Cygwin. This is necessary
for two reasons:

- Cygwin has its own file hierarchy, so absolute paths used in Cygwin is
  not suitable to be used Win32 API. cygwin_conv_to_win32_path can not be
  used because it automatically dereference Cygwin symbol links, also it
  causes extra syscall. Fortunately Git rarely use absolute paths, so we
  always use Cygwin implementation for absolute paths.

- Support of symbol links. Cygwin stores symbol links as ordinary using
  one of two possible formats. Therefore, the fast implementation falls
  back to Cygwin functions if it detects potential use of symbol links.

The speed of this implementation should be the same as mingw_lstat for
common cases, but it is considerable slower when the specified file name
does not exist.

Despite all efforts to make the fast implementation as robust as possible,
it may not work well for some very rare situations. I am aware only one
situation: use Cygwin mount to bind unrelated paths inside repository
together.  Therefore, the core.cygwinnativestat configuration option is
provided, which controls whether native or Cygwin version of stat is used.

Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
 Documentation/config.txt |    9 +++
 Makefile                 |    4 ++
 compat/cygwin.c          |  125 ++++++++++++++++++++++++++++++++++++++++++++++
 compat/cygwin.h          |    9 +++
 git-compat-util.h        |    1 +
 5 files changed, 148 insertions(+), 0 deletions(-)
 create mode 100644 compat/cygwin.c
 create mode 100644 compat/cygwin.h

diff --git a/Documentation/config.txt b/Documentation/config.txt
index bea867d..c198bc0 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -117,6 +117,15 @@ core.fileMode::
 	the working copy are ignored; useful on broken filesystems like FAT.
 	See linkgit:git-update-index[1]. True by default.
 
+core.cygwinNativeStat::
+	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.
+
 core.trustctime::
 	If false, the ctime differences between the index and the
 	working copy are ignored; useful when the inode change time
diff --git a/Makefile b/Makefile
index 3c0664a..0708390 100644
--- a/Makefile
+++ b/Makefile
@@ -347,6 +347,7 @@ LIB_H += cache.h
 LIB_H += cache-tree.h
 LIB_H += commit.h
 LIB_H += compat/mingw.h
+LIB_H += compat/cygwin.h
 LIB_H += csum-file.h
 LIB_H += decorate.h
 LIB_H += delta.h
@@ -747,6 +748,9 @@ ifeq ($(uname_S),HP-UX)
 	NO_SYS_SELECT_H = YesPlease
 	SNPRINTF_RETURNS_BOGUS = YesPlease
 endif
+ifneq (,$(findstring CYGWIN,$(uname_S)))
+	COMPAT_OBJS += compat/cygwin.o
+endif
 ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_MMAP = YesPlease
 	NO_PREAD = YesPlease
diff --git a/compat/cygwin.c b/compat/cygwin.c
new file mode 100644
index 0000000..ad09b17
--- /dev/null
+++ b/compat/cygwin.c
@@ -0,0 +1,125 @@
+#define WIN32_LEAN_AND_MEAN
+#include "../git-compat-util.h"
+#include "win32.h"
+#include "../cache.h" /* to read configuration */
+
+static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
+{
+	long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
+	winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
+	ts->tv_sec = (time_t)(winTime/10000000); /* 100-nanosecond interval to seconds */
+	ts->tv_nsec = (long)(winTime - ts->tv_sec*10000000LL) * 100; /* nanoseconds */
+}
+
+#define size_to_blocks(s) (((s)+511)/512)
+
+/* do_stat is a common implementation for cygwin_lstat and cygwin_stat.
+ *
+ * To simplify its logic, in the case of cygwin symlinks, this implementation
+ * falls back to the cygwin version of stat/lstat, which is provided as the
+ * last argument.
+ */
+static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat)
+{
+	WIN32_FILE_ATTRIBUTE_DATA fdata;
+
+	if (file_name[0] == '/')
+		return cygstat (file_name, buf);
+
+	if (!(errno = get_file_attr(file_name, &fdata))) {
+		/*
+		 * If the system attribute is set and it is not a directory then
+		 * it could be a symbol link created in the nowinsymlinks mode.
+		 * Normally, Cygwin works in the winsymlinks mode, so this situation
+		 * is very unlikely. For the sake of simplicity of our code, let's
+		 * Cygwin to handle it.
+		 */
+		if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&
+		    !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+			return cygstat (file_name, buf);
+
+		/* fill out the stat structure */
+		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
+		buf->st_ino = 0;
+		buf->st_mode = file_attr_to_st_mode (fdata.dwFileAttributes);
+		buf->st_nlink = 1;
+		buf->st_uid = buf->st_gid = 0;
+#ifdef __CYGWIN_USE_BIG_TYPES__
+		buf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +
+			fdata.nFileSizeLow;
+#else
+		buf->st_size = (off_t)fdata.nFileSizeLow;
+#endif
+		buf->st_blocks = size_to_blocks(buf->st_size);
+		filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);
+		filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);
+		filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);
+		return 0;
+	} else if (errno == ENOENT) {
+		/*
+		 * In the winsymlinks mode (which is the default), Cygwin
+		 * emulates symbol links using Windows shortcut files. These
+		 * files are formed by adding .lnk extension. So, if we have
+		 * not found the specified file name, it could be that it is
+		 * a symbol link. Let's Cygwin to deal with that.
+		 */
+		return cygstat (file_name, buf);
+	}
+	return -1;
+}
+
+/* We provide our own lstat/stat functions, since the provided Cygwin versions
+ * of these functions are too slow. These stat functions are tailored for Git's
+ * usage, and therefore they are not meant to be complete and correct emulation
+ * of lstat/stat functionality.
+ */
+static int cygwin_lstat(const char *path, struct stat *buf)
+{
+	return do_stat(path, buf, lstat);
+}
+
+static int cygwin_stat(const char *path, struct stat *buf)
+{
+	return do_stat(path, buf, stat);
+}
+
+
+/*
+ * At start up, we are trying to determine whether Win32 API or cygwin stat
+ * functions should be used. The choice is determined by core.cygwinnativestat.
+ * 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.
+ */
+static int native_stat = 1;
+
+static int git_cygwin_config(const char *var, const char *value, void *cb)
+{
+	if (!strcmp(var, "core.cygwinnativestat"))
+		native_stat = git_config_bool(var, value);
+	return 0;
+}
+
+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;
+		return 0;
+	}
+	return 1;
+}
+
+static int cygwin_stat_stub(const char *file_name, struct stat *buf)
+{
+	return (init_stat() ? stat : *cygwin_stat_fn)(file_name, buf);
+}
+
+static int cygwin_lstat_stub(const char *file_name, struct stat *buf)
+{
+	return (init_stat() ? lstat : *cygwin_lstat_fn)(file_name, buf);
+}
+
+stat_fn_t cygwin_stat_fn = cygwin_stat_stub;
+stat_fn_t cygwin_lstat_fn = cygwin_lstat_stub;
+
diff --git a/compat/cygwin.h b/compat/cygwin.h
new file mode 100644
index 0000000..a3229f5
--- /dev/null
+++ b/compat/cygwin.h
@@ -0,0 +1,9 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+
+typedef int (*stat_fn_t)(const char*, struct stat*);
+extern stat_fn_t cygwin_stat_fn;
+extern stat_fn_t cygwin_lstat_fn;
+
+#define stat(path, buf) (*cygwin_stat_fn)(path, buf)
+#define lstat(path, buf) (*cygwin_lstat_fn)(path, buf)
diff --git a/git-compat-util.h b/git-compat-util.h
index db2836f..cd9752c 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -85,6 +85,7 @@
 #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>
-- 
1.6.0.2.237.g0297e5

^ permalink raw reply related

* [PATCH 3/4] mingw: move common functionality to win32.h
From: Dmitry Potapov @ 2008-09-27  8:43 UTC (permalink / raw)
  To: Git Mailing List
  Cc: Junio C Hamano, Shawn O. Pearce, Alex Riesen, Dmitry Potapov,
	Johannes Sixt, Marcus Griep

Some small Win32 specific functions will be shared by MinGW and
Cygwin compatibility layer. Place them into a separate header.

Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
 compat/mingw.c |   42 ++++--------------------------------------
 compat/win32.h |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 38 deletions(-)
 create mode 100644 compat/win32.h

diff --git a/compat/mingw.c b/compat/mingw.c
index a2b8cd7..ac77283 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1,4 +1,5 @@
 #include "../git-compat-util.h"
+#include "win32.h"
 #include "../strbuf.h"
 
 unsigned int _CRT_fmode = _O_BINARY;
@@ -39,46 +40,19 @@ static int do_lstat(const char *file_name, struct stat *buf)
 {
 	WIN32_FILE_ATTRIBUTE_DATA fdata;
 
-	if (GetFileAttributesExA(file_name, GetFileExInfoStandard, &fdata)) {
-		int fMode = S_IREAD;
-		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-			fMode |= S_IFDIR;
-		else
-			fMode |= S_IFREG;
-		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
-			fMode |= S_IWRITE;
-
+	if (!(errno = get_file_attr(file_name, &fdata))) {
 		buf->st_ino = 0;
 		buf->st_gid = 0;
 		buf->st_uid = 0;
 		buf->st_nlink = 1;
-		buf->st_mode = fMode;
+		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
 		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
 		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
-		errno = 0;
 		return 0;
 	}
-
-	switch (GetLastError()) {
-	case ERROR_ACCESS_DENIED:
-	case ERROR_SHARING_VIOLATION:
-	case ERROR_LOCK_VIOLATION:
-	case ERROR_SHARING_BUFFER_EXCEEDED:
-		errno = EACCES;
-		break;
-	case ERROR_BUFFER_OVERFLOW:
-		errno = ENAMETOOLONG;
-		break;
-	case ERROR_NOT_ENOUGH_MEMORY:
-		errno = ENOMEM;
-		break;
-	default:
-		errno = ENOENT;
-		break;
-	}
 	return -1;
 }
 
@@ -130,19 +104,11 @@ int mingw_fstat(int fd, struct stat *buf)
 		return fstat(fd, buf);
 
 	if (GetFileInformationByHandle(fh, &fdata)) {
-		int fMode = S_IREAD;
-		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-			fMode |= S_IFDIR;
-		else
-			fMode |= S_IFREG;
-		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
-			fMode |= S_IWRITE;
-
 		buf->st_ino = 0;
 		buf->st_gid = 0;
 		buf->st_uid = 0;
 		buf->st_nlink = 1;
-		buf->st_mode = fMode;
+		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
 		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
diff --git a/compat/win32.h b/compat/win32.h
new file mode 100644
index 0000000..c26384e
--- /dev/null
+++ b/compat/win32.h
@@ -0,0 +1,34 @@
+/* common Win32 functions for MinGW and Cygwin */
+#include <windows.h>
+
+static inline int file_attr_to_st_mode (DWORD attr)
+{
+	int fMode = S_IREAD;
+	if (attr & FILE_ATTRIBUTE_DIRECTORY)
+		fMode |= S_IFDIR;
+	else
+		fMode |= S_IFREG;
+	if (!(attr & FILE_ATTRIBUTE_READONLY))
+		fMode |= S_IWRITE;
+	return fMode;
+}
+
+static inline int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fdata)
+{
+	if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata))
+		return 0;
+
+	switch (GetLastError()) {
+	case ERROR_ACCESS_DENIED:
+	case ERROR_SHARING_VIOLATION:
+	case ERROR_LOCK_VIOLATION:
+	case ERROR_SHARING_BUFFER_EXCEEDED:
+		return EACCES;
+	case ERROR_BUFFER_OVERFLOW:
+		return ENAMETOOLONG;
+	case ERROR_NOT_ENOUGH_MEMORY:
+		return ENOMEM;
+	default:
+		return ENOENT;
+	}
+}
-- 
1.6.0.2.237.g0297e5

^ permalink raw reply related

* [PATCH 2/4] add have_git_dir() function
From: Dmitry Potapov @ 2008-09-27  8:41 UTC (permalink / raw)
  To: Git Mailing List
  Cc: Junio C Hamano, Shawn O. Pearce, Alex Riesen, Dmitry Potapov,
	Johannes Sixt, Marcus Griep

This function is used to learn whether git_dir is already set up or not.
It is necessary, because we want to read configuration in compat/cygwin.c

Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
 cache.h       |    1 +
 environment.c |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/cache.h b/cache.h
index de8c2b6..e0e46ed 100644
--- a/cache.h
+++ b/cache.h
@@ -313,6 +313,7 @@ extern int is_bare_repository(void);
 extern int is_inside_git_dir(void);
 extern char *git_work_tree_cfg;
 extern int is_inside_work_tree(void);
+extern int have_git_dir(void);
 extern const char *get_git_dir(void);
 extern char *get_object_directory(void);
 extern char *get_index_file(void);
diff --git a/environment.c b/environment.c
index 0c6d11f..0693cd9 100644
--- a/environment.c
+++ b/environment.c
@@ -80,6 +80,11 @@ int is_bare_repository(void)
 	return is_bare_repository_cfg && !get_git_work_tree();
 }
 
+int have_git_dir(void)
+{
+	return !!git_dir;
+}
+
 const char *get_git_dir(void)
 {
 	if (!git_dir)
-- 
1.6.0.2.237.g0297e5

^ permalink raw reply related

* [PATCH 1/4] mingw: remove use of _getdrive() from lstat/fstat
From: Dmitry Potapov @ 2008-09-27  8:39 UTC (permalink / raw)
  To: Git Mailing List
  Cc: Junio C Hamano, Shawn O. Pearce, Alex Riesen, Dmitry Potapov,
	Johannes Sixt, Marcus Griep

The field device is not used by Git, and putting the number of the
current device is meaningless anyway.

Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
 compat/mingw.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index ccfa2a0..a2b8cd7 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -31,7 +31,6 @@ static inline time_t filetime_to_time_t(const FILETIME *ft)
 	return (time_t)winTime;
 }
 
-extern int _getdrive( void );
 /* We keep the do_lstat code in a separate function to avoid recursion.
  * When a path ends with a slash, the stat will fail with ENOENT. In
  * this case, we strip the trailing slashes and stat again.
@@ -55,7 +54,7 @@ static int do_lstat(const char *file_name, struct stat *buf)
 		buf->st_nlink = 1;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
-		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
+		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
 		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
@@ -145,7 +144,7 @@ int mingw_fstat(int fd, struct stat *buf)
 		buf->st_nlink = 1;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
-		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
+		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
 		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
-- 
1.6.0.2.237.g0297e5

^ permalink raw reply related

* Re: git log and utf-u in filenames
From: Jakub Narebski @ 2008-09-27  8:37 UTC (permalink / raw)
  To: Alex Riesen; +Cc: Joey Hess, Git Mailing List
In-Reply-To: <81b0412b0809260649n7d7c0ccbwfde5504157687cda@mail.gmail.com>

On Fri, 26 Sep 2008, Alex Riesen wrote:
> 2008/9/26 Jakub Narebski <jnareb@gmail.com>:

>>> How about simply splitting output on end of line ("\0" NUL) characters?
>>> The "\n" NL you refer to is just as EOR as NUL.
>>
>> Doesn't work for "git diff-tree -z [...]" output. When there is rename
>> or copy detected, NUL is used as separator between fields (beetween
>> source and destination unquoted filename), not only between records:
>>
>>  git diff-tree
>>      .... <src qfilename> TAB <dst qfilename> LF
>>
>>  git diff-tree -z
>>      .... <src filename>  NUL <dst filename>  NUL
>>
> 
> You still have the marker (Rnnn) from pre-<src filename> record and
> can treat the next record correspondingly. Still a split, just a bit more
> careful handling of the resulting list/array.

Currently gitweb does something like this:

  open $fd, "-|", git_cmd(), "diff-tree", '-r', ...
  @difftree = <$fd>;
  close $fd;
  foreach my $line (@difftree) {
     ...
  }

If gitweb would use git-diff-tree with '-z' option, above code
would get more complicated, offsetting simplification of not using
unquote() (which is already written).

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH v2] Add a "fast stat" mode for Cygwin
From: Alex Riesen @ 2008-09-27  8:35 UTC (permalink / raw)
  To: Marcus Griep
  Cc: Git Mailing List, Junio C Hamano, Shawn O. Pearce, Dmitry Potapov,
	Johannes Sixt
In-Reply-To: <1222498926-30635-1-git-send-email-marcus@griep.us>

Marcus Griep, Sat, Sep 27, 2008 09:02:06 +0200:
> This patch introduces core.cygwinnativestat configuration flag. If this

"cygwin.nativestat"? If only to shame them

> variable is not set then Git will work as before. However, if it is set
> then the Cygwin version of Git will try to use a Win32 API function if
> it is possible to speed up stat/lstat.
> 
> This fast mode works only for relative paths. It is assumed that the
> whole repository is located inside one directory without using Cygwin
> mount to bind external paths inside of the current tree.
> 
> Symbolic links are supported by falling back on the cygwin version of
> these functions.

The cygwins .lnk cannot be supported. The names just don't exist for
native GetFileAttributesExA.

^ permalink raw reply

* [PATCH v2] Add a "fast stat" mode for Cygwin
From: Marcus Griep @ 2008-09-27  7:02 UTC (permalink / raw)
  To: Git Mailing List
  Cc: Junio C Hamano, Shawn O. Pearce, Alex Riesen, Dmitry Potapov,
	Johannes Sixt, Marcus Griep
In-Reply-To: <20080923140144.GN21650@dpotapov.dyndns.org>

This patch introduces core.cygwinnativestat configuration flag. If this
variable is not set then Git will work as before. However, if it is set
then the Cygwin version of Git will try to use a Win32 API function if
it is possible to speed up stat/lstat.

This fast mode works only for relative paths. It is assumed that the
whole repository is located inside one directory without using Cygwin
mount to bind external paths inside of the current tree.

Symbolic links are supported by falling back on the cygwin version of
these functions.

A very superficial testing shows 'git status' in the fast mode works more
than twice faster than in the normal mode, i.e. with about the same speed
as the native MinGW version.

Also, with this patch, Cygwin and MinGW share the same code for doing
native filesystem stats.  Also incorporates Shawn Pearce's suggestion
to use a config flag rather than an environment variable to control
which method (native or cygwin) is used.

Originally-by: Dmitry Potapov <dpotapov@gmail.com>
Signed-off-by: Marcus Griep <marcus@griep.us>
---

 This is a substitute patch that takes care of many of the concerns already
 posted to this thread regarding the patch.  Sorry if it steps on your toes,
 Dmitry.  You began scratching my itch, so I wanted to jump in and scratch
 some more.

 Overall, the new patch implements many of the ideas from the thread, including
 using a configuration flag to determine which stat (cygwin or native) to use,
 and the code is refactored so that MinGW and Cygwin can both use the same
 base stat code.

 If it looks good, I'd appreciate a regression 'Tested-by' from the MinGW
 folks to make sure I didn't break their compile or such.

 Also, if you'd prefer that I submit a patch that would be applied on top
 of Dmitry's currently pending patch, I can do that as well.

 Finally, here is the output from a little benchmark I ran on my large
 repository at work:
 115769 files in 17626 directories

 Windows native stat: false
 2.17user 8.92system 0:14.40elapsed 76%CPU (0avgtext+0avgdata 22544384maxresident)k
 0inputs+0outputs (161427major+0minor)pagefaults 0swaps

 Windows native stat: true
 1.00user 2.85system 0:06.26elapsed 61%CPU (0avgtext+0avgdata 22544384maxresident)k
 0inputs+0outputs (161427major+0minor)pagefaults 0swaps

 Looks like a nice improvement to me.

 -Marcus

 Makefile          |    7 ++++
 cache.h           |    1 +
 compat/cygwin.c   |   67 ++++++++++++++++++++++++++++++++++++
 compat/cygwin.h   |    7 ++++
 compat/mingw.c    |   64 +---------------------------------
 compat/windows.c  |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 compat/windows.h  |   12 ++++++
 environment.c     |    5 +++
 git-compat-util.h |    1 +
 9 files changed, 200 insertions(+), 62 deletions(-)
 create mode 100644 compat/cygwin.c
 create mode 100644 compat/cygwin.h
 create mode 100644 compat/windows.c
 create mode 100644 compat/windows.h

diff --git a/Makefile b/Makefile
index e0c03c3..685f038 100644
--- a/Makefile
+++ b/Makefile
@@ -346,6 +346,8 @@ LIB_H += cache.h
 LIB_H += cache-tree.h
 LIB_H += commit.h
 LIB_H += compat/mingw.h
+LIB_H += compat/cygwin.h
+LIB_H += compat/windows.h
 LIB_H += csum-file.h
 LIB_H += decorate.h
 LIB_H += delta.h
@@ -748,6 +750,10 @@ ifeq ($(uname_S),HP-UX)
 	NO_SYS_SELECT_H = YesPlease
 	SNPRINTF_RETURNS_BOGUS = YesPlease
 endif
+ifneq (,$(findstring CYGWIN,$(uname_S)))
+	COMPAT_OBJS += compat/cygwin.o
+	COMPAT_OBJS += compat/windows.o
+endif
 ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_MMAP = YesPlease
 	NO_PREAD = YesPlease
@@ -774,6 +780,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
 	COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
 	COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o
+	COMPAT_OBJS += compat/windows.o
 	EXTLIBS += -lws2_32
 	X = .exe
 	gitexecdir = ../libexec/git-core
diff --git a/cache.h b/cache.h
index f4b8ddf..b42ca0f 100644
--- a/cache.h
+++ b/cache.h
@@ -321,6 +321,7 @@ extern int set_git_dir(const char *path);
 extern const char *get_git_work_tree(void);
 extern const char *read_gitfile_gently(const char *path);
 extern void set_git_work_tree(const char *tree);
+extern int have_git_dir(void);
 
 #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
 
diff --git a/compat/cygwin.c b/compat/cygwin.c
new file mode 100644
index 0000000..db44aa8
--- /dev/null
+++ b/compat/cygwin.c
@@ -0,0 +1,67 @@
+#include "windows.h"
+#include "../cache.h"
+
+#undef stat
+#undef lstat
+
+/* We provide our own lstat/stat functions, since the provided Cygwin versions
+ * of these functions are too slow. These stat functions are tailored for Git's
+ * usage, and therefore they are not meant to be complete and correct emulation
+ * of lstat/stat functionality.
+ */
+static int cygwin_lstat(const char *path, struct stat *buf)
+{
+	return win_stat(path, buf, lstat);
+}
+
+static int cygwin_stat(const char *path, struct stat *buf)
+{
+	return win_stat(path, buf, stat);
+}
+
+static int native_stat = -1;
+static stat_fn_t cygwin_stat_fn = stat;
+static stat_fn_t cygwin_lstat_fn = lstat;
+
+static int git_cygwin_config(const char *var, const char *value, void *cb)
+{
+	if (!strcmp(var, "core.cygwinnativestat"))
+		native_stat = git_config_bool(var, value);
+	return 0;
+}
+
+static void init_stat(void)
+{
+	if (native_stat < 0 && have_git_dir()) {
+		native_stat = 0;
+		git_config(git_cygwin_config, NULL);
+		cygwin_stat_fn = native_stat ? cygwin_stat : stat;
+		cygwin_lstat_fn = native_stat ? cygwin_lstat : lstat;
+	}
+}
+
+/*
+ * This are startup stubs, which choose what implementation of lstat/stat
+ * should be used. If core.cygwinnativestat is not set then the standard
+ * functions included in the cygwin library are used. If it is set then our
+ * fast and dirty implementation is invoked, which should be 2-3 times
+ * faster than cygwin functions.
+ */
+int cygwin_stat_choice(const char *file_name, struct stat *buf)
+{
+	if (file_name[0] == '/')
+		return stat(file_name, buf);
+
+	init_stat();
+	return (cygwin_stat_fn ? cygwin_stat_fn : stat) (file_name, buf);
+}
+
+int cygwin_lstat_choice(const char *file_name, struct stat *buf)
+{
+	if (file_name[0] == '/')
+		return lstat(file_name, buf);
+
+	init_stat();
+	return (cygwin_lstat_fn ? cygwin_lstat_fn : lstat) (file_name, buf);
+}
+
diff --git a/compat/cygwin.h b/compat/cygwin.h
new file mode 100644
index 0000000..14775fd
--- /dev/null
+++ b/compat/cygwin.h
@@ -0,0 +1,7 @@
+#include "windows.h"
+
+int cygwin_stat_choice(const char*, struct stat*);
+int cygwin_lstat_choice(const char*, struct stat*);
+
+#define stat(path,buf) cygwin_stat_choice(path,buf)
+#define lstat cygwin_lstat_choice
diff --git a/compat/mingw.c b/compat/mingw.c
index ccfa2a0..174142c 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -23,66 +23,6 @@ int mingw_open (const char *filename, int oflags, ...)
 	return fd;
 }
 
-static inline time_t filetime_to_time_t(const FILETIME *ft)
-{
-	long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
-	winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
-	winTime /= 10000000;		 /* Nano to seconds resolution */
-	return (time_t)winTime;
-}
-
-extern int _getdrive( void );
-/* We keep the do_lstat code in a separate function to avoid recursion.
- * When a path ends with a slash, the stat will fail with ENOENT. In
- * this case, we strip the trailing slashes and stat again.
- */
-static int do_lstat(const char *file_name, struct stat *buf)
-{
-	WIN32_FILE_ATTRIBUTE_DATA fdata;
-
-	if (GetFileAttributesExA(file_name, GetFileExInfoStandard, &fdata)) {
-		int fMode = S_IREAD;
-		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-			fMode |= S_IFDIR;
-		else
-			fMode |= S_IFREG;
-		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
-			fMode |= S_IWRITE;
-
-		buf->st_ino = 0;
-		buf->st_gid = 0;
-		buf->st_uid = 0;
-		buf->st_nlink = 1;
-		buf->st_mode = fMode;
-		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
-		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
-		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
-		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
-		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
-		errno = 0;
-		return 0;
-	}
-
-	switch (GetLastError()) {
-	case ERROR_ACCESS_DENIED:
-	case ERROR_SHARING_VIOLATION:
-	case ERROR_LOCK_VIOLATION:
-	case ERROR_SHARING_BUFFER_EXCEEDED:
-		errno = EACCES;
-		break;
-	case ERROR_BUFFER_OVERFLOW:
-		errno = ENAMETOOLONG;
-		break;
-	case ERROR_NOT_ENOUGH_MEMORY:
-		errno = ENOMEM;
-		break;
-	default:
-		errno = ENOENT;
-		break;
-	}
-	return -1;
-}
-
 /* We provide our own lstat/fstat functions, since the provided
  * lstat/fstat functions are so slow. These stat functions are
  * tailored for Git's usage (read: fast), and are not meant to be
@@ -94,7 +34,7 @@ int mingw_lstat(const char *file_name, struct stat *buf)
 	int namelen;
 	static char alt_name[PATH_MAX];
 
-	if (!do_lstat(file_name, buf))
+	if (!win_stat(file_name, buf, win_stat_fail))
 		return 0;
 
 	/* if file_name ended in a '/', Windows returned ENOENT;
@@ -113,7 +53,7 @@ int mingw_lstat(const char *file_name, struct stat *buf)
 
 	memcpy(alt_name, file_name, namelen);
 	alt_name[namelen] = 0;
-	return do_lstat(alt_name, buf);
+	return win_stat(alt_name, buf, win_stat_fail);
 }
 
 #undef fstat
diff --git a/compat/windows.c b/compat/windows.c
new file mode 100644
index 0000000..8c7d976
--- /dev/null
+++ b/compat/windows.c
@@ -0,0 +1,98 @@
+#define WIN32_LEAN_AND_MEAN
+#include "../git-compat-util.h"
+#include <windows.h>
+
+static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
+{
+	long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
+	winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
+	ts->tv_sec = (time_t)(winTime/10000000); /* 100-nanosecond interval to seconds */
+	ts->tv_nsec = (long)(winTime - ts->tv_sec*10000000LL) * 100; /* nanoseconds */
+}
+
+#define size_to_blocks(s) (((s)+511)/512)
+
+/* do_lstat is a common implementation of a faster stat algorithm for Windows
+ *
+ * When the Windows stat fails for an unknown reason, a fallback is called to
+ * handle the error.
+ */
+int win_stat(const char *file_name, struct stat *buf, stat_fn_t fallback)
+{
+	WIN32_FILE_ATTRIBUTE_DATA fdata;
+
+	if (GetFileAttributesExA(file_name, GetFileExInfoStandard, &fdata)) {
+		int fMode = S_IREAD;
+
+#if defined(__CYGWIN__)
+		/*
+		 * If the system attribute is set and it is not a directory then
+		 * it could be a symbol link created in the nowinsymlinks mode.
+		 * Normally, Cygwin works in the winsymlinks mode, so this situation
+		 * is very unlikely. For the sake of simplicity of our code, let's
+		 * Cygwin to handle it.
+		 */
+		if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&
+		    !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+			return fallback (file_name, buf);
+#endif
+
+		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+			fMode |= S_IFDIR;
+		else
+			fMode |= S_IFREG;
+		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
+			fMode |= S_IWRITE;
+
+		buf->st_ino = 0;
+		buf->st_gid = buf->st_uid = 0;
+		buf->st_nlink = 1;
+		buf->st_mode = fMode;
+#ifdef __CYGWIN_USE_BIG_TYPES__
+		buf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +
+			fdata.nFileSizeLow;
+#else
+		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
+#endif
+		buf->st_blocks = size_to_blocks(buf->st_size);
+		/* st_dev, st_rdev are not used by Git */
+		buf->st_dev = buf->st_rdev = 0;
+		filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);
+		filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);
+		filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);
+		errno = 0;
+		return 0;
+	}
+
+	switch (GetLastError()) {
+	case ERROR_ACCESS_DENIED:
+	case ERROR_SHARING_VIOLATION:
+	case ERROR_LOCK_VIOLATION:
+	case ERROR_SHARING_BUFFER_EXCEEDED:
+		errno = EACCES;
+		break;
+	case ERROR_BUFFER_OVERFLOW:
+		errno = ENAMETOOLONG;
+		break;
+	case ERROR_NOT_ENOUGH_MEMORY:
+		errno = ENOMEM;
+		break;
+	default:
+		/* In the winsymlinks mode (which is the default), Cygwin
+		 * emulates symbol links using Windows shortcut files. These
+		 * files are formed by adding .lnk extension. So, if we have
+		 * not found the specified file name, it could be that it is
+		 * a symbol link. Let's the fallback deal with that.
+		 * In MinGW, this could also happen if the path ends with a
+		 * slash.
+		 */
+		return fallback (file_name, buf);
+	}
+	return -1;
+}
+
+int win_stat_fail(const char *file_name, struct stat *buf)
+{
+	errno = ENOENT;
+	return -1;
+}
diff --git a/compat/windows.h b/compat/windows.h
new file mode 100644
index 0000000..8412e42
--- /dev/null
+++ b/compat/windows.h
@@ -0,0 +1,12 @@
+#ifndef COMPAT_WINDOWS_H
+#define COMPAT_WINDOWS_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+typedef int (*stat_fn_t)(const char*, struct stat*);
+
+extern int win_stat(const char*, struct stat*, stat_fn_t);
+extern int win_stat_fail(const char*, struct stat *);
+
+#endif
diff --git a/environment.c b/environment.c
index 0c6d11f..cbd8074 100644
--- a/environment.c
+++ b/environment.c
@@ -151,3 +151,8 @@ int set_git_dir(const char *path)
 	setup_git_env();
 	return 0;
 }
+
+int have_git_dir(void)
+{
+	return !!git_dir;
+}
diff --git a/git-compat-util.h b/git-compat-util.h
index db2836f..cd9752c 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -85,6 +85,7 @@
 #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>
-- 
1.6.0.2.405.g3cc38

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox