Class: Gollum::GitAccess

Inherits:
Object
  • Object
show all
Defined in:
lib/gollum/git_access.rb

Overview

Controls all access to the Git objects from Gollum. Extend this class to add custom caching for special cases.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, page_file_dir = nil) ⇒ GitAccess

Initializes the GitAccess instance.

path - The String path to the Git repository that holds the

Gollum site.

page_file_dir - String the directory in which all page files reside

Returns this instance.



12
13
14
15
16
17
# File 'lib/gollum/git_access.rb', line 12

def initialize(path, page_file_dir = nil)
  @page_file_dir = page_file_dir
  @path = path
  @repo = Grit::Repo.new(path)
  clear
end

Instance Attribute Details

#commit_mapObject (readonly)

Gets a Hash cache of commit SHAs to the Grit::Commit instance.

{"abcd123" => <Grit::Commit>}


132
133
134
# File 'lib/gollum/git_access.rb', line 132

def commit_map
  @commit_map
end

#pathObject (readonly)

Gets the String path to the Git repository.



111
112
113
# File 'lib/gollum/git_access.rb', line 111

def path
  @path
end

#ref_mapObject (readonly)

Gets a Hash cache of refs to commit SHAs.

{"master" => "abc123", ...}


120
121
122
# File 'lib/gollum/git_access.rb', line 120

def ref_map
  @ref_map
end

#repoObject (readonly)

Gets the Grit::Repo instance for the Git repository.



114
115
116
# File 'lib/gollum/git_access.rb', line 114

def repo
  @repo
end

#tree_mapObject (readonly)

Gets a Hash cache of commit SHAs to a recursive tree of blobs.

{"abc123" => [<BlobEntry>, <BlobEntry>]}


126
127
128
# File 'lib/gollum/git_access.rb', line 126

def tree_map
  @tree_map
end

Instance Method Details

#blob(sha) ⇒ Object

Public: Fetches the contents of the Git blob at the given SHA.

sha - A String Git SHA.

Returns the String content of the blob.



63
64
65
# File 'lib/gollum/git_access.rb', line 63

def blob(sha)
  cat_file!(sha)
end

#cat_file!(sha) ⇒ Object

Reads the content from the Git db at the given SHA.

sha - The String SHA.

Returns the String content of the Git object.



181
182
183
# File 'lib/gollum/git_access.rb', line 181

def cat_file!(sha)
  @repo.git.cat_file({:p => true}, sha)
end

#clearObject

Public: Clears all of the cached data that this GitAccess is tracking.

Returns nothing.



90
91
92
93
94
# File 'lib/gollum/git_access.rb', line 90

def clear
  @ref_map    = {}
  @tree_map   = {}
  @commit_map = {}
end

#commit(ref) ⇒ Object

Public: Looks up the Git commit using the given Git SHA or ref.

ref - A String Git SHA or ref.

Returns a Grit::Commit.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/gollum/git_access.rb', line 72

def commit(ref)
  if sha?(ref)
    get_cache(:commit, ref) { commit!(ref) }
  else
    if sha = get_cache(:ref, ref)
      commit(sha)
    else
      if cm = commit!(ref)
        set_cache(:ref,    ref,   cm.id)
        set_cache(:commit, cm.id, cm)
      end
    end
  end
end

#commit!(sha) ⇒ Object

Reads a Git commit.

sha - The string SHA of the Git commit.

Returns a Grit::Commit.



190
191
192
# File 'lib/gollum/git_access.rb', line 190

def commit!(sha)
  @repo.commit(sha)
end

#decode_git_path(path) ⇒ Object

Decode octal sequences (NNN) in tree path names.

path - String path name.

Returns a decoded String.



239
240
241
242
243
244
245
246
# File 'lib/gollum/git_access.rb', line 239

def decode_git_path(path)
  if path[0] == ?" && path[-1] == ?"
    path = path[1...-1]
    path.gsub!(/\\\d{3}/)   { |m| m[1..-1].to_i(8).chr }
  end
  path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m.to_s}")) }
  path
end

#exist?Boolean

Public: Determines whether the Git repository exists on disk.

Returns true if it exists, or false.

Returns:

  • (Boolean)


22
23
24
# File 'lib/gollum/git_access.rb', line 22

def exist?
  @repo.git.exist?
end

#get_cache(name, key) ⇒ Object

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.



202
203
204
205
206
207
208
209
# File 'lib/gollum/git_access.rb', line 202

def get_cache(name, key)
  cache = instance_variable_get("@#{name}_map")
  value = cache[key]
  if value.nil? && block_given?
    set_cache(name, key, value = yield)
  end
  value == :_nil ? nil : value
end

#parse_tree_line(line) ⇒ Object

Parses a line of output from the ‘ls-tree` command.

line - A String line of output:

"100644 blob 839c2291b30495b9a882c17d08254d3c90d8fb53  Home.md"

Returns an Array of BlobEntry instances.



229
230
231
232
# File 'lib/gollum/git_access.rb', line 229

def parse_tree_line(line)
  mode, type, sha, size, *name = line.split(/\s+/)
  BlobEntry.new(sha, name.join(' '), size.to_i)
end

#ref_to_sha(ref) ⇒ Object

Public: Converts a given Git reference to a SHA, using the cache if available.

ref - a String Git reference (ex: “master”)

Returns a String, or nil if the ref isn’t found.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/gollum/git_access.rb', line 32

def ref_to_sha(ref)
  ref = ref.to_s
  return if ref.empty?
  sha =
    if sha?(ref)
      ref
    else
      get_cache(:ref, ref) { ref_to_sha!(ref) }
    end.to_s
  sha.empty? ? nil : sha
end

#ref_to_sha!(ref) ⇒ Object

Looks up the Git SHA for the given Git ref.

ref - String Git ref.

Returns a String SHA.



148
149
150
151
# File 'lib/gollum/git_access.rb', line 148

def ref_to_sha!(ref)
  @repo.git.rev_list({:max_count=>1}, ref)
rescue Grit::GitRuby::Repository::NoSuchShaFound
end

#refreshObject

Public: Refreshes just the cached Git reference data. This should be called after every Gollum update.

Returns nothing.



100
101
102
# File 'lib/gollum/git_access.rb', line 100

def refresh
  @ref_map.clear
end

#set_cache(name, key, value) ⇒ Object

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.



218
219
220
221
# File 'lib/gollum/git_access.rb', line 218

def set_cache(name, key, value)
  cache      = instance_variable_get("@#{name}_map")
  cache[key] = value || :_nil
end

#sha?(str) ⇒ Boolean

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.

Returns:

  • (Boolean)


139
140
141
# File 'lib/gollum/git_access.rb', line 139

def sha?(str)
  !!(str =~ /^[0-9a-f]{40}$/)
end

#tree(ref) ⇒ Object

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.



50
51
52
53
54
55
56
# File 'lib/gollum/git_access.rb', line 50

def tree(ref)
  if sha = ref_to_sha(ref)
    get_cache(:tree, sha) { tree!(sha) }
  else
    []
  end
end

#tree!(sha) ⇒ Object

Looks up the Git blobs for a given commit.

sha - String commit SHA.

Returns an Array of BlobEntry instances.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/gollum/git_access.rb', line 158

def tree!(sha)
  tree  = @repo.git.native(:ls_tree,
    {:r => true, :l => true, :z => true}, sha)
  if tree.respond_to?(:force_encoding)
    tree.force_encoding("UTF-8")
  end
  items = tree.split("\0").inject([]) do |memo, line|
    memo << parse_tree_line(line)
  end

  if dir = @page_file_dir
    regex = /^#{dir}\//
    items.select { |i| i.path =~ regex }
  else
    items
  end
end