meetteem: tech addict

software development, etc.

Using Capistrano to Create A Remote Git Repository

Last night, I thought about buying a GitHub micro plan to host my private projects. The free account in GitHub gives you a 100MB storage and unlimited public repositories, but no private repositories. It has a nice web interface, which makes things like creating repositories easy.

Anyway, after further thinking, I decided not to buy and use my VPS instead. I have a VPS which has several gigs more of storage space, and that's more than enough for Git hosting. And I only want it for my private/personal projects. For open source, GitHub is always there.

One of the things that I seem to keep repeating is setting up a remote git repository. So to address this repetitive task, I created a tiny Capistrano script to do just that: create a remote repository in my VPS.

Here's the capfile.

set :root_path, "/var/git/"
set :box, "server.com"

namespace :git do

  desc "Create a bare git repository"
  task :create, :hosts => box do
    get_repository_name()
    path = "#{root_path}#{gitdirname}"
    create_bare_repository(path)
  end

  desc "View clone urls of existing git repos in #{box}:#{root_path}"
  task :view_clone_urls, :hosts => box do
    sudo "ls #{root_path}" do |ch, stream, data|
      data.split(/\s+/).each do |r|
        puts "#{r.ljust(20)} -> git@#{box}:#{root_path}#{r}"
      end
    end
  end

  def get_repository_name
    set(:gitdirname) { Capistrano::CLI.ui.ask "Enter project name: " }
    set(:gitdirname, "#{gitdirname}.git") if gitdirname[-4..-1] != ".git"
  end

  def create_bare_repository(repo_path)
    sudo "mkdir #{repo_path}"
    run "cd #{repo_path} && #{sudo} git --bare init"
    sudo "chown -R git:git #{repo_path}"

    puts "\n\nClone url: git@#{box}:#{repo_path}\n"
    puts "To add the new remote to your existing git, run: "
    puts "  git remote add origin git@#{box}:#{repo_path}"
    puts "After committing the changes, push the with the following command"
    puts "  git push origin master\n\n"
  end

end

How to use?

Get it and check out the cap tasks.

~/dev/tools$ cap -T
cap git:create          # Create a bare git repository
cap git:view_clone_urls # View clone urls of existing git repos in server.com...
...

Edit the variables root_path and box near the top of the capfile. root_path is the path in the remote machine where the repo will be stored, and box is the server address.

Let's create a remote repository using cap git:create.

~/dev/tools$ cap git:create
  * executing `git:create'
Enter project name: hello-world
  * executing "sudo -p 'sudo password: ' mkdir /var/git/hello-world.git"
    servers: ["server.com"]
    [server.com] executing command
    command finished
  * executing "cd /var/git/hello-world.git && sudo -p 'sudo password: ' git --bare init"
    servers: ["server.com"]
    [server.com] executing command
 ** [out :: server.com] Initialized empty Git repository in /var/git/hello-world.git/
    command finished
  * executing "sudo -p 'sudo password: ' chown -R git:git /var/git/hello-world.git"
    servers: ["server.com"]
    [server.com] executing command
    command finished


    Clone url: git@server.com:/var/git/hello-world.git
    To add the new remote to your existing git, run: 
      git remote add origin git@server.com:/var/git/hello-world.git
    After committing the changes, push the with the following command
      git push origin master

And bind our project to the remote repository using git-remote add and push it to our newly created remote.

  ~/dev/tools/hello-world$ git remote add origin git@server.com:/var/git/hello-world.git
  ~/dev/tools/hello-world$ git push origin master
  Counting objects: 3, done.
  Writing objects: 100% (3/3), 215 bytes, done.
  Total 3 (delta 0), reused 0 (delta 0)
  To git@server.com:/var/git/hello-world.git
   * [new branch]      master -> master

So, there.