Re: Git changes permissions on directories when deleting files.
From: Chad Joan <hidden>
Date: 2016-06-15 22:50:45
Possibly related (same subject, not in this thread)
- 2016-06-15 · Git changes permissions on directories when deleting files. · Chad Joan <hidden>
- 2016-06-15 · Re: Git changes permissions on directories when deleting files. · Chad Joan <hidden>
- 2016-06-15 · Re: Git changes permissions on directories when deleting files. · Computer Druid <hidden>
- 2016-06-15 · Re: Git changes permissions on directories when deleting files. · Chad Joan <hidden>
- 2016-06-15 · Re: Git changes permissions on directories when deleting files. · Chad Joan <hidden>
On Thu, Mar 3, 2011 at 10:16 AM, Jeff King [off-list ref] wrote:
...quoted
diff -crB git-1.7.3.4/dir.c git-1.7.3.4-new/dir.cContext 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);
+
#endifdiff -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)