* 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
* [QGit] [PATCH] Modify Highlight Color at File Context View.
From: Li Frank-B20596 @ 2008-09-27 3:44 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <e5bfff550809260337o1523995ele3333c0de9295393@mail.gmail.com>
>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>
---
src/filecontent.cpp | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/filecontent.cpp b/src/filecontent.cpp
index 28e0f91..23c2e95 100644
--- a/src/filecontent.cpp
+++ b/src/filecontent.cpp
@@ -576,12 +576,14 @@ void FileContent::setAnnList() {
listWidgetAnn->clear();
listWidgetAnn->addItems(sl);
- QBrush b(Qt::darkGray);
+ QBrush fore(Qt::darkRed);
+ QBrush back(Qt::lightGray);
QFont f(listWidgetAnn->font());
f.setBold(true);
FOREACH (QVector<int>, it, curIdLines) {
QListWidgetItem* item = listWidgetAnn->item(*it);
- item->setForeground(b);
+ item->setForeground(fore);
+ item->setBackground(back);
item->setFont(f);
}
/* When listWidgetAnn get focus for the first time the current
--
1.6.0.2.1172.ga5ed0
^ permalink raw reply related
* Re: status letters consistency in log and ls-files
From: Jeff King @ 2008-09-27 3:30 UTC (permalink / raw)
To: Leo Razoumov; +Cc: Git Mailing List
In-Reply-To: <ee2a733e0809262020l318b0ac3v560400d95a5ba2b7@mail.gmail.com>
On Fri, Sep 26, 2008 at 11:20:03PM -0400, Leo Razoumov wrote:
> > git diff --name-status
> >
> > will show you the modified and deleted files. But since you are using
> > "-c" to show _all_ cached files, I think only ls-files can do that
> > (since diff is, obviously, about files with differences).
>
> Moreover, git diff would not show untracked files while git ls-files
> will include them and label '?'
Yes, but that is somewhat simpler to fix, since we know that they cannot
be part of the "git diff" output. That is, you can just append the "git
ls-files -v -o" output. Actually, since cached files use the 'H' tag
which doesn't conflict with git-diff, and since your goal was to combine
the multiple output anyway, I wonder if something like this would make
you happy:
(
git ls-files --exclude-standard -v -c -o &&
git diff --name-status --cached
) |
perl -e '
my %h;
while(<>) {
chomp;
my ($status, $name) = split / /, $_, 2;
$h{$name} .= $status;
}
print "$h{$_} $_\n" foreach sort keys(%h);
'
?
Personally, I find listing every cached file makes the output hard to
read, since any modified ones will be lost in the noise. But that is
what you said you wanted...
-Peff
^ permalink raw reply
* Re: status letters consistency in log and ls-files
From: Leo Razoumov @ 2008-09-27 3:20 UTC (permalink / raw)
To: Jeff King, Git Mailing List
In-Reply-To: <20080927002949.GA25586@coredump.intra.peff.net>
On 9/26/08, Jeff King <peff@peff.net> wrote:
> On Fri, Sep 26, 2008 at 07:24:11PM -0400, Leo Razoumov wrote:
>
> > Another script takes output of
> > git ls-files -v -c -d -m -o -k
> > and for each file pulls together all the file status letters in one record.
>
>
> OK. I was thinking I could suggest just using "git diff" here instead.
> E.g.,:
>
> git diff --name-status
>
> will show you the modified and deleted files. But since you are using
> "-c" to show _all_ cached files, I think only ls-files can do that
> (since diff is, obviously, about files with differences).
>
> So I'm not sure there is a straight-forward solution short of
> translating the status codes.
>
> -Peff
Moreover, git diff would not show untracked files while git ls-files
will include them and label '?'
--Leo--
^ permalink raw reply
* Re: gitk: Turn short SHA1 names into links too
From: Paul Mackerras @ 2008-09-27 3:18 UTC (permalink / raw)
To: Wincent Colaiuta; +Cc: Linus Torvalds, Git Mailing List
In-Reply-To: <BD7D0F18-32BD-4059-9190-A2C1B101B4C1@wincent.com>
Wincent Colaiuta writes:
> It's a shame that tcl/tk regular expressions don't appear to support
> anchoring matches against word boundaries (ie. "\b").
They do. From the re_syntax (3tcl) man page:
\m matches only at the beginning of a word
\M matches only at the end of a word
\y matches only at the beginning or end of a word
\Y matches only at a point that is not the beginning or end of a
word
Paul.
^ permalink raw reply
* Re: gitk: Turn short SHA1 names into links too
From: Paul Mackerras @ 2008-09-27 3:16 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.1.10.0809251657080.3265@nehalem.linux-foundation.org>
Linus Torvalds writes:
> And the thing I wanted to work was to have the abbreviated SHA1's that
> have started to get more common in the kernel commit logs work as links in
> gitk too, just the way a full 40-character SHA1 link works.
Fair enough...
> This patch does seem to work, but it's also buggy in exactly the same ways
> the regular 40-character links are buggy, and while I find those bugs
> very irritating _too_, I can't cut-and-paste myself to a solution for
> that.
>
> The pre-existing bugs that this shares with the long links are:
>
> - since gitk started doing incremental showing of the graph, the whole
> "check if it exists" doesn't work right if the target hasn't been
> loaded yet. And when it _does_ end up being loaded one second later,
> nothing re-does the scanning.
Actually there *is* logic in gitk to remember that certain SHA1 ids
are "interesting" and do something when we come across them later. So
when we see a string of 40 hex digits in a commit message and we don't
recognize that as an ID that we know about, we remember it as an
interesting ID, with the action being to turn the string into a link.
So when the ID turns up later, the string in the commit message
becomes a link.
However, that currently only works for the full 40-character IDs, not
for abbreviations, because the way we remember that the ID is
interesting is with an associative array (i.e. a hash). What we need
to do is use only the first 6 characters and then have each array
element be a list of (ID, action) pairs, where the ID can now be a
partial ID.
I'd hack it up now except that I just got home from the US and I need
to sleep...
> - slightly related to the above: when we _do_ find a link, we create it
> to be a link to line so-and-so, but since we now don't just
> incrementally parse the commits that come in, but gitk _also_ actually
> reflows the commits to be in topological order, the link we just
> created may actually no longer point to the right line by the time the
> link is then clicked on, so clicking on a link can actually take you to
> the wrong commit!
Yep, guilty as charged. We need to defer the ID -> line number
translation until the user actually clicks on the link.
> I suspect that the correct fix is to always do the link, whether we
> actually see it or not, and not make it point to a line number, but simply
> keep it as a SHA1, and then do the equivalent of "gotocommit" when
> clicking it. But I don't know how links workin tcl/tk, so I'm not going to
> be able to do that.
We need this change in setlink (caution, completely untested):
- $ctext tag bind $lk <1> [list selectline [rowofcommit $id] 1]
+ $ctext tag bind $lk <1> [list selbyid $id]
> In the meantime, this patch introduces no new bugs, and the workarounds
> are the same for abbreviated SHA1's as they are for the full ones.
>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> ---
>
> I'm sure it could have been done better. In particular, I think the
> "short->long" translation could/should probably be a function of its own.
> But I'm so uncomfortable with wish programming that I'm not starting to
> write any new functions..
>
> Comments? Paul?
The main thing is to change how we handle the commitinterest array so
that we can use it to match on short IDs as well as full 40-char ones.
And yes, we should pull out the short->long translation into its own
function.
Paul.
^ permalink raw reply
* Re: git apply --directory broken for new files
From: Jeff King @ 2008-09-27 1:54 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Johannes Schindelin, Junio C Hamano, Shawn O. Pearce,
Git Mailing List
In-Reply-To: <48DBF794.9030809@zytor.com>
On Thu, Sep 25, 2008 at 01:41:56PM -0700, H. Peter Anvin wrote:
> Trying with git 1.6.0.1:
>
> : tazenda 124 ; git apply --directory=gpxe/ < /tmp/diff
> fatal: git-apply: bad git-diff - inconsistent new filename on line 105
Hmm. It looks like this is broken for deletion, too. I believe the
problem is just that when sanity checking "diff --git" patches, we
weren't applying the --directory root consistently.
I think this fix is sane, but I would appreciate ACKs from Dscho and
Junio, who wrote the --directory code and the patch sanity checking
code, respectively.
-- >8 --
apply --directory: handle creation and deletion patches
We carefully verify that the input to git-apply is sane,
including cross-checking that the filenames we see in "+++"
headers match what was provided on the command line of "diff
--git". When --directory is used, however, we ended up
comparing the unadorned name to one with the prepended root,
causing us to complain about a mismatch.
We simply need to prepend the root directory, if any, when
pulling the name out of the git header.
Signed-off-by: Jeff King <peff@peff.net>
---
builtin-apply.c | 7 +++++++
t/t4128-apply-root.sh | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 2ab4aba..f9070d5 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -787,6 +787,13 @@ static char *git_header_name(char *line, int llen)
break;
}
if (second[len] == '\n' && !memcmp(name, second, len)) {
+ if (root) {
+ char *ret = xmalloc(root_len + len + 1);
+ strcpy(ret, root);
+ memcpy(ret + root_len, name, len);
+ ret[root_len + len] = '\0';
+ return ret;
+ }
return xmemdupz(name, len);
}
}
diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh
index 2dd0c75..bd1bdf1 100755
--- a/t/t4128-apply-root.sh
+++ b/t/t4128-apply-root.sh
@@ -40,4 +40,39 @@ test_expect_success 'apply --directory -p (2) ' '
'
+cat > patch << EOF
+diff --git a/newfile b/newfile
+new file mode 100644
+index 0000000..d95f3ad
+--- /dev/null
++++ b/newfile
+@@ -0,0 +1 @@
++content
+EOF
+
+test_expect_success 'apply --directory (new file)' '
+ git reset --hard initial &&
+ git apply --directory=some/sub/dir/ --index patch &&
+ test content = $(git show :some/sub/dir/newfile) &&
+ test content = $(cat some/sub/dir/newfile)
+'
+
+cat > patch << EOF
+diff --git a/delfile b/delfile
+deleted file mode 100644
+index d95f3ad..0000000
+--- a/delfile
++++ /dev/null
+@@ -1 +0,0 @@
+-content
+EOF
+
+test_expect_success 'apply --directory (delete file)' '
+ git reset --hard initial &&
+ echo content >some/sub/dir/delfile &&
+ git add some/sub/dir/delfile &&
+ git apply --directory=some/sub/dir/ --index patch &&
+ ! git ls-files | grep delfile
+'
+
test_done
--
1.6.0.2.517.g8be702.dirty
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox