3126: Handle "no local repository" case better.
[arvados.git] / services / api / app / models / commit.rb
index 5d6e555755ab3f504aa1f8548d6c9db10a62265b..a6b085722e90fb043a2277f7781727218e8e2559 100644 (file)
@@ -119,6 +119,9 @@ class Commit < ActiveRecord::Base
       raise ArgumentError.new "invalid sha1 #{sha1}"
     end
     src_gitdir, _ = git_dir_for repo_name
+    unless src_gitdir
+      raise ArgumentError.new "no local repository for #{repo_name}"
+    end
     dst_gitdir = Rails.configuration.git_internal_dir
     must_pipe("echo #{sha1.shellescape}",
               "git --git-dir #{src_gitdir.shellescape} pack-objects -q --revs --stdout",
@@ -154,8 +157,11 @@ class Commit < ActiveRecord::Base
   end
 
   def self.cache_dir_for git_url
-    Rails.root.join('tmp', 'git', Digest::SHA1.hexdigest(git_url) + ".git").
-      to_s
+    File.join(cache_dir_base, Digest::SHA1.hexdigest(git_url) + ".git").to_s
+  end
+
+  def self.cache_dir_base
+    Rails.root.join 'tmp', 'git'
   end
 
   def self.fetch_remote_repository gitdir, git_url
@@ -166,9 +172,16 @@ class Commit < ActiveRecord::Base
     unless /^[a-z]+:\/\// =~ git_url
       raise ArgumentError.new "invalid git url #{git_url}"
     end
-    FileUtils.mkdir_p gitdir
+    begin
+      must_git gitdir, "branch"
+    rescue GitError => e
+      raise unless /Not a git repository/ =~ e.to_s
+      # OK, this just means we need to create a blank cache repository
+      # before fetching.
+      FileUtils.mkdir_p gitdir
+      must_git gitdir, "init"
+    end
     must_git(gitdir,
-             "init",
              "fetch --no-progress --tags --prune --force --update-head-ok #{git_url.shellescape} 'refs/heads/*:refs/heads/*'")
   end