lib/gitrb/repository.rb in gitrb-0.1.3 vs lib/gitrb/repository.rb in gitrb-0.1.4
- old
+ new
@@ -31,10 +31,11 @@
@bare = options[:bare] || false
@branch = options[:branch] || 'master'
@logger = options[:logger] || Logger.new(nil)
@encoding = options[:encoding] || DEFAULT_ENCODING
@lock = {}
+ @transaction = Mutex.new
@path = options[:path]
@path.chomp!('/')
@path += '/.git' if !@bare
@@ -50,27 +51,39 @@
@bare
end
# Switch branch
def branch=(branch)
- @branch = branch
- load
+ raise 'Forbidden from within a transaction' if in_transaction?
+ @transaction.synchronize do
+ @branch = branch
+ load
+ end
end
# Has our repository been changed on disk?
def changed?
- head.nil? || head.id != read_head_id
+ !head || head.id != read_head_id
end
# Load the repository, if it has been changed on disk.
def refresh
load if changed?
end
+ # Clear cached objects
+ def clear
+ raise 'Forbidden from within a transaction' if in_transaction?
+ @transaction.synchronize do
+ @objects.clear
+ load
+ end
+ end
+
# Is there any transaction going on?
def in_transaction?
- @lock[Thread.current.object_id]
+ !!@lock[Thread.current.object_id]
end
# Diff
def diff(from, to, path = nil)
if from && !(Commit === from)
@@ -284,18 +297,10 @@
email = Etc.getlogin + '@' + `hostname -f`.chomp
end
User.new(name, email)
end
- def dup
- super.instance_eval do
- @objects = Trie.new
- load
- self
- end
- end
-
private
def check_git_version
version = git_version
raise "Invalid git version: #{version}" if version !~ /^git version ([\d\.]+)$/
@@ -325,10 +330,11 @@
# Start a transaction.
#
# Tries to get lock on lock file, load the this repository if
# has changed in the repository.
def start_transaction
+ @transaction.lock
file = File.open("#{head_path}.lock", 'w')
file.flock(File::LOCK_EX)
@lock[Thread.current.object_id] = file
refresh
end
@@ -347,21 +353,22 @@
# Release the lock file.
def finish_transaction
@lock[Thread.current.object_id].close rescue nil
@lock.delete(Thread.current.object_id)
File.unlink("#{head_path}.lock") rescue nil
+ @transaction.unlock
end
def get_type(id, expected)
object = get(id)
raise NotFound, "Wrong type #{object.type}, expected #{expected}" if object && object.type != expected
object
end
def load_packs
@packs = Trie.new
- @objects = Trie.new
+ @objects = 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 }
@@ -380,11 +387,11 @@
@root = @head.tree
else
@head = nil
@root = Tree.new(:repository => self)
end
- @logger.debug "gitrb: Reloaded, head is #{@head ? head.id : 'nil'}"
+ @logger.debug "gitrb: Reloaded, head is #{head ? head.id : 'nil'}"
end
# Returns the hash value of an object string.
def sha(str)
Digest::SHA1.hexdigest(str)[0, 40]
@@ -423,8 +430,7 @@
end
def legacy_loose_object?(buf)
buf[0].ord == 0x78 && ((buf[0].ord << 8) | buf[1].ord) % 31 == 0
end
-
end
end