Git create remote repository on push
Checkout and track the branch from the remote:
git checkout -t origin/funbranch
Branch off of it:
git checkout -b mybranch
Push your new one up, it will create a new branch automatically on the remote:
git push origin mybranch
It should say "created new remote branch origin/mybranch"
If you are still getting "Remote end Hung up", it sounds like a security thing. Do you have SSH keys installed correctly, and do you have write permissions on the remote server?
The way most open source projects work, you have to create a fork (a clone inherently) that you use to do your work because most of the time you don't have write permissions to the repo. When you have changes, you will then send a pull request to the repository owner, and he/she will pull from your fork the changes that they want.
There is currently no way to use git push
to create a repository on the remote. The best you can do is write a one-liner script something like this:
#!/bin/bash
ssh $1 "git init --bare $2" &&
git push ssh://$1/$2
Hopefully you can ssh in; if you can't, you could use some kind of filesystem access to just manually create the repo by dumping in the appropriate file/directory structure (maybe create it locally and copy). You might also create a named remote along the way.
This was actually one of the most requested features on the 2010 Git Survey - so maybe you'll get your wish sometime in the next year!
You can write a wrapper script on the remote, and prepend command="/path/to/wrapper" to the authorized_keys' lines.
command="/usr/local/bin/gitaccess" ssh-rsa ...
In this wrapper you would check SSH_ORIGINAL_COMMAND. Git issues these commands:
git receive-pack '/path/provided' # when pushing
git upload-pack '/path/provided' # when pulling
If SSH_ORIGINAL_COMMAND is not empty and starts with one of these, you check the path, create the repository if necessary, install any configuration you need in it, and execute the command.
If SSH_ORIGINAL_COMMAND is empty and you want to provide users with shell access, you invoke a shell.
If SSH_ORIGINAL_COMMAND is not empty but doesn't start with a git command, if you want to allow users to have shell access, you just execute the command provided.
Here's a bit of Ruby code to demonstrate. Note that I didn't test it and there's room for improvement (for example we should not hardcode /bin/bash).
#!/usr/bin/env ruby
orig_command = ENV['SSH_ORIGINAL_COMMAND']
if orig_command.nil?
# If you want to preserve shell access
exec '/bin/bash' # not tested, I hope it's interactive if executed this way
end
cmd_parts = orig_command.match /([a-z-]+) '([a-z0-9.\/]+)'/
if cmd_parts.nil?
# If you want to preserve shell access
exec '/bin/bash', '-c', orig_command
end
command = cmd_parts[1]
path = '/var/repositories/'+cmd_parts[2] # not secured (could contain '..')
if command == 'git-receive-pack' || command == 'git-upload-pack'
if not File.directory?(path)
`git init --bare #{path}` # not secured, I didn't escape path
# Do any configuration here
end
exec 'git-shell', '-c', "#{command} '#{path}'"
end
# If you want to preserve shell access
exec '/bin/bash', '-c', orig_command
You can also pass an argument to this script in the authorized_keys to identify users and choose whether they should have shell access. I also do this to control access on a per-repository basis. If you want to carry this argument to the git hooks, just create an environment variable.