Merge branch 'master' into 7478-anm-spot-instances
[arvados.git] / services / api / app / models / commit.rb
index aa384622f435e95a23ec6452c1807715adea290d..921c690cd00f78f6fc2b46bbace23fff89992db8 100644 (file)
@@ -2,10 +2,12 @@
 #
 # SPDX-License-Identifier: AGPL-3.0
 
+require 'request_error'
+
 class Commit < ActiveRecord::Base
   extend CurrentApiClient
 
-  class GitError < StandardError
+  class GitError < RequestError
     def http_status
       422
     end
@@ -149,7 +151,7 @@ class Commit < ActiveRecord::Base
     dst_gitdir = Rails.configuration.git_internal_dir
 
     begin
-      commit_in_dst = must_git(dst_gitdir, "rev-parse --verify #{sha1.shellescape}^{commit}").strip
+      commit_in_dst = must_git(dst_gitdir, "log -n1 --format=%H #{sha1.shellescape}^{commit}").strip
     rescue GitError
       commit_in_dst = false
     end
@@ -164,7 +166,8 @@ class Commit < ActiveRecord::Base
       # is no such branch, or the branch we choose changes under us in
       # race), we fall back to pack|unpack.
       begin
-        branches = must_git("branch --contains #{sha1.shellescape}^{commit}")
+        branches = must_git(src_gitdir,
+                            "branch --contains #{sha1.shellescape}")
         m = branches.match(/^. (\w+)\n/)
         if !m
           raise GitError.new "commit is not on any branch"
@@ -172,6 +175,11 @@ class Commit < ActiveRecord::Base
         branch = m[1]
         must_git(dst_gitdir,
                  "fetch file://#{src_gitdir.shellescape} #{branch.shellescape}")
+        # Even if all of the above steps succeeded, we might still not
+        # have the right commit due to a race, in which case tag_cmd
+        # will fail, and we'll need to fall back to pack|unpack. So
+        # don't be tempted to condense this tag_cmd and the one in the
+        # rescue block into a single attempt.
         must_git(dst_gitdir, tag_cmd)
       rescue GitError
         must_pipe("echo #{sha1.shellescape}",
@@ -213,7 +221,7 @@ class Commit < ActiveRecord::Base
   end
 
   def self.cache_dir_base
-    Rails.root.join 'tmp', 'git'
+    Rails.root.join 'tmp', 'git-cache'
   end
 
   def self.fetch_remote_repository gitdir, git_url