class Au::Repository
Attributes
current[R]
singleton class
head[R]
singleton class
path[R]
singleton class
root[R]
singleton class
Public Class Methods
diff(file_path)
click to toggle source
# File lib/au/models/repository.rb, line 20 def self.diff(file_path) return nil unless head tracked_version = head.cat(file_path) return nil unless tracked_version `diff -c #{tracked_version.path} #{File.join(root, file_path)}` end
head(path = nil)
click to toggle source
# File lib/au/models/repository.rb, line 16 def self.head(path = nil) Commit.find instance(path, false).head end
instance(path = nil, create = false)
click to toggle source
# File lib/au/models/repository.rb, line 27 def self.instance(path = nil, create = false) return @single_instance unless @single_instance.nil? begin @single_instance = new(path, create) rescue Kernel.abort("Fetal error: Repository not found. ") end end
new(path, create = false)
click to toggle source
# File lib/au/models/repository.rb, line 36 def initialize(path, create = false) if path.nil? working_dir = Dir.pwd # little bit different with mercurial 0.1 # here we only check whether the current working directory is a repository if not File.directory?(File.join(working_dir, '.au')) and not create raise 'Repository not found in ' + working_dir end path = working_dir end @root = path @path = File.join(path, '.au') Dir.mkdir(@path) if create && !File.directory?(@path) @head_pstore = PStore.new(File.join(@path, 'head.pstore')) update_head_var @alt_pstore = PStore.new(File.join(@path, 'alt.pstore')) update_alt_list @leaves_pstore = PStore.new(File.join(@path, 'leaves.pstore')) end
path(path = nil)
click to toggle source
# File lib/au/models/repository.rb, line 12 def self.path(path = nil) instance(path, false).path end
root(path = nil)
click to toggle source
# File lib/au/models/repository.rb, line 8 def self.root(path = nil) instance(path, false).root end
Private Class Methods
resolve_conflict_fname()
click to toggle source
# File lib/au/models/repository.rb, line 259 def self.resolve_conflict_fname File.join(Repository.instance.path, 'resolve_conflict') end
Public Instance Methods
checkout(commit_id)
click to toggle source
# File lib/au/models/repository.rb, line 88 def checkout(commit_id) this_commit = Commit.find(commit_id) if this_commit this_commit.checkout(update_head_var) update_alt_pstore(update_head_var) update_head_pstore(commit_id) update_head_var end end
commit(commit_message)
click to toggle source
# File lib/au/models/repository.rb, line 71 def commit(commit_message) staged_file_paths = Staging.staged_file_paths return if staged_file_paths.empty? commit_created_id = if File.exist?(Repository.resolve_conflict_fname) parent_id1, parent_id2 = File.read(Repository.resolve_conflict_fname).split(',') File.delete(Repository.resolve_conflict_fname) Commit.create_commit_resolve_conflict(staged_file_paths, parent_id1, parent_id2) else Commit.create(staged_file_paths, commit_message, @head) end update_head_pstore(commit_created_id) update_leaves_pstore(commit_created_id) Staging.clear_staged_file_paths commit_created_id end
heads()
click to toggle source
def clone
end
# File lib/au/models/repository.rb, line 211 def heads @leaves_pstore.transaction(true) do @leaves_pstore.roots end end
merge(commit_to_merge)
click to toggle source
# File lib/au/models/repository.rb, line 63 def merge(commit_to_merge) commit_id = Commit.merge(@head, commit_to_merge) return nil if commit_id.nil? # checkout to new commit checkout(commit_id) commit_id end
pull(remote_repo)
click to toggle source
# File lib/au/models/repository.rb, line 98 def pull(remote_repo) # Initialize local and remote db and commit list remote_commit_db = Commit.db(remote_repo.path) remote_commit_list = remote_commit_db.transaction do remote_commit_db.roots end local_commit_db = Commit.db local_commit_list = local_commit_db.transaction do local_commit_db.roots end # Check if the root commits are the same if local_commit_list[0] != remote_commit_list[0] raise "Error: Root commits do not match." end # Find commits that only exist on remote repo commit_id_to_add_list = remote_commit_list.reject{|x| local_commit_list.include?(x)} commits_to_add = {} remote_commit_db.transaction(true) do commit_id_to_add_list.each{|commit_id| commits_to_add[commit_id] = remote_commit_db[commit_id]} end # Write those commits to local commit db local_commit_db.transaction do commits_to_add.each{|commit_id, data| local_commit_db[commit_id] = data} end # Find documents and their diff_id in those commits that only existed remotely remote_diff_id_to_add_list = {} commits_to_add.each do |_, commit| commit[:doc_diff_ids].each do |doc_path, diff_id| remote_diff_id_to_add_list[doc_path] = diff_id end end # Write these information to local remote_diff_id_to_add_list.each do |doc_path, diff_id| diff_pstore_remote = PStore.new(diff_db_name_remote(doc_path, remote_repo.path)) diff_pstore_remote.transaction(true) do diff_pstore_local = PStore.new(diff_db_name_remote(doc_path, @path)) diff_pstore_local.transaction do if diff_pstore_local[diff_id] == nil diff_pstore_local[diff_id] = diff_pstore_remote[diff_id] elsif diff_pstore_local[diff_id] != diff_pstore_remote[diff_id] raise "Error: Remote and local reposiroty have different content in a same diff" end end end end # Find heads that only exist on remote repo heads_to_add = remote_repo.heads.reject{|x| heads.include?(x)} heads_to_add.each{|x| update_leaves_pstore(x)} end
push(remote_repo)
click to toggle source
# File lib/au/models/repository.rb, line 153 def push(remote_repo) # Initialize local and remote db and commit list remote_commit_db = Commit.db(remote_repo.path) remote_commit_list = remote_commit_db.transaction do remote_commit_db.roots end local_commit_db = Commit.db local_commit_list = local_commit_db.transaction do local_commit_db.roots end # Check if the root commits are the same if local_commit_list[0] != remote_commit_list[0] raise "Error: Root commits do not match." end # Find commits that only exist locally commit_id_to_add_list = local_commit_list.reject{|x| remote_commit_list.include?(x)} commits_to_add = {} local_commit_db.transaction(true) do commit_id_to_add_list.each{|commit_id| commits_to_add[commit_id] = local_commit_db[commit_id]} end # Write those commits to remote commit db remote_commit_db.transaction do commits_to_add.each{|commit_id, data| remote_commit_db[commit_id] = data} end # Find documents and their diff_id in those commits that only existed locally local_diff_id_to_add_list = {} commits_to_add.each do |_, commit| commit[:doc_diff_ids].each do |doc_path, diff_id| local_diff_id_to_add_list[doc_path] = diff_id end end # Write these information to remote local_diff_id_to_add_list.each do |doc_path, diff_id| diff_pstore_local = PStore.new(diff_db_name_remote(doc_path, @path)) diff_pstore_local.transaction(true) do diff_pstore_remote = PStore.new(diff_db_name_remote(doc_path, remote_repo.path)) diff_pstore_remote.transaction do if diff_pstore_remote[diff_id] == nil diff_pstore_remote[diff_id] = diff_pstore_local[diff_id] elsif diff_pstore_local[diff_id] != diff_pstore_remote[diff_id] raise "Error: Remote and local reposiroty have different content in a same diff" end end end end # Find heads that only exist on remote repo heads_to_add = heads.reject{|x| remote_repo.heads.include?(x)} heads_to_add.each{|x| remote_repo.update_leaves_pstore(x)} end
update_head_var()
click to toggle source
# File lib/au/models/repository.rb, line 217 def update_head_var @head = @head_pstore.transaction(true) do @head_pstore[:head] end end
update_leaves_pstore(commit_id)
click to toggle source
# File lib/au/models/repository.rb, line 223 def update_leaves_pstore(commit_id) @leaves_pstore.transaction do commit = Commit.find(commit_id) if commit parent_commit_id_1, parent_commit_id_2 = commit.parent_id_1, commit.parent_id_2 @leaves_pstore.delete(parent_commit_id_1) @leaves_pstore.delete(parent_commit_id_2) @leaves_pstore[commit_id] = 1 end end end
Private Instance Methods
diff_db_name_remote(file_path, remote_path)
click to toggle source
# File lib/au/models/repository.rb, line 236 def diff_db_name_remote(file_path, remote_path) paths = [remote_path, "diff_#{file_path.gsub('/', '.')}.pstore"].compact File.join(*paths) end
update_alt_list()
click to toggle source
# File lib/au/models/repository.rb, line 247 def update_alt_list @alt_list = @alt_pstore.transaction(true) do @alt_pstore[:commit] end end
update_alt_pstore(commit_id)
click to toggle source
# File lib/au/models/repository.rb, line 253 def update_alt_pstore(commit_id) @alt_pstore.transaction do @alt_pstore[:commit].nil? ? (@alt_pstore[:commit] = [commit_id]) : (@alt_pstore[:commit] << commit_id) end end
update_head_pstore(commit_id)
click to toggle source
# File lib/au/models/repository.rb, line 241 def update_head_pstore(commit_id) @head = @head_pstore.transaction do @head_pstore[:head] = commit_id end end