Re: Git changes permissions on directories when deleting files.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 3, 2011 at 10:16 AM, Jeff King <peff@xxxxxxxx> wrote:
>
> ...
>
> > diff -crB git-1.7.3.4/dir.c git-1.7.3.4-new/dir.c
>
> Context diff? Eww. There is this awesome tool called "git" that can help
> you with managing versions of software. :)
>
> -Peff

Yes... though I'm just letting Gentoo compile it for me and I'm not
doing anything serious enough to justify downloading/installing GIT by
hand and next to the one that's already there.  So I just worked from
the tarball that Gentoo uses and added stuff.  Any other day and I'd
be all over that git usage ;)


 I did run into more permissions being messed up, so I grepped for
rmdir and replaced /all/ instances of it in git's C code.  I haven't
had anymore trouble so far.  Here's the newer patch:

diff -crB git-1.7.3.4/dir.c git-1.7.3.4-new/dir.c
*** git-1.7.3.4/dir.c	Wed Mar  2 13:00:54 2011
--- git-1.7.3.4-new/dir.c	Thu Mar 10 11:09:32 2011
***************
*** 994,999 ****
--- 994,1022 ----
  	return ret;
  }

+ 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_dir_recursively(struct strbuf *path, int flag)
  {
  	DIR *dir;
***************
*** 1037,1043 ****

  	strbuf_setlen(path, original_len);
  	if (!ret)
! 		ret = rmdir(path->buf);
  	return ret;
  }

--- 1060,1066 ----

  	strbuf_setlen(path, original_len);
  	if (!ret)
! 		ret = rmdir_on_broken_cifs(path->buf);
  	return ret;
  }

***************
*** 1066,1072 ****
  		slash = dirs + (slash - name);
  		do {
  			*slash = '\0';
! 		} while (rmdir(dirs) == 0 && (slash = strrchr(dirs, '/')));
  		free(dirs);
  	}
  	return 0;
--- 1090,1096 ----
  		slash = dirs + (slash - name);
  		do {
  			*slash = '\0';
! 		} while (rmdir_on_broken_cifs(dirs) == 0 && (slash = strrchr(dirs, '/')));
  		free(dirs);
  	}
  	return 0;
Only in git-1.7.3.4: dir.c~
diff -crB git-1.7.3.4/dir.h git-1.7.3.4-new/dir.h
*** git-1.7.3.4/dir.h	Wed Dec 15 21:52:11 2010
--- git-1.7.3.4-new/dir.h	Thu Mar 10 11:09:13 2011
***************
*** 101,104 ****
--- 101,106 ----
  /* tries to remove the path with empty directories along it, ignores ENOENT */
  extern int remove_path(const char *path);

+ extern int rmdir_on_broken_cifs(const char *path);
+
  #endif
diff -crB git-1.7.3.4/entry.c git-1.7.3.4-new/entry.c
*** git-1.7.3.4/entry.c	Wed Dec 15 21:52:11 2010
--- git-1.7.3.4-new/entry.c	Thu Mar 10 11:12:25 2011
***************
*** 68,74 ****
  			die_errno("cannot unlink '%s'", pathbuf);
  	}
  	closedir(dir);
! 	if (rmdir(path))
  		die_errno("cannot rmdir '%s'", path);
  }

--- 68,74 ----
  			die_errno("cannot unlink '%s'", pathbuf);
  	}
  	closedir(dir);
! 	if (rmdir_on_broken_cifs(path))
  		die_errno("cannot rmdir '%s'", path);
  }

diff -crB git-1.7.3.4/pack-refs.c git-1.7.3.4-new/pack-refs.c
*** git-1.7.3.4/pack-refs.c	Wed Dec 15 21:52:11 2010
--- git-1.7.3.4-new/pack-refs.c	Thu Mar 10 12:34:53 2011
***************
*** 2,7 ****
--- 2,8 ----
  #include "refs.h"
  #include "tag.h"
  #include "pack-refs.h"
+ #include "dir.h"

  struct ref_to_prune {
  	struct ref_to_prune *next;
***************
*** 86,92 ****
  		if (q == p)
  			break;
  		*q = '\0';
! 		if (rmdir(git_path("%s", name)))
  			break;
  	}
  }
--- 87,93 ----
  		if (q == p)
  			break;
  		*q = '\0';
! 		if (rmdir_on_broken_cifs(git_path("%s", name)))
  			break;
  	}
  }
diff -crB git-1.7.3.4/symlinks.c git-1.7.3.4-new/symlinks.c
*** git-1.7.3.4/symlinks.c	Wed Dec 15 21:52:11 2010
--- git-1.7.3.4-new/symlinks.c	Thu Mar 10 11:24:08 2011
***************
*** 1,4 ****
--- 1,5 ----
  #include "cache.h"
+ #include "dir.h"

  /*
   * Returns the length (on a path component basis) of the longest
***************
*** 255,261 ****
  {
  	while (removal.len > new_len) {
  		removal.path[removal.len] = '\0';
! 		if (rmdir(removal.path))
  			break;
  		do {
  			removal.len--;
--- 256,262 ----
  {
  	while (removal.len > new_len) {
  		removal.path[removal.len] = '\0';
! 		if (rmdir_on_broken_cifs(removal.path))
  			break;
  		do {
  			removal.len--;
diff -crB git-1.7.3.4/wrapper.c git-1.7.3.4-new/wrapper.c
*** git-1.7.3.4/wrapper.c	Wed Dec 15 21:52:11 2010
--- git-1.7.3.4-new/wrapper.c	Thu Mar 10 11:12:36 2011
***************
*** 2,7 ****
--- 2,8 ----
   * Various trivial helper wrappers around standard functions
   */
  #include "cache.h"
+ #include "dir.h"

  static void try_to_free_builtin(size_t size)
  {
***************
*** 346,352 ****

  int rmdir_or_warn(const char *file)
  {
! 	return warn_if_unremovable("rmdir", file, rmdir(file));
  }

  int remove_or_warn(unsigned int mode, const char *file)
--- 347,353 ----

  int rmdir_or_warn(const char *file)
  {
! 	return warn_if_unremovable("rmdir", file, rmdir_on_broken_cifs(file));
  }

  int remove_or_warn(unsigned int mode, const char *file)
--
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


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]