On Tue, Mar 01, 2011 at 03:46:46PM -0500, Chad Joan wrote:
quoted
quoted
I'll do that, but it will probably take a long long time for me to see
the patch. I'm hoping there's some cheap hack I can use to work
around it in the meantime.
I'd say grep for "rmdir" is Git's source code, and replace the calls
with a wrapper that does roughly
rmdir_wrapper(dir) {
rmdir(dir);
if (stat(dir, &buf))
chmod(dir, buf.st_mode | 0777);
}
OK, I'll try that when I get a chance.
I think this is the cheap hack that you want:
diff --git a/dir.c b/dir.c
index 168dad6..fb6d306 100644
--- a/dir.c
+++ b/dir.c
@@ -1236,6 +1236,29 @@ void setup_standard_excludes(struct dir_struct *dir)
add_excludes_from_file(dir, excludes_file);
}
+static int rmdir_on_broken_cifs(const char *path)
+{
+ struct stat sb;
+ if (stat(path, &sb) < 0) {
+ /* Oh well, hopefully if we can't stat it
+ * it is already gone or we don't have
+ * permissions to screw it up anyway. */
+ return rmdir(path);
+ }
+ if (rmdir(path) == 0) {
+ /* it worked, nothing to restore */
+ return 0;
+ }
+ /* maybe remove this conditional if you can trigger
+ * the problem with other types of errors */
+ if (errno != ENOTEMPTY)
+ return -1;
+ if (chmod(path, sb.st_mode) < 0)
+ warning("we probably just screwed up the permissions of %s",
+ path);
+ return -1;
+}
+
int remove_path(const char *name)
{
char *slash;@@ -1249,7 +1272,7 @@ int remove_path(const char *name)
slash = dirs + (slash - name);
do {
*slash = '\0';
- } while (rmdir(dirs) == 0 && (slash = strrchr(dirs, '/')));
+ } while (rmdir_on_broken_cifs(dirs) == 0 && (slash = strrchr(dirs, '/')));
free(dirs);
}
return 0;
Totally untested, of course. But hey, it compiles, so it must be good.
-Peff