On Wed, 29 Jul 2009, Linus Torvalds wrote: > > The 'merge' issue is different, though: it's not due to a blind 'lstat()', > but due to a blind 'unlink()' done by 'remove_path()'. I think > 'remove_path()' should be taught to look for symlinks, and remove just the > symlink - but that's a bit more work, especially since the symlink cache > doesn't seem to expose any way to get the "what is the first symlink path" > information. > > Kjetil, can you look at that? Hmm... This looks like it should do it. It doesn't make the test _pass_ (we don't seem to be creating a/b-2/c/d properly - I haven't checked why yet, but I suspect it is becasue we think it already exists due to the symlinked version lstat'ing fine), but it seems to do the right thing. Linus --- dir.c | 20 -------------------- symlinks.c | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/dir.c b/dir.c index e05b850..2204826 100644 --- a/dir.c +++ b/dir.c @@ -911,23 +911,3 @@ void setup_standard_excludes(struct dir_struct *dir) if (excludes_file && !access(excludes_file, R_OK)) add_excludes_from_file(dir, excludes_file); } - -int remove_path(const char *name) -{ - char *slash; - - if (unlink(name) && errno != ENOENT) - return -1; - - slash = strrchr(name, '/'); - if (slash) { - char *dirs = xstrdup(name); - slash = dirs + (slash - name); - do { - *slash = '\0'; - } while (rmdir(dirs) && (slash = strrchr(dirs, '/'))); - free(dirs); - } - return 0; -} - diff --git a/symlinks.c b/symlinks.c index 4bdded3..349c8d5 100644 --- a/symlinks.c +++ b/symlinks.c @@ -306,3 +306,29 @@ void remove_scheduled_dirs(void) { do_remove_scheduled_dirs(0); } + +int remove_path(const char *name) +{ + char *slash; + + /* + * If we have a leading symlink, we remove + * just the symlink! + */ + if (has_symlink_leading_path(name, strlen(name))) + name = default_cache.path; + + if (unlink(name) && errno != ENOENT) + return -1; + + slash = strrchr(name, '/'); + if (slash) { + char *dirs = xstrdup(name); + slash = dirs + (slash - name); + do { + *slash = '\0'; + } while (rmdir(dirs) && (slash = strrchr(dirs, '/'))); + free(dirs); + } + return 0; +} -- 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