Permalink
Browse files

Only use gitrb to create commits

  • Loading branch information...
1 parent e230456 commit 67cccfb8814eb15f1debc5d51127b82cb81bd808 @bronson bronson committed Nov 1, 2011
Showing with 88 additions and 19 deletions.
  1. +24 −18 lib/gitrepo.rb
  2. +64 −1 spec/gitrepo_spec.rb
View
@@ -1,7 +1,5 @@
# interface for working on git repos, insulates app from underlying implementation
-# todo: make a way for caller to tell GitRepo to indent all log messages?
-
require 'gitrb'
require 'retryable'
@@ -10,48 +8,54 @@ class GitRepo
include Retryable # only for network operations
class GitError < RuntimeError; end
+ attr_reader :root, :bare
# required: :root, the directory to contain the repo
# optional: :clone a repo to clone (:bare => true if it should be bare)
# :create to create a new empty repo if it doesn't already exist
def initialize opts
@root = opts[:root]
+ @bare = opts[:bare]
+
+ retryable_options opts[:retryable_options] if opts[:retryable_options]
if opts[:clone]
retryable(:task => "cloning #{opts[:clone]}") do
args = [opts[:clone], opts[:root]]
args.push '--bare' if opts[:bare]
git_exec :clone, *args
end
+ elsif opts[:create]
+ Dir.mkdir opts[:root] unless test ?d, opts[:root]
+ if opts[:bare]
+ git :init, '--bare'
+ else
+ git :init
+ end
end
- unless opts[:create] # unless we're creating it, repo needs to exist by now
- raise "#{@root} doesn't exist" unless test ?d, @root
+ # a little sanity checking, catch simple errors early
+ raise GitError.new "#{@root} does not exist" unless test ?d, @root
+ if opts[:bare]
+ raise GitError.new "#{@root} does not appear to be a bare repo" unless test(?d, File.join(@root, 'objects'))
+ else
+ raise GitError.new "#{@root}/.git does not exist" unless test(?d, File.join(@root, '.git'))
+ raise GitError.new "#{@root}/.git does not appear to be a git repo" unless test(?d, File.join(@root, '.git', 'objects'))
end
-
- # todo: move gitrb so it only exists in CommitHelper
- # gitrb has a bug where it will complain about frozen strings unless you dup the path
- @repo = Gitrb::Repository.new(:path => @root.dup, :bare => opts[:bare], :create => opts[:create])
- end
-
- def root
- @root
end
def git_exec *args
args = args.map { |a| a.to_s }
out = IO.popen('-', 'r') do |io|
- if io
- # parent, read the git output
+ if io # parent
block_given? ? yield(io) : io.read
- else
+ else # child
STDERR.reopen STDOUT
exec 'git', *args
end
end
if $?.exitstatus > 0
- # return '' if $?.exitstatus == 1 && out == ''
raise GitError.new("git #{args.join(' ')}: #{out}")
end
@@ -143,8 +147,10 @@ def entries
def commit message, author, committer=author
author = Gitrb::User.new(author[:name], author[:email], author[:date] || Time.now)
committer = Gitrb::User.new(committer[:name], committer[:email], committer[:date] || Time.now)
- @repo.transaction(message, author, committer) do
- yield CommitHelper.new @repo
+ # gitrb has a bug where it will complain about frozen strings unless you dup the path
+ repo = Gitrb::Repository.new(:path => root.dup, :bare => bare, :create => false)
+ repo.transaction(message, author, committer) do
+ yield CommitHelper.new(repo)
end
end
end
View
@@ -27,7 +27,7 @@ def with_git_repo args={}, &block
end
end
- # creates a git repo with one commit (git can get psychotic when a repo has 0 commits)
+ # creates a git repo with one commit ugit can get psychotic when a repo has 0 commits)
def with_git_commit *args
with_git_repo(*args) do |repo|
author = { :name => "test author", :email => "testemail@example.com" }
@@ -39,6 +39,69 @@ def with_git_commit *args
end
+ it "should create a regular repo" do
+ Dir.mktmpdir 'gitrepo-test-' do |dir|
+ GitRepo.new :root => dir, :create => true
+ raise "no .git" unless test ?d, File.join(dir, '.git')
+ raise "no .git/objects" unless test ?d, File.join(dir, '.git', 'objects')
+ GitRepo.new :root => dir
+ end
+ end
+
+ it "should create a bare repo" do
+ Dir.mktmpdir 'gitrepo-test-' do |dir|
+ GitRepo.new :root => dir, :bare => true, :create => true
+ raise "no objects" unless test ?d, File.join(dir, 'objects')
+ GitRepo.new :root => dir, :bare => true
+ end
+ end
+
+ it "should error out if no repo" do
+ lambda {
+ GitRepo.new :root => '/usr/haha'
+ }.should raise_error(GitRepo::GitError, /does not exist/)
+ end
+
+ it "should refuse to open a bare repo as regular" do
+ with_git_repo(:bare => true) do |repo|
+ lambda {
+ GitRepo.new :root => repo.root
+ }.should raise_error(GitRepo::GitError, /does not exist/)
+ end
+ end
+
+ it "should refuse to open a regular repo as bare" do
+ with_git_repo do |repo|
+ lambda {
+ GitRepo.new :root => repo.root, :bare => true
+ }.should raise_error(GitRepo::GitError, /does not appear to be a bare repo/)
+ end
+ end
+
+ it "should clone a regular repo" do
+ Dir.mktmpdir 'gitrepo-test-' do |dir|
+ root = "#{dir}/thedir"
+ GitRepo.any_instance.should_receive(:git_exec).once.with(:clone, 'feta', root).and_return { |a,b,c,d|
+ Dir.mkdir root # need to make it look like git ran the clone, otherwise sanity checks fail
+ Dir.mkdir File.join(root, '.git')
+ Dir.mkdir File.join(root, '.git', 'objects')
+ }
+ GitRepo.new :root => root, :clone => 'feta', :retryable_options => { :logger => lambda { |task,retries,error| } }
+ end
+ end
+
+ it "should clone a bare repo" do
+ Dir.mktmpdir 'gitrepo-test-' do |dir|
+ root = "#{dir}/thedir"
+ GitRepo.any_instance.should_receive(:git_exec).once.with(:clone, 'feta', root, '--bare').and_return { |a,b,c,d|
+ Dir.mkdir root # need to make it look like git ran the clone, otherwise sanity checks fail
+ Dir.mkdir File.join(root, 'objects')
+ }
+ GitRepo.new :root => root, :clone => 'feta', :bare => true, :retryable_options => { :logger => lambda { |task,retries,error| } }
+ end
+ end
+
+
it "should allow remotes to be added and removed" do
with_git_commit(:bare => true) do |repo|
repo.remote_add :origin, 'http://example.com/'

0 comments on commit 67cccfb

Please sign in to comment.