Merge branch 'js/fopen-harder' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 5 Feb 2016 22:54:11 +0000 (14:54 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 5 Feb 2016 22:54:11 +0000 (14:54 -0800)
Some codepaths used fopen(3) when opening a fixed path in $GIT_DIR
(e.g. COMMIT_EDITMSG) that is meant to be left after the command is
done. This however did not work well if the repository is set to
be shared with core.sharedRepository and the umask of the previous
user is tighter. They have been made to work better by calling
unlink(2) and retrying after fopen(3) fails with EPERM.

* js/fopen-harder:
Handle more file writes correctly in shared repos
commit: allow editing the commit message even in shared repos

builtin/commit.c
builtin/fast-export.c
builtin/fetch.c
git-compat-util.h
wrapper.c
index d054f849606b248a82f7b29103308feab36ca9e9..89bf6ad38abbbee068ca29bad2ce2a4b728fa388 100644 (file)
@@ -761,7 +761,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                hook_arg2 = "";
        }
 
-       s->fp = fopen(git_path(commit_editmsg), "w");
+       s->fp = fopen_for_writing(git_path(commit_editmsg));
        if (s->fp == NULL)
                die_errno(_("could not open '%s'"), git_path(commit_editmsg));
 
index d9ac5d8410b30e02fbb8edb06a1991655c5be8f4..2471297f7101964c61c055b10e24a7aa4b65326a 100644 (file)
@@ -880,7 +880,7 @@ static void export_marks(char *file)
        FILE *f;
        int e = 0;
 
-       f = fopen(file, "w");
+       f = fopen_for_writing(file);
        if (!f)
                die_errno("Unable to open marks file %s for writing.", file);
 
index c85f3471d4b53ce7db7662b5531ddebe5513b7b0..9e24bb485f4ba438c8e3cd84856b13f4ab7fa927 100644 (file)
@@ -837,7 +837,7 @@ static void check_not_current_branch(struct ref *ref_map)
 static int truncate_fetch_head(void)
 {
        const char *filename = git_path_fetch_head();
-       FILE *fp = fopen(filename, "w");
+       FILE *fp = fopen_for_writing(filename);
 
        if (!fp)
                return error(_("cannot open %s: %s\n"), filename, strerror(errno));
index 2da0a75a380da198bd65fe3d9b0c95ef98a0b4aa..e8f286722864e13e8d5e1ad1e7380c586e505320 100644 (file)
@@ -733,6 +733,7 @@ extern int xmkstemp_mode(char *template, int mode);
 extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
 extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
 extern char *xgetcwd(void);
+extern FILE *fopen_for_writing(const char *path);
 
 #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))
 
index c95e2906b850749cbeb109050359b671979969f2..52001789ded0372becd3f55dda4cd1226c4b6dae 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -375,6 +375,19 @@ FILE *xfdopen(int fd, const char *mode)
        return stream;
 }
 
+FILE *fopen_for_writing(const char *path)
+{
+       FILE *ret = fopen(path, "w");
+
+       if (!ret && errno == EPERM) {
+               if (!unlink(path))
+                       ret = fopen(path, "w");
+               else
+                       errno = EPERM;
+       }
+       return ret;
+}
+
 int xmkstemp(char *template)
 {
        int fd;