class Gollum::Git::Git
Public Class Methods
new(repo)
click to toggle source
Rugged does not have a Git
class, but the Repository class should allows us to do what's necessary.
# File lib/rugged_adapter/git_layer_rugged.rb, line 153 def initialize(repo) @repo = repo end
Public Instance Methods
apply_patch(head_sha = 'HEAD', patch=nil)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 189 def apply_patch(head_sha = 'HEAD', patch=nil) false # Rewrite gollum-lib's revert so that it doesn't require a direct equivalent of Grit's apply_patch end
cat_file(options, sha)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 185 def cat_file(options, sha) @repo.lookup(sha).read_raw end
checkout(path, ref = 'HEAD', options = {})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 198 def checkout(path, ref = 'HEAD', options = {}) path = path.nil? ? path : [path] options = options.merge({:paths => path, :strategy => :force}) if ref == 'HEAD' @repo.checkout_head(options) else ref = "refs/heads/#{ref}" unless ref =~ /^refs\/heads\// @repo.checkout_tree(sha_from_ref(ref), options) end end
commit_from_ref(ref)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 274 def commit_from_ref(ref) sha_or_commit_from_ref(ref, :commit) end
exist?()
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 157 def exist? ::File.exists?(@repo.path) end
grep(query, options={})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 161 def grep(query, options={}) ref = options[:ref] ? options[:ref] : "HEAD" tree = @repo.lookup(sha_from_ref(ref)).tree tree = @repo.lookup(tree[options[:path]][:oid]) if options[:path] results = [] tree.walk_blobs(:postorder) do |root, entry| blob = @repo.lookup(entry[:oid]) count = 0 blob.content.each_line do |line| next unless line.force_encoding("UTF-8").match(/#{Regexp.escape(query)}/i) count += 1 end path = options[:path] ? ::File.join(options[:path], root, entry[:name]) : "#{root}#{entry[:name]}" results << {:name => path, :count => count} unless count == 0 end results end
log(ref = 'refs/heads/master', path = nil, options = {})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 209 def log(ref = 'refs/heads/master', path = nil, options = {}) default_options = { :limit => options[:max_count] ? options[:max_count] : 10, :offset => options[:skip] ? options[:skip] : 0, :path => path, :follow => false, :skip_merges => false } options = default_options.merge(options) options[:limit] ||= 0 options[:offset] ||= 0 sha = sha_from_ref(ref) return [] if sha.nil? begin build_log(sha, options) rescue Rugged::OdbError, Rugged::InvalidError, Rugged::ReferenceError # Return an empty array if the ref wasn't found [] end end
lookup(id)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 247 def lookup(id) @repo.lookup(id) end
ls_files(query, options = {})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 234 def ls_files(query, options = {}) ref = options[:ref] || "refs/heads/master" tree = @repo.lookup(sha_from_ref(ref)).tree tree = @repo.lookup(tree[options[:path]][:oid]) if options[:path] results = [] tree.walk_blobs do |root, blob| next unless blob[:name] =~ /#{query}/ path = options[:path] ? ::File.join(options[:path], root, blob[:name]) : "#{root}#{blob[:name]}" results << path end results end
pull(remote, branches = nil, options = {})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 283 def pull(remote, branches = nil, options = {}) branches = [branches].flatten.map {|branch| "refs/heads/#{branch}" unless branch =~ /^refs\/heads\//} r = @repo.remotes[remote] r.fetch(branches, options) branches.each do |branch| branch_name = branch.match(/^refs\/heads\/(.*)/)[1] remote_name = remote.match(/^(refs\/heads\/)?(.*)/)[2] remote_ref = @repo.branches["#{remote_name}/#{branch_name}"].target local_ref = @repo.branches[branch].target index = @repo.merge_commits(local_ref, remote_ref) options = { author: Actor.default_actor.to_h, committer: Actor.default_actor.to_h, message: "Merged branch #{branch} of #{remote}.", parents: [local_ref, remote_ref], tree: index.write_tree(@repo), update_ref: branch } Rugged::Commit.create @repo, options @repo.checkout(@repo.head.name, :strategy => :force) if !@repo.bare? && branch == @repo.head.name end end
push(remote, branches = nil, options = {})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 278 def push(remote, branches = nil, options = {}) branches = [branches].flatten.map {|branch| "refs/heads/#{branch}" unless branch =~ /^refs\/heads\//} @repo.push(remote, branches, options) end
ref_to_sha(query)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 251 def ref_to_sha(query) return query if sha?(query) query = "refs/heads/#{query}" if !query.nil? && !(query =~ /^refs\/heads\//) && !(query == "HEAD") begin return @repo.rev_parse_oid(query) rescue Rugged::ReferenceError, Rugged::InvalidError return nil end end
revert(path, sha1, sha2, ref)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 193 def revert(path, sha1, sha2, ref) # FIXME: See https://github.com/gollum/grit_adapter/pull/14 fail NotImplementedError end
rm(path, options = {})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 179 def rm(path, options = {}) index = @repo.index index.write ::File.unlink ::File.join(@repo.workdir, path) end
sha_or_commit_from_ref(ref, request_kind = nil)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 261 def sha_or_commit_from_ref(ref, request_kind = nil) sha = ref_to_sha(ref) return nil if sha.nil? object = @repo.lookup(sha) if object.kind_of?(Rugged::Commit) then return Gollum::Git::Commit.new(object) if request_kind == :commit sha elsif object.respond_to?(:target) sha_or_commit_from_ref(object.target.oid, request_kind) end end
Also aliased as: sha_from_ref
versions_for_path(path = nil, ref = nil, options = {})
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 230 def versions_for_path(path = nil, ref = nil, options = {}) log(ref, path, options) end
Private Instance Methods
build_log(sha, options)
click to toggle source
Return an array of log commits, given an SHA hash and a hash of options. From Gitlab::Git
# File lib/rugged_adapter/git_layer_rugged.rb, line 313 def build_log(sha, options) # Instantiate a Walker and add the SHA hash walker = Rugged::Walker.new(@repo) walker.push(sha) commits = [] skipped = 0 current_path = options[:path] current_path = nil if current_path == '' limit = options[:limit].to_i offset = options[:offset].to_i skip_merges = options[:skip_merges] walker.sorting(Rugged::SORT_DATE) walker.each do |c| break if limit > 0 && commits.length >= limit if skip_merges # Skip merge commits next if c.parents.length > 1 end if !current_path || commit_touches_path?(c, current_path, options[:follow], walker) # This is a commit we care about, unless we haven't skipped enough # yet skipped += 1 commits.push(Gollum::Git::Commit.new(c)) if skipped > offset end end walker.reset commits end
commit_touches_path?(commit, path, follow, walker)
click to toggle source
Returns true if commit
introduced changes to path
, using commit trees to make that determination. Uses the history simplification rules that `git log` uses by default, where a commit is omitted if it is TREESAME to any parent.
If the follow
option is true and the file specified by path
was renamed, then the path value is set to the old path.
# File lib/rugged_adapter/git_layer_rugged.rb, line 352 def commit_touches_path?(commit, path, follow, walker) entry = tree_entry(commit, path) if commit.parents.empty? # This is the root commit, return true if it has +path+ in its tree return entry != nil end num_treesame = 0 commit.parents.each do |parent| parent_entry = tree_entry(parent, path) # Only follow the first TREESAME parent for merge commits if num_treesame > 0 walker.hide(parent) next end if entry.nil? && parent_entry.nil? num_treesame += 1 elsif entry && parent_entry && entry[:oid] == parent_entry[:oid] num_treesame += 1 end end case num_treesame when 0 detect_rename(commit, commit.parents.first, path) if follow true else false end end
detect_rename(commit, parent, path)
click to toggle source
Compare commit
and parent
for path
. If path
is a file and was renamed in commit
, then set path
to the old filename.
# File lib/rugged_adapter/git_layer_rugged.rb, line 404 def detect_rename(commit, parent, path) diff = parent.diff(commit, paths: [path], disable_pathspec_match: true) # If +path+ is a filename, not a directory, then we should only have # one delta. We don't need to follow renames for directories. return nil if diff.each_delta.count > 1 delta = diff.each_delta.first if delta.added? full_diff = parent.diff(commit) full_diff.find_similar! full_diff.each_delta do |full_delta| if full_delta.renamed? && path == full_delta.new_file[:path] # Look for the old path in ancestors path.replace(full_delta.old_file[:path]) end end end end
sha?(str)
click to toggle source
# File lib/rugged_adapter/git_layer_rugged.rb, line 307 def sha?(str) !!(str =~ /^[0-9a-f]{40}$/) end
tree_entry(commit, path)
click to toggle source
Find the entry for path
in the tree for commit
# File lib/rugged_adapter/git_layer_rugged.rb, line 386 def tree_entry(commit, path) pathname = Pathname.new(path) tmp_entry = nil pathname.each_filename do |dir| tmp_entry = if tmp_entry.nil? commit.tree[dir] else @repo.lookup(tmp_entry[:oid])[dir] end return nil unless tmp_entry end tmp_entry end