threads / discuss / 2898

How to set up a shared repository

Subject: How to set up a shared repository

## tl;dr

3 messages between Dec 21, 2005 and Dec 21, 2005.

replies: 2people: 2as markdown or json

Johannes Schindelin· Dec 21, 2005, 18:27 UTC · lore
Hi,

I installed a shared git repository in the last few days and this is the result. May it be useful!

Ciao, Dscho

---
[Note: this text assumes you have applied the core.umask patch]

So, there you are. You know CVS (or at least its concepts), and you want to set up a shared repository.

A. Setting up the umask
1. Separate repository box

If you are lucky enough that you can afford a separate machine for the shared repository: Good. Just make sure that the umask is set group friendly, either by ensuring that (assuming the login shell is bash) $HOME/.bash_profile contains the line

	umask 0002
or by using git-shell, which you have modified by inserting
	umask(0002);
at the start of main().
2. Some server accessible by ssh

If there are valid reasons not to set umask (maybe you want to allow other uses of that machine), or if you just do not want to go through the hassle to find out which scripts your login shell executes at startup, you just have to

	git-repo-config core.umask 0002
B. Making sure the index is not corrupted by a push
1. No checkout!

You can use the shared repository just like you use CVS: no working directory. To disallow a checkout, just do

	touch .git/index
	chmod a-rwx .git/index

Every attempt to modify the index (which is invalid), will now result in an error.

2. Ensure index and working directory consistency (no locking)

If you want to be able to work on the project in the shared repository, create hooks, as follows:

	test -d .git/hooks || mkdir .git/hooks
	cat > .git/hooks/update << EOF
	#!/bin/sh
	
	# if the working directory contains modifications, do not allow push
	HEAD=$(git-symbolic-ref HEAD)
	case "$1" in
	$HEAD)
	        unset GIT_DIR
	        cd .. && test -z "$(git-diff-index --name-only HEAD)";;
	esac
	EOF
	chmod a+x .git/hooks/update
	cat > .git/hooks/post-update << EOF
	#!/bin/sh
	
	# checkout HEAD, and build
	HEAD=$(git-symbolic-ref HEAD)
	case "$1" in
	$HEAD)
	        unset GIT_DIR
		umask 0002
		cd .. && git checkout -f HEAD && make;;
	esac
	EOF
	chmod a+x .git/hooks/post-update

This assumes that your project contains a Makefile, and that the tools necessary to build are installed on the repository server.

Note that I did not check if a push locks another push.
Junio C Hamano· Dec 21, 2005, 20:56 UTC · re: Johannes Schindelin · lore

Re: How to set up a shared repository

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Show 10 quoted lines
> A. Setting up the umask
>
> 1. Separate repository box
>
> If you are lucky enough that you can afford a separate machine for the 
> shared repository: Good. Just make sure that the umask is set group 
> friendly, either by ensuring that (assuming the login shell is bash) 
> $HOME/.bash_profile contains the line
>
> 	umask 0002

I suspect a bash started from ssh noninteractive session does not read .bash_profile --- you may want to check.

> 2. Some server accessible by ssh
>
> 	git-repo-config core.umask 0002
Not yet ;-)
Show 12 quoted lines
> B. Making sure the index is not corrupted by a push
>
> 1. No checkout!
>
> You can use the shared repository just like you use CVS: no working 
> directory. To disallow a checkout, just do
>
> 	touch .git/index
> 	chmod a-rwx .git/index
>
> Every attempt to modify the index (which is invalid), will now result in 
> an error.
Arrrgh....what a hack.  But it is a good hack.
> 2. Ensure index and working directory consistency (no locking)
>
> If you want to be able to work on the project in the shared repository, 
I am very tempted to end this sentence with "please don't" ;-).
> create hooks, as follows:

Your update hook looks sane if too strict. I do not think of any reason to push and fast forward a branch that is not pointed at by .git/HEAD. Not that I encourage pushing into a non-naked repository where an uncontrolled random development happens, though.

> Note that I did not check if a push locks another push.

Although it does protect against stomping on each other by read/do-work/re-read-and-swap cycle, push does not lock. If you want to run a build from the post-update hook you need to serialize the build yourself.

Johannes Schindelin· Dec 21, 2005, 21:36 UTC · re: Junio C Hamano · lore

Re: How to set up a shared repository

Hi,
On Wed, 21 Dec 2005, Junio C Hamano wrote:
Show 15 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > A. Setting up the umask
> >
> > 1. Separate repository box
> >
> > If you are lucky enough that you can afford a separate machine for the 
> > shared repository: Good. Just make sure that the umask is set group 
> > friendly, either by ensuring that (assuming the login shell is bash) 
> > $HOME/.bash_profile contains the line
> >
> > 	umask 0002
> 
> I suspect a bash started from ssh noninteractive session does
> not read .bash_profile --- you may want to check.

Yes, you're right. But after all, this section was meant to put a little pressure on you to agree to core.umask ;-)

Show 5 quoted lines
> > 2. Some server accessible by ssh
> >
> > 	git-repo-config core.umask 0002
> 
> Not yet ;-)
Well, it is a reality here ;-)
Show 14 quoted lines
> > B. Making sure the index is not corrupted by a push
> >
> > 1. No checkout!
> >
> > You can use the shared repository just like you use CVS: no working 
> > directory. To disallow a checkout, just do
> >
> > 	touch .git/index
> > 	chmod a-rwx .git/index
> >
> > Every attempt to modify the index (which is invalid), will now result in 
> > an error.
> 
> Arrrgh....what a hack.  But it is a good hack.

It is the simplest way to achieve the goal (at least that I could think of). Thanks for the compliment!

Show 5 quoted lines
> > 2. Ensure index and working directory consistency (no locking)
> >
> > If you want to be able to work on the project in the shared repository, 
> 
> I am very tempted to end this sentence with "please don't" ;-).
You are very welcome to do so!

Of course, the use case is git itself. I host a private version with all the goodies I like so much, and which you unfortunately do not like as much.

It is a phantastic way to keep git up to date without having to login manually. It is also a phantastic way to break the setup spectacularly when something goes wrong.

Show 7 quoted lines
> > create hooks, as follows:
> 
> Your update hook looks sane if too strict.  I do not think of
> any reason to push and fast forward a branch that is not pointed
> at by .git/HEAD.  Not that I encourage pushing into a non-naked
> repository where an uncontrolled random development happens,
> though.
Is it too strict?

: #!/bin/sh : : # if the working directory contains modifications, do not allow : # push

This checks if the ref being pushed is the current HEAD:

: HEAD=$(git-symbolic-ref HEAD) : case "$1" in : $HEAD)

Only if it is, this check occurs

: unset GIT_DIR : cd .. && test -z "$(git-diff-index --name-only HEAD)";; : esac

IMHO this does exactly the right thing: Fail only if the ref to push is the current HEAD *and* something is not committed.

Show 6 quoted lines
> > Note that I did not check if a push locks another push.
> 
> Although it does protect against stomping on each other by
> read/do-work/re-read-and-swap cycle, push does not lock. If you
> want to run a build from the post-update hook you need to
> serialize the build yourself.

Yes, I feared that much. Also note that in my dangerous setup, something could go awfully wrong because post-update is currently compiling git itself, while somebody else wants to use it.

So, more and more I think about it, I should not do it then. But for a few days, I am the only user!

Thanks, Dscho

← back to recent threads