summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 785a985)
raw | patch | inline | side by side (parent: 785a985)
author | Johannes Schindelin <Johannes.Schindelin@gmx.de> | |
Sat, 25 Apr 2009 09:57:14 +0000 (11:57 +0200) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sat, 25 Apr 2009 16:49:21 +0000 (09:49 -0700) |
It seems that accessing NTFS partitions with ufsd (at least on my EeePC)
has an unnerving bug: if you link() a file and unlink() it right away,
the target of the link() will have the correct size, but consist of NULs.
It seems as if the calls are simply not serialized correctly, as single-stepping
through the function move_temp_to_file() works flawlessly.
As ufsd is "Commertial software" (sic!), I cannot fix it, and have to work
around it in Git.
At the same time, it seems that this fixes msysGit issues 222 and 229 to
assume that Windows cannot handle link() && unlink().
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
has an unnerving bug: if you link() a file and unlink() it right away,
the target of the link() will have the correct size, but consist of NULs.
It seems as if the calls are simply not serialized correctly, as single-stepping
through the function move_temp_to_file() works flawlessly.
As ufsd is "Commertial software" (sic!), I cannot fix it, and have to work
around it in Git.
At the same time, it seems that this fixes msysGit issues 222 and 229 to
assume that Windows cannot handle link() && unlink().
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt | patch | blob | history | |
Makefile | patch | blob | history | |
cache.h | patch | blob | history | |
config.c | patch | blob | history | |
environment.c | patch | blob | history | |
sha1_file.c | patch | blob | history |
index 31885690f0bbc7130891a514a17b637d42347f2d..d31adb6719eeff3009a2799b89d5ae6d343d3e88 100644 (file)
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
index comparison to the filesystem data in parallel, allowing
overlapping IO's.
+core.unreliableHardlinks::
+ Some filesystem drivers cannot properly handle hardlinking a file
+ and deleting the source right away. In such a case, you need to
+ set this config variable to 'true'.
+
alias.*::
Command aliases for the linkgit:git[1] command wrapper - e.g.
after defining "alias.last = cat-file commit HEAD", the invocation
diff --git a/Makefile b/Makefile
index 6f602c7bbfa2fe21fe86f88d26d1fdb00b5b6296..5c8e83a99732626fd47fb4a9f97e08d93f90ffb1 100644 (file)
--- a/Makefile
+++ b/Makefile
# Define UNRELIABLE_FSTAT if your system's fstat does not return the same
# information on a not yet closed file that lstat would return for the same
# file after it was closed.
+#
+# Define UNRELIABLE_HARDLINKS if your operating systems has problems when
+# hardlinking a file to another name and unlinking the original file right
+# away (some NTFS drivers seem to zero the contents in that scenario).
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
@$(SHELL_PATH) ./GIT-VERSION-GEN
NO_NSEC = YesPlease
USE_WIN32_MMAP = YesPlease
UNRELIABLE_FSTAT = UnfortunatelyYes
+ UNRELIABLE_HARDLINKS = UnfortunatelySometimes
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch
COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/win32mmap.o
endif
endif
+ifdef UNRELIABLE_HARDLINKS
+ COMPAT_CFLAGS += -DUNRELIABLE_HARDLINKS=1
+endif
ifdef NO_PREAD
COMPAT_CFLAGS += -DNO_PREAD
COMPAT_OBJS += compat/pread.o
index ab1294d6fbb7f699af160ac06674e54798f3db6c..ff9e145be0a869546d309fb16db651f6b30a70e9 100644 (file)
--- a/cache.h
+++ b/cache.h
extern enum rebase_setup_type autorebase;
extern enum push_default_type push_default;
+extern int unreliable_hardlinks;
+
#define GIT_REPO_VERSION 0
extern int repository_format_version;
extern int check_repository_format(void);
diff --git a/config.c b/config.c
index 8c1ae598a98ed013be61ccf64170b21924186f5f..1750cfb85e34214533af13069853b7159cead2e8 100644 (file)
--- a/config.c
+++ b/config.c
return 0;
}
+ if (!strcmp(var, "core.unreliablehardlinks")) {
+ unreliable_hardlinks = git_config_bool(var, value);
+ return 0;
+ }
+
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
diff --git a/environment.c b/environment.c
index 4696885b224ac12964fce2eb06617b7ab5633854..10578d24d77de08bde2cbda7616d14f1705d490d 100644 (file)
--- a/environment.c
+++ b/environment.c
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
+#ifndef UNRELIABLE_HARDLINKS
+#define UNRELIABLE_HARDLINKS 0
+#endif
+int unreliable_hardlinks = UNRELIABLE_HARDLINKS;
/* Parallel index stat data preload? */
int core_preload_index = 0;
diff --git a/sha1_file.c b/sha1_file.c
index 8fe135dc61908103cf2d7de700794843f83db057..11969fc161bb56af410a76f0791dc9cb3bec0e1b 100644 (file)
--- a/sha1_file.c
+++ b/sha1_file.c
{
int ret = 0;
- if (link(tmpfile, filename))
+ if (unreliable_hardlinks)
+ goto try_rename;
+ else if (link(tmpfile, filename))
ret = errno;
/*
* left to unlink.
*/
if (ret && ret != EEXIST) {
+ try_rename:
if (!rename(tmpfile, filename))
goto out;
ret = errno;