This commit is contained in:
rick
2010-11-20 13:08:39 -08:00
parent 0b8bc597a7
commit 4dda9fb2ae
3 changed files with 118 additions and 19 deletions
+4 -3
View File
@@ -3,9 +3,10 @@ module Gollum
# Gets the String SHA for this blob.
attr_reader :sha
# Gets the String full path for this blob.
# Gets the full path String for this blob.
attr_reader :path
# Gets the Fixnum size of this blob.
attr_reader :size
def initialize(sha, path, size = nil)
@@ -15,12 +16,12 @@ module Gollum
@dir = @name = @blob = nil
end
# Gets the normalized directory path for this blob.
# Gets the normalized directory path String for this blob.
def dir
@dir ||= self.class.normalize_dir(::File.dirname(@path))
end
# Gets the String file base name for this blob.
# Gets the file base name String for this blob.
def name
@name ||= ::File.basename(@path)
end
+114 -15
View File
@@ -1,21 +1,29 @@
module Gollum
# Controls all access to the Git objects from Gollum. Extend this class to
# add custom caching for special cases.
class GitAccess
# Gets the String path to the Git repository.
attr_reader :path
# Gets the Grit::Repo instance for the Git repository.
attr_reader :repo
# Gets a Hash cache of refs to commit SHAs.
#
# {"master" => "abc123", ...}
#
# Returns the Hash cache.
attr_reader :ref_map
# Gets a Hash cache of commit SHAs to a recursive tree of blobs.
#
# {"abc123" => [["lib/foo.rb", "blob-sha"], [file, sha], ...], ...}
# {"abc123" => [<BlobEntry>, <BlobEntry>]}
#
# Returns the Hash cache.
attr_reader :tree_map
# Gets a Hash cache of commit SHAs to the Grit::Commit instance.
#
# {"abcd123" => <Grit::Commit>}
#
attr_reader :commit_map
def initialize(path)
@@ -24,20 +32,19 @@ module Gollum
clear
end
def clear
@ref_map = {}
@tree_map = {}
@commit_map = {}
end
def refresh
@ref_map.clear
end
# Public: Determines whether the Git repository exists on disk.
#
# Returns true if it exists, or false.
def exist?
@repo.git.exist?
end
# Public: Converts a given Git reference to a SHA, using the cache if
# available.
#
# ref - a String Git reference (ex: "master")
#
# Returns a String.
def ref_to_sha(ref)
if sha?(ref)
ref
@@ -46,6 +53,12 @@ module Gollum
end
end
# Public: Gets a recursive list of Git blobs for the whole tree at the
# given commit.
#
# ref - A String Git reference or Git SHA to a commit.
#
# Returns an Array of BlobEntry instances.
def tree(ref)
if sha = ref_to_sha(ref)
get_cache(:tree, sha) { tree!(sha) }
@@ -54,10 +67,20 @@ module Gollum
end
end
# Public: Fetches the contents of the Git blob at the given SHA.
#
# sha - A String Git SHA.
#
# Returns the String content of the blob.
def blob(sha)
cat_file!(sha)
end
# Public: Looks up the Git commit using the given Git SHA or ref.
#
# ref - A String Git SHA or ref.
#
# Returns a Grit::Commit.
def commit(ref)
if sha?(ref)
get_cache(:commit, ref) { commit!(ref) }
@@ -73,6 +96,11 @@ module Gollum
end
end
# Public: Gets a list of Git commits.
#
# *shas - An Array of String SHAs.
#
# Returns an Array of Grit::Commit instances.
def commits(*shas)
shas.flatten!
cached_commits = multi_get(:commit, shas)
@@ -85,23 +113,62 @@ module Gollum
shas.map { |sha| cached_commits[sha] }
end
def multi_commit!(shas, hash)
# Public: Clears all of the cached data that this GitAccess is tracking.
#
# Returns nothing.
def clear
@ref_map = {}
@tree_map = {}
@commit_map = {}
end
# Public: Refreshes just the cached Git reference data. This should
# be called after every Gollum update.
#
# Returns nothing.
def refresh
@ref_map.clear
end
# Raw method for fetching a list of Git commits.
#
# shas - An Array of String SHAs.
# hash - Optional Hash to store the found commits, indexed by their SHA.
#
# Returns the same Hash instance.
def multi_commit!(shas, hash = {})
shas.each_slice(500) do |slice|
@repo.batch(slice).each do |commit|
hash[commit.id] = commit
end
end
hash
end
# Checks to see if the given String is a 40 character hex SHA.
#
# str - Possible String SHA.
#
# Returns true if the String is a SHA, or false.
def sha?(str)
str =~ /^[0-9a-f]{40}$/
!!(str =~ /^[0-9a-f]{40}$/)
end
# Looks up the Git SHA for the given Git ref.
#
# ref - String Git ref.
#
# Returns a String SHA.
def ref_to_sha!(ref)
@repo.git.rev_list({:max_count=>1}, ref)
rescue Grit::GitRuby::Repository::NoSuchShaFound
end
# Looks up the Git blobs for a given commit.
#
# sha - String commit SHA.
#
# Returns an Array of BlobEntry instances.
def tree!(sha)
tree = @repo.git.native(:ls_tree,
{:r => true, :l => true, :z => true}, sha)
@@ -110,14 +177,32 @@ module Gollum
end
end
# Reads the content from the Git db at the given SHA.
#
# sha - The String SHA.
#
# Returns the String content of the Git object.
def cat_file!(sha)
@repo.git.cat_file({:p => true}, sha)
end
# Reads a Git commit.
#
# sha - The string SHA of the Git commit.
#
# Returns a Grit::Commit.
def commit!(sha)
@repo.commit(sha)
end
# Attempts to get the given data from a cache. If it doesn't exist, it'll
# pass the results of the yielded block to the cache for future accesses.
#
# name - The cache prefix used in building the full cache key.
# key - The unique cache key suffix, usually a String Git SHA.
#
# Yields a block to pass to the cache.
# Returns the cached result.
def get_cache(name, key)
cache = instance_variable_get("@#{name}_map")
value = cache[key]
@@ -127,11 +212,25 @@ module Gollum
value == :_nil ? nil : value
end
# Writes some data to the internal cache.
#
# name - The cache prefix used in building the full cache key.
# key - The unique cache key suffix, usually a String Git SHA.
# value - The value to write to the cache.
#
# Returns nothing.
def set_cache(name, key, value)
cache = instance_variable_get("@#{name}_map")
cache[key] = value || :_nil
end
# Gets multiple values from the cache in a single call.
#
# name - The cache prefix used in building the full cache key.
# keys - Array of cache key names to fetch.
#
# Returns a Hash of the objects that were found in the cache, indexed by
# the cache key.
def multi_get(name, keys)
value = instance_variable_get("@#{name}_map")
keys.inject({}) do |memo, key|
-1
View File
@@ -1,5 +1,4 @@
module Gollum
# Encapsulate sanitization options.
#
# This class does not yet support all options of Sanitize library.