'git clone' respects umask, except for top level project directory - linux

I would like to clone a git project (from github, say), and have the top level directory be writable by group.
I tried a couple different things. First, just setting the umask before cloning.
$ umask
0002
Files that I create are then writable by group
$ touch test
$ ls -l test
-rw-rw-r-- 1 user group 0 2012-05-17 09:32 test
Now I try git clone
$ git clone git#github.com:user/repo.git
Cloning into repo... [succeeds]
But the clone directory not writable by group.
$ ls -ld repo
drwxr-xr-x 11 user group 4096 2012-05-17 09:32 repo
I tried the same thing with a repo created with git init --shared=umask (which should already be the default) in a directory with 775 permissions. After pushing to github git clone gets the same results.
This isn't a huge deal, I can chmod in my checkout scripts. But if there's a right/builtin way to do this, that's preferable. Git is version 1.7.4.1 on Ubuntu 11.04.
Any ideas or links are appreciated. I saw this post, but it uses chmod, I haven't been able to find much else on this. Thanks!

Try setting the global "core.sharedRepository=group" just for the clone command:
git -c "core.sharedRepository=group" clone git#github.com:user/repo.git
ls -ld repo/.git
drwxrwsr-x 8 user user 4096 Jul 4 22:16 repo/.git/

This was due to a bug, fixed in git >= v1.7.11.3
See:
https://github.com/git/git/commit/45d4fdc2dc74c657a9c2e95bf04aed539fdcb0a4

Related

fatal: Not a git repository: '.'

I have a valid git repository named /tmp/A.
When I cd to the /tmp/A and run any git command from bash it works good, but when I run git commands from callCommand call in haskell programm I get error:
fatal: Not a git repository: '.'
If I run in callCommand pwd and ls -la before git command, like:
callCommand $ "pwd; ls -la; git status"
It shows that it is at right path /tmp/A and ls shows that repository exists and has .git directory, but git returns error.
What wrong I do?
Upd.
ls output is
drwxrwxr-x 11 xxx xxx 4096 Mar 22 11:44 .
drwxrwxr-x 3 xxx xxx 4096 Mar 22 11:44 ..
drwxrwxr-x 8 xxx xxx 4096 Mar 22 11:44 .git
-rw-rw-r-- 1 xxx xxx 270 Mar 22 11:44 .gitignore
drwxrwxr-x 7 xxx xxx 4096 Mar 22 11:44 dir2
drwxrwxr-x 8 xxx xxx 4096 Mar 22 11:44 dir1
drwxrwxr-x 9 xxx xxx 4096 Mar 22 11:44 test
Upd. Upd.
Program which fails is called from hook post-receive of cloned git repository. When run same program not from hook of this repository, it works fine.
Why self cloning repository from hook does not works?
TL;DR: you probably want unset GIT_DIR at the front of your script (well, however Haskell spells this operation).
The issue here is that while /tmp/A is a sensible Git repository, the actual repository itself is in the .git sub-directory. That is, /tmp/A/ is the work-tree and /tmp/A/.git is the repository proper.
In normal operation, we run git subcommand arguments ..., e.g., git status or git commit -m message from our work-trees. The work-tree contains a .git directory or, in some cases,1 a .git file. The top-level git command checks for .git, finds it, and says aha, the repository is ./.git. Or, it does not find .git, so it looks one level up—e.g., from /tmp/A it would climb one level to /tmp itself, and check there for .git. This repeats until some sort of stopping point.2
In all cases, this search process must either stop successfully—by finding the repository proper—or else git subcommand dies with the fatal: Not a git repository ... message. Now comes the critical, and hidden in plain sight, secret: At this point, the top-level git command sets an environment variable named GIT_DIR to contain the path name of the actual repository. It then runs the sub-command, which uses $GIT_DIR to locate the repository. In our normal use-case, where we are in /tmp/A and /tmp/A contains a .git directory, this sets $GIT_DIR to /tmp/A/.git and the sub-commands all work.
But in your case, $GIT_DIR is already set. Specifially, it's set to .. So now the top-level git command stops searching. It just verifies that $GIT_DIR is valid and names a Git repository, or dies with the fatal error message. Since /tmp/A isn't a repository—it's really /tmp/A/.git—this causes the problem.
Unsetting the environment variable turns the search back on, fixing the problem. You can also use --git-dir as an argument, or set a correct value in $GIT_DIR. Note that the same rules apply with $GIT_WORK_TREE: the --work-tree argument sets $GIT_WORK_TREE, and if you don't use that and $GIT_WORK_TREE isn't set, the front-end git command uses its climb up the file system tree to a .git directory or file code to find the root of your work-tree. So if $GIT_DIR or $GIT_WORK_TREE are set when you run git subcommand, Git obeys them unless you override them with --git-dir and/or --work-tree.
Hooks always have $GIT_DIR set. They may or may not have $GIT_WORK_TREE set as well. Most of them run in the top level of the work-tree, but, as the githooks documentation notes, pre-receive, update, post-receive, post-update, and push-to-checkout all run in $GIT_DIR.
1The .git-as-a-file trick is used by both submodules and added work-trees, in modern Git. Git 1.7 and early 1.8 left submodules with embedded .git directories, and does not support added work-trees.
2The obvious stopping point is upon reaching /, when there is nowhere left to climb. However, Git is by default careful, at least on Unix and Unix-like systems, to avoid climbing through a mount point. Mount points allow you to graft different file system layers and/or storage pools into a single tree-structured hierarchy. Typically /tmp itself might be a memory file system, for instance, and large systems might isolate "system storage" (/ and the like) from "user storage" (/home). Docker uses mount points to restructure file systems in the docker image, and so on.

"Read-only file system" error when Git tries to access index.lock

I haven't touched my local Git repository for a couple of days. Now when I cd to the root and type
git add -A :/
I get:
fatal: Unable to create '/home/james/code/winescan/Prototype/.git/index.lock': Read-only file system
Adding sudo to the command gives the same error. Then I tried ls -al:
drwxr-xr-x 8 james james 4096 Jul 28 16:24 .git
Then I tried changing the mode for the directory:
$ sudo chmod 0777 .git
[sudo] password for james:
chmod: changing permissions of '.git': Read-only file system
Nothing seems to work, what do I do?

Where can I get the description of `--shared` option of `git init` command for Windows?

I am reading the Git documentation about the git init command:
--shared[=(false|true|umask|group|all|world|everybody|0xxx)] Specify that the Git repository is to be shared amongst several users. This
allows users belonging to the same group to push into that repository.
When specified, the config variable "core.sharedRepository" is set so
that files and directories under $GIT_DIR are created with the
requested permissions. When not specified, Git will use permissions
reported by umask(2).
The option can have the following values, defaulting to group if no
value is given:
umask (or false) Use permissions reported by umask(2). The default,
when --shared is not specified.
group (or true) Make the repository group-writable, (and g+sx, since
the git group may be not the primary group of all users). This is used
to loosen the permissions of an otherwise safe umask(2) value. Note
that the umask still applies to the other permission bits (e.g. if
umask is 0022, using group will not remove read privileges from other
(non-group) users). See 0xxx for how to exactly specify the repository
permissions.
all (or world or everybody) Same as group, but make the repository
readable by all users.
0xxx 0xxx is an octal number and each file will have mode 0xxx. 0xxx
will override users' umask(2) value (and not only loosen permissions
as group and all does). 0640 will create a repository which is
group-readable, but not group-writable or accessible to others. 0660
will create a repo that is readable and writable to the current user
and group, but inaccessible to others.
This information is for Linux-based OS only. Am I right? But what about Windows? I use Git for Windows. Windows uses ACL instead of umask for working with permissions. :(
It is very sad, but umask and --shared do nothing in the Git Bash for Windows:
Developer#BUSHCOMP MINGW64 /d/temp/000
$ ls -l readme.txt
-rw-r--r-- 1 Developer Domain users 0 Sep 10 16:44 readme.txt
Developer#BUSHCOMP MINGW64 /d/temp/000
$ chmod a+rw readme.txt
Developer#BUSHCOMP MINGW64 /d/temp/000
$ ls -l readme.txt
-rw-r--r-- 1 Developer Domain users 0 Sep 10 16:44 readme.txt
Permissions of the readme.txt wasn't changed: I see -rw-r--r-- instead of -rw-rw-rw-.
Developer#BUSHCOMP MINGW64 /d/temp/000
$ chmod 666 readme.txt
Developer#BUSHCOMP MINGW64 /d/temp/000
$ ls -l readme.txt
-rw-r--r-- 1 Developer Domain users 0 Sep 10 16:44 readme.txt
Permissions of the readme.txt wasn't changed again: I see -rw-r--r-- instead of -rw-rw-rw-.
Ok, I try to use --shared=0666:
Developer#BUSHCOMP MINGW64 /d/temp/000/111
$ git init --shared=0666
Bare repository is initialized Git в D:/temp/000/111/.git/
Developer#BUSHCOMP MINGW64 /d/temp/000/111 (master)
$ echo 2>test.txt
Developer#BUSHCOMP MINGW64 /d/temp/000/111 (master)
$ git add test.txt
Developer#BUSHCOMP MINGW64 /d/temp/000/111 (master)
$ git commit -m "Test"
[master (root commit) 0d01d64] Test
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test.txt
Developer#BUSHCOMP MINGW64 /d/temp/000/111 (master)
$ ls -l test.txt
-rw-r--r-- 1 Developer Domain users 0 Sep 10 17:10 test.txt
At this case I see `-rw-r--r--` instead of `-rw-rw-rw-` also.
I've updated Git for Windows from 2.4.5 to 2.5.2 but these problems exist stil.
UPD
I got the answer here.

Git Install Script How to enter shell command

This is more of a git related question than openshift.
When I push files to the git server using git, I see that the file permissions of my perl index.cgi file gets changed to 700 in my openshift repo.
Hence every time I do a push, I have to log in to the server using ssh and do a chmod a+x index.cgi in my $OPENSHIFT_REPO_DIR to change it to 755.
I read in the git documentation it is possible to add a hook and I tried updating the post update script in the hooks directory with the following command
exec chmod a+x $OPENSHIFT_DATA_DIR/index.cgi
However that does not seemed to have worked.
Can you please tell me what I am doing wrong ?
How can I ensure I don't have to make the chmod change every time I push files ?
How does one execute shell commands via the git install script (I don't know what is install script, I assume it means the hooks)
based on a below suggestion i thought i would need to add the hook to the server so i tried it but i got an error
$ git add .git/hooks/post-update
error: Invalid path '.git/hooks/post-update'
error: unable to add .git/hooks/post-update to index
so i tried some options using action hooks by placing a "start" in the local .openshift/action_hooks directory.
The command there ive tried to use was
exec chmod a+x register.cgi and even chmod a+x register.cgi
Not much luck. Any inputs. I will be raising this as a separate q against actionhooks.
This is more of a git related question than openshift.
Actually, it is more related to openshift than it is to Git: Git only records 644 and 755 permissions.
But the destination system managing a checkout (and updating a working tree) would set the permission according to the default umask (which could be in your case 077).
Make sure the default umask is 022.
Regarding the hook, check its name ('post-update', no extension) and permission (it must be executable, 755 would be useful)
Bring authority in this case gitweb folder.
gitweb/
drwxr-xr-x 3 root root 4096 Sep 25 12:01 .
drwxr-xr-x 225 root root 12288 Oct 27 20:10 ..
-rwxr-xr-x 1 root root 251319 Sep 23 04:36 gitweb.cgi
lrwxrwxrwx 1 root root 10 Sep 23 04:36 index.cgi -> gitweb.cgi
drwxr-xr-x 2 root root 4096 Sep 25 12:01 static

How to allow a group access for a GIT repo (Ubuntu)

So I have a GIT repo hosted with Gitosis.
I have a user called user1 and of course user root.
user1 belongs to group 'dev'
/var/www is owned by root, and grouped to 'dev'
permissions for the group are rwx
user1 has confirmed access to the git repo. I cloned it already and that works fine.
BUT, when I try to have user1 pull the repo on /var/www I get
error: cannot open .git/FETCH_HEAD: Permission denied
So what else am I missing. The GIT repo is already a --shared repo. For some reason I can't get this user to pull on /var/www ?
Thanks!
So turns out the answer was to change the GROUP of the .git folder to that of the user.
I hadn't realized that .git/FETCH_HEAD was a program and access was denied to run that. I thought it was a gitosis thing but it wasn't.
Thanks!
You can fix them retroactively (after which you won't need the config setting) with
chmod -R user:group /path/to/shared.git
find /path/to/shared.git -type d |xargs chmod 2775 # or 2770 if you don't want it public
find /path/to/shared.git -type f |xargs chmod 444 # or 440
find /path/to/shared.git/hooks |xargs chmod ugo+x # or ug+x

Resources