diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index a27225b4..9f259bee 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -39,7 +39,7 @@ module Gollum end def ref_to_sha(ref) - if ref =~ /^[0-9a-f]{40}$/ + if sha?(ref) ref else @ref_map[ref] ||= ref_to_sha!(ref) @@ -56,15 +56,46 @@ module Gollum end def commit(ref) - if sha = @ref_map[ref] + ref_is_sha = sha?(ref) + if sha = (!ref_is_sha && @ref_map[ref]) @commit_map[sha] ||= commit!(sha) else cm = commit!(ref) - @ref_map[ref] = cm.id + @ref_map[ref] = cm.id if !ref_is_sha @commit_map[cm.id] = cm end end + def commits(*shas) + shas.flatten! + cached_commits = multi_get(:commit_map, shas) + missing_shas = shas.select do |sha| + !cached_commits.key?(sha) + end + if !missing_shas.empty? + missing_shas.each_slice(500) do |slice| + @repo.batch(slice).each do |commit| + cached_commits[commit.id] = commit + end + end + end + shas.map { |sha| cached_commits[sha] } + end + + def multi_get(name, keys) + value = instance_variable_get("@#{name}") + keys.inject({}) do |memo, key| + if v = value[key] + memo[key] = v + end + memo + end + end + + def sha?(str) + str =~ /^[0-9a-f]{40}$/ + end + def ref_to_sha!(ref) @repo.git.rev_list({:max_count=>1}, ref) end diff --git a/test/test_git_access.rb b/test/test_git_access.rb index 8d991fea..7e62c689 100644 --- a/test/test_git_access.rb +++ b/test/test_git_access.rb @@ -5,6 +5,23 @@ context "GitAccess" do @access = Gollum::GitAccess.new(testpath("examples/lotr.git")) end + test "#commit fills commit_map cache" do + assert @access.commit_map.empty? + actual = @access.repo.commits.first + expected = @access.commit(actual.id) + assert_equal actual.message, expected.message + assert_equal actual.message, @access.commit_map[actual.id].message + end + + test "#commits uses commit_map" do + actual = @access.repo.commits.first + #@access.commit actual.id + @access.commit_map['abc'] = 1 + commits = @access.commits('abc', actual.id) + assert_equal 1, commits[0] + assert_equal actual.message, commits[1].message + end + test "#tree_map_for caches ref and tree" do assert @access.ref_map.empty? assert @access.tree_map.empty?