5

I'm part of a small team trying to start coding on a project. I've decided it's time to give git a chance (no more svn) and was trying to see if we could use our shared web hosting to deploy a "public" repository there so that we can easily push/pull to/from it and keep up-to-date with each others changes.

The problem I'm having now is that we only have a single ssh account for that hosting. Having used svn in the past, I could enforce a svn username on a given pair of ssh keys, however I don't seem to be able to do something similar with git (in other words tie the ssh keypair to a specific dev). I don't mind everybody having read/write permissions everywhere, since anything that is private should stay on each others machine. Finally, solutions such as gitosis can not be used.

I guess my question to you is how is accountability to git pushes given? Is it tied to the ssh account being used, or the email address given in git config? Can I create different ssh keys for every developer (for the same ssh account though), and just send them to the devs?

acp
  • 71
  • 1
  • 8

6 Answers6

9

Normally you have a git user where everyone uses to commit, and they have ssh keys on the server so that you can log in. I use gitolite to manage my git repository at work. However you can do it with just ssh access.

Login to your webhost make a folder for your project. Then have your developers create rsa public keys, copy them to your webhost's home folder. Copy them into ~/.ssh/authorized_keys. Now all your developers will be able to ssh into that machine. Now you have them do git pull webhostUsername@somehost:project.git

Example to set up empty directory:

ssh user@host.com
mkdir someProject.git
cd someProject.git
git init --bare
cd ~
git clone user@host:someProject.git test
cd test
touch README
git add README
git commit -m "added readme"
git push

Add developers to that account

scp someuser_id.pub user@host.com:
ssh user@host.com
cat someuser_if.pub >> ~/.ssh/authorized_keys

Now the person who created that public key will be able to connect to your server.

Every person that uses git has to give a username and email. That is how you keep track of who is using it. The user you use to push is only there for communicating.

Ethan
  • 6,883
  • 3
  • 33
  • 41
  • @acp, In addition to this answer, make sure your developers also set up their username and email with git as suggested by Chilledrat – Pablo Maurin Mar 30 '12 at 18:48
  • @PabloMaurin very true. At least git should force the developer to put in a name and email.. Someone was thinking when they designed git... :-) – Ethan Mar 31 '12 at 03:52
6

We had a similar problem: one server with a git cloned repo and a used to which devs were connecting using SSH keys. Our problem was that we needed the exact committer that pushed from this server to Github.

git config which could be run probably from .bascrc at login time does not help since this sets the settings (user.name and user.email) in the SSH-enables users's home directory, and therefore to all devs connecting. Therefore the last one that makes a connection overrides the setting one other dev has just set.

I have found this article that you might also need about Carrying your Git settings around. This is about setting the variables:

GIT_AUTHOR_NAME="Developer Name"
GIT_AUTHOR_EMAIL=foo@example.org
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"

on the developer machines and letting SSH forward them to the server as described in the pointed article.

But anyways, developers must be trusted since they can always spoof these settings.

Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
Gabriel Petrovay
  • 20,476
  • 22
  • 97
  • 168
1

The short answer is to get each developer to run the following two commands on their development machine(s) before committing anything:

git config --global user.name "Example Name"
git config --global user.email "example@email.address.com"

You can check what your current settings are with:

git config --list

These settings will be recorded against each commit the developer makes and can be seen when listing the log, etc. Remember, with git the changes are recorded locally first before being pushed to your public repo. The method of connecting to the public repo for pushing (ssh, git:// or locally) has no bearing on the commit.

The global settings can be overridden with environment variables (see git-commit-tree man page for details), but if neither the environment variables or global settings listed above are present, git will use settings recorded against the system account used to make the commit (user and host name.)

Chilledrat
  • 2,593
  • 3
  • 28
  • 38
0

With Gitosis, you'd essentially set up a single shell account that accepts multiple SSH keys. Each dev has their own key, and each dev's commits get correctly attributed to the key owner, not the shell account owner.

koppor
  • 19,079
  • 15
  • 119
  • 161
Alex Howansky
  • 50,515
  • 8
  • 78
  • 98
  • The OP's problem is having only one ssh account. Though conceivable to use his single ssh account as both a gitosis account and a regular shell account, that is very messy, and highly discouraged. @Ethan has the correct answer – Pablo Maurin Mar 30 '12 at 18:45
  • 1
    @PabloMaurin in Ethan's answer there is also a single ssh shell account used for all the developers. There's exactly zero difference in security, aside from the extra software layer. The only problem is the question states gitosis cannot be used. – wds Jun 19 '12 at 13:56
-1

Just as an update, I ended up doing the above with a custom gitserve script I found somewhere round (sorry don't have the link anymore):

#!/usr/bin/env ruby

# user and permissions are passed from authorized_keys

user = ARGV[0]
permissions = ARGV[1]
command = ENV['SSH_ORIGINAL_COMMAND']
abort unless user and permissions and command

# check the supplied command contains a valid git action 

valid_actions = ['git-receive-pack', 'git-upload-pack']
action = command.split[0]
abort unless valid_actions.include? action

# check the permissions for this user

abort "read denied for #{user}" unless permissions =~ /r/
abort "write denied for #{user}" if action == 'git-receive-pack' and permissions !~ /w/

STDERR.write "user #{user} authorized\n"

# user made a valid request so handing over to git-shell

Kernel.exec 'git', 'shell', '-c', command

My .authorized_keys file contains then entries starting like that:

command="/path/to/custom/script <username> <permissions>",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa ...

where permissions = r, w or rw. Thanks all for your comments!

acp
  • 71
  • 1
  • 8
-2

Try a free hosted solution which can offer many advantages over hosting on your server. Advantages such as advanced merge request workflows, web based code browsers with all sorts of features, etc.

You may want to check out Assembla - http://www.assembla.com. They just release their advanced merge request workflows for Git which have been a very helpful: http://blog.assembla.com/assemblablog/tabid/12618/bid/80158/Announcing-Advanced-Merge-Requests-for-Git.aspx

John
  • 35
  • 3