lib/gitrb/repository.rb in gitrb-0.1.5 vs lib/gitrb/repository.rb in gitrb-0.1.6
- old
+ new
@@ -81,20 +81,30 @@
def in_transaction?
!!@lock[Thread.current.object_id]
end
# Diff
- def diff(from, to, path = nil)
+ # Options:
+ # :to - Required target commit
+ # :from - Optional source commit (otherwise comparision with empty tree)
+ # :path - Restrict to path
+ # :detect_renames - Detect renames O(n^2)
+ # :detect_copies - Detect copies O(n^2), very slow
+ def diff(opts)
+ from, to = opts[:from], opts[:to]
if from && !(Commit === from)
raise ArgumentError, "Invalid sha: #{from}" if from !~ SHA_PATTERN
from = Reference.new(:repository => self, :id => from)
end
if !(Commit === to)
raise ArgumentError, "Invalid sha: #{to}" if to !~ SHA_PATTERN
to = Reference.new(:repository => self, :id => to)
end
- Diff.new(from, to, git_diff_tree('--root', '-u', '--full-index', from && from.id, to.id, '--', path))
+ Diff.new(from, to, git_diff_tree('--root', '--full-index', '-u',
+ opts[:detect_renames] ? '-M' : nil,
+ opts[:detect_copies] ? '-C' : nil,
+ from ? from.id : nil, to.id, '--', opts[:path]))
end
# All changes made inside a transaction are atomic. If some
# exception occurs the transaction will be rolled back.
#
@@ -143,16 +153,15 @@
# Returns a list of commits starting from head commit.
def log(limit = 10, start = nil, path = nil)
limit = limit.to_s
start = start.to_s
+ path = path.to_s
raise ArgumentError, "Invalid limit: #{limit}" if limit !~ /^\d+$/
raise ArgumentError, "Invalid commit: #{start}" if start =~ /^\-/
- args = ['--pretty=tformat:%H%n%P%n%T%n%an%n%ae%n%at%n%cn%n%ce%n%ct%n%x00%s%n%b%x00', "-#{limit}" ]
- args << start if !start.empty?
- args << '--' << path if path && !path.empty?
- log = git_log(*args).split(/\n*\x00\n*/)
+ log = git_log('--pretty=tformat:%H%n%P%n%T%n%an%n%ae%n%at%n%cn%n%ce%n%ct%n%x00%s%n%b%x00',
+ "-#{limit}", start.empty? ? nil : start, '--', path.empty? ? nil : path).split(/\n*\x00\n*/)
commits = []
log.each_slice(2) do |data, message|
data = data.split("\n")
parents = data[1].empty? ? nil : data[1].split(' ').map {|id| Reference.new(:repository => self, :id => id) }
commits << Commit.new(:repository => self,
@@ -174,19 +183,24 @@
# Returns a tree, blob, commit or tag object.
def get(id)
raise ArgumentError, 'No id given' if !(String === id)
if id =~ SHA_PATTERN
- raise NotFound, "Sha too short: #{id}" if id.length < 5
- list = @objects.find(id).to_a
- raise NotFound, "Sha is ambiguous: #{id}" if list.size > 1
- return list.first if list.size == 1
+ raise ArgumentError, "Sha too short: #{id}" if id.length < 5
+
+ trie = @objects.find(id)
+ raise NotFound, "Sha is ambiguous: #{id}" if trie.size > 1
+ return trie.value if !trie.empty?
elsif id =~ REVISION_PATTERN
list = git_rev_parse(id).split("\n") rescue nil
raise NotFound, "Revision not found: #{id}" if !list || list.empty?
raise NotFound, "Revision is ambiguous: #{id}" if list.size > 1
id = list.first
+
+ trie = @objects.find(id)
+ raise NotFound, "Sha is ambiguous: #{id}" if trie.size > 1
+ return trie.value if !trie.empty?
end
@logger.debug "gitrb: Loading #{id}"
path = object_path(id)
@@ -205,18 +219,14 @@
type, size = header.split(' ', 2)
raise NotFound, "Bad object: #{id}" if content.length != size.to_i
else
trie = @packs.find(id)
- raise NotFound, "Object not found: #{id}" if !trie
-
- id += trie.key[-(41 - id.length)...-1]
-
- list = trie.to_a
- raise NotFound, "Sha is ambiguous: #{id}" if list.size > 1
-
- pack, offset = list.first
+ raise NotFound, "Object not found: #{id}" if trie.empty?
+ raise NotFound, "Sha is ambiguous: #{id}" if trie.size > 1
+ id = trie.key
+ pack, offset = trie.value
content, type = pack.get_object(offset)
end
@logger.debug "gitrb: Loaded #{id}"
@@ -363,10 +373,10 @@
object
end
def load_packs
@packs = Trie.new
- @objects = Synchronized.new(Trie.new)
+ @objects = Util::Synchronized.new(Trie.new)
packs_path = "#{@path}/objects/pack"
if File.directory?(packs_path)
Dir.open(packs_path) do |dir|
entries = dir.select { |entry| entry =~ /\.pack$/i }