Preserve file permissions on git-reflog expire
PATCH 1/1 Preserve file permissions on git-reflog expire
Preserve file permissions on git-reflog expire to avoid problems with shared repositories and git-gc.
---
This small patch fixes a bug with shared repositories and git-reflog expire.
If you have a shared repository created with git-init --shared, several users can push to it.
Once you run git-gc (which calls git-reflog expire) on the shared repository, the reflogs files are recreated with umask permissions, which defaults to 644 (with no group write). Since then, users receive the following error when trying to push:
samuel@erdinger:~/myrepo$ git push Counting objects: 5, done. Compressing objects: 100% (3/3), done. Unpacking objects: 100% (3/3), done. Writing objects: 100% (3/3), 295 bytes, done. Total 3 (delta 2), reused 0 (delta 0) error: Unable to append to logs/refs/heads/master: Permission denied To /remote/myrepo/ ! [remote rejected] master -> master (failed to write) error: failed to push some refs to '/remote/myrepo/'
This patch avoid this error preserving the permissions on reflog files.
builtin-reflog.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
builtin-reflog.c +5 -0
@@ -265,6 +265,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,struct cmd_reflog_expire_cb *cmd = cb_data;struct expire_reflog_cb cb;struct ref_lock *lock; +struct stat filestat;char *log_file, *newlog_path =NULL ;int status =0 ;
@@ -303,6 +304,10 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, status |=error ("Couldn't write %s" , lock->lk->filename);unlink (newlog_path); + }else if (stat (log_file, &filestat)){ + status |=error ("unable to read permissions of %s" , log_file); + }else if (chmod (newlog_path, filestat.st_mode)){ + status |=error ("cannot set permissions of %s" , newlog_path); }else if (rename (newlog_path, log_file)) { status |=error ("cannot rename %s to %s" , newlog_path, log_file);
Signature · 1 line
1.6.0.2.532.g84ed4c.dirty
Quoted 1 line · Samuel Lucas Vaz de Mello
Preserve file permissions on git-reflog expire to avoid problems with shared repositories and git-gc.
Looong line needs wrapped (I could do this myself if this was the only issue, but...)
Quoted 6 lines
Signed-off-by Samuel Lucas Vaz de Mello <[email protected]>---
This small patch fixes a bug with shared repositories and git-reflog expire.
Quoted 10 lines
samuel@erdinger:~/myrepo$ git push Counting objects: 5, done. Compressing objects: 100% (3/3), done. Unpacking objects: 100% (3/3), done. Writing objects: 100% (3/3), 295 bytes, done. Total 3 (delta 2), reused 0 (delta 0) error: Unable to append to logs/refs/heads/master: Permission denied To /remote/myrepo/ ! [remote rejected] master -> master (failed to write) error: failed to push some refs to '/remote/myrepo/'
Thanks for a reproduction recipe. I think an abbreviated version of this would deserve to be in the commit log message proper.
Quoted 13 lines
builtin-reflog.c +1
-0@@ -265,6 +265,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,struct cmd_reflog_expire_cb *cmd = cb_data;struct expire_reflog_cb cb;struct ref_lock *lock; +struct stat filestat;char *log_file, *newlog_path =NULL ;int status =0 ;
builtin-reflog.c static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, · line 308
Quoted 5 lines
builtin-reflog.c +2
-0@@ -303,6 +304,10 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, status |=error ("Couldn't write %s" , lock->lk->filename);unlink (newlog_path); + }else if (stat (log_file, &filestat)){ + status |=error ("unable to read permissions of %s" , log_file);
Hmmm. Is there a reason you did not use adjust_shared_perm() like all the other codepaths for creating files under .git/ directory do?
Hi,
Quoted 13 lines · Junio C Hamano
Quoted 10 lines · Samuel Lucas Vaz de Mello
samuel@erdinger:~/myrepo$ git push Counting objects: 5, done. Compressing objects: 100% (3/3), done. Unpacking objects: 100% (3/3), done. Writing objects: 100% (3/3), 295 bytes, done. Total 3 (delta 2), reused 0 (delta 0) error: Unable to append to logs/refs/heads/master: Permission denied To /remote/myrepo/ ! [remote rejected] master -> master (failed to write) error: failed to push some refs to '/remote/myrepo/'
Quoted 2 lines
Thanks for a reproduction recipe. I think an abbreviated version of this would deserve to be in the commit log message proper.
Or as a test script.
Ciao,
Dscho