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