This series of five patches makes us a lot more careful about readlink(), and in particular it avoids the code that depends on doing an lstat(), and then using st_size as the length of the link. That's what POSIX says _should_ happen, but Ramon Tayag reported git failing on NTFS under Linux because st_size doesn't match readlink() return value. It doesn't seem to be unknown elsewhere either, since coreutils (through gnulib's areadlink_with_size) also has a big compatibility layer around readlink(). This series has been 'tested' by running it with the appended totally hacky patch that fakes out the lstat() st_size values for symlinks, so it has actually had some testing. The complete series does: Linus Torvalds (5): Add generic 'strbuf_readlink()' helper function Make 'ce_compare_link()' use the new 'strbuf_readlink()' Make 'index_path()' use 'strbuf_readlink()' Make 'diff_populate_filespec()' use the new 'strbuf_readlink()' Make 'prepare_temp_file()' ignore st_size for symlinks builtin-apply.c | 6 ++---- diff.c | 25 +++++++++++-------------- read-cache.c | 22 ++++++++-------------- sha1_file.c | 14 +++++--------- strbuf.c | 28 ++++++++++++++++++++++++++++ strbuf.h | 1 + 6 files changed, 55 insertions(+), 41 deletions(-) and the hacky test-patch (which is obviously _not_ meant to be applied) is as follows... Linus --- diff --git a/cache.h b/cache.h index 231c06d..2d85fca 100644 --- a/cache.h +++ b/cache.h @@ -943,4 +943,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix); char *alias_lookup(const char *alias); int split_cmdline(char *cmdline, const char ***argv); +extern int gitlstat(const char *, struct stat *); +#define lstat gitlstat + #endif /* CACHE_H */ diff --git a/read-cache.c b/read-cache.c index b1475ff..defbb20 100644 --- a/read-cache.c +++ b/read-cache.c @@ -15,6 +15,16 @@ #include "revision.h" #include "blob.h" +#undef lstat +int gitlstat(const char *path, struct stat *buf) +{ + int retval = lstat(path, buf); + if (!retval && S_ISLNK(buf->st_mode)) + buf->st_size = 1; + return retval; +} +#define lstat gitlstat + /* Index extensions. * * The first letter should be 'A'..'Z' for extensions that are not -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html