Решение на Пета задача от Клара Кайралах

Обратно към всички решения

Към профила на Клара Кайралах

Резултати

  • 2 точки от тестове
  • 0 бонус точки
  • 2 точки общо
  • 9 успешни тест(а)
  • 21 неуспешни тест(а)

Код

require 'digest/sha1'
require 'date'
class Commit
def initialize(message, objects)
@message = message
@date = DateTime.now.strftime("%a %b %d %H:%M %Y %z")
@hash = Digest::SHA1.hexdigest(@date + @message)
@objects = objects
end
attr_reader :hash,:date,:message,:objects
end
class ReturnObject
def initialize(is_success, message, result)
@result = result
@success = is_success
@message = message
end
def message
@message
end
def success?
@success
end
def error?
! @success
end
def result
raise NoMethodError if ! @success
@result
end
end
class ObjectStore
def initialize
@add_history = {}
@object_for_remove = []
@current_branch = "master"
@branches_names = [@current_branch]
@branch_with_commits = {}
@branch_with_commits[@current_branch.to_sym] = {}
@count_times = 0
end
def add(name, object)
@add_history[name.to_sym] = object
ReturnObject.new(true, "Added #{ name } to stage.", object)
end
def check_if_there_is_nothing_to_commit(length,remove_length)
return ReturnObject.new(false,
"Nothing to commit, working directory clean.",
[]) if length == 0 and remove_length == 0
return ReturnObject.new(true,
message + "\n\t#{length2} objects changed",
[]) if remove_length > 0
end
def commit(message)
length, remove_length = @add_history.length, @object_for_remove.length
check_if_there_is_nothing_to_commit(length,remove_length)
@branch_with_commits[@current_branch.to_sym][message], @add_history =
Commit.new(message,@add_history), {}
ReturnObject.new(true,
message + "\n\t#{ length } objects changed",
@branch_with_commits[@current_branch.to_sym][message])
end
def remove(name)
@branch_with_commits[@current_branch.to_sym].each{ |commit_name,obj|
if obj.objects.has_key?(name.to_sym)
commit, current_branch = commit_name.to_sym, @current_branch.to_sym
@object_for_remove.push(@branch_with_commits[current_branch][commit])
return ReturnObject.new(true,
"Added #{ name } for removal.",
@object_for_remove)
end
}
ReturnObject.new(false, "Object #{ name } is not committed.", [])
end
def delete_commits_before_date(last_commit_date)
branch = @branch_with_commits[@current_branch.to_sym]
branch.each{ |key, value|
branch.delete(key) if value.date > last_commit_date }
end
def error
error_comit = Commit.new("Commit #{ commit_hash } does not exist.", [])
ReturnObject.new(false, error_comit.message, [])
end
def checkout(commit_hash)
last_commit_date = DateTime.new
branch = @branch_with_commits
branch[@current_branch.to_sym].each{ |key, value|
if commit_hash == value.hash
last_commit_date, current_branch = value.date, @current_branch.to_sym
delete_commits_before_date(last_commit_date)
return ReturnObject.new(true,
"HEAD is now at #{ value.hash }.",
@branch[current_branch][key.to_sym])
end
}
error
end
def branch
return @branches if @count_times != 0
@branches = Branch.new
@branches.set_branches(@branch_with_commits)
@count_times += 1
@branches
end
def self.init(&block)
new_repo = ObjectStore.new
if block_given?
new_repo.instance_eval &block
end
new_repo
end
def log
message = "Branch #{ @current_branch } does not have any commits yet."
branch, log_message = @branch_with_commits, ""
return ReturnObject.new(false,
message,
[]) if @branch[@current_branch.to_sym].empty?
@branch_with_commits[@current_branch.to_sym].each { |message, commit_object|
commit = "Commit #{ commit_object.hash }\nDate: #{ commit_object.date }" +
"\n\n\t#{ message }"
log_message << commit + "\n\n"
}
ReturnObject.new(true, log_message, [])
end
def head
branch = @branch_with_commits
message = "Branch #{ @current_branch } does not have any commits yet."
return ReturnObject.new(false,
message,
[]) if @branch[@current_branch.to_sym].empty?
message, result_object = @branch[@current_branch.to_sym].first
ReturnObject.new(true, message, result_object)
end
def get(name)
name = name.to_sym
@branch_with_commits[@current_branch.to_sym].each{ |commit_name, obj|
return ReturnObject.new(true,
"Found object #{ name }.",
obj.objects[name]) if obj.objects.has_key?(name)
}
ReturnObject.new(false, "Object #{ name } is not committed.", [])
end
end
class Branch < ObjectStore
def initialize
super
end
def set_branches(branches)
@branch_with_commits = branches
end
def create(branch_name)
return ReturnObject.new(false,
"Branch #{ branch_name } already exists.",
[]) if @branches_names.include?(branch_name)
current_branch, branch_name = @current_branch.to_sym, branch_name.to_sym
@branch_with_commits[branch_name] = @branch_with_commits[current_branch]
@branches_names.push(branch_name)
ReturnObject.new(true, "Created branch #{ branch_name }.", [])
end
def checkout(branch_name)
return ReturnObject.new(false,
"Branch #{ branch_name } already exists.",
[]) if ! @branches_names.include?(branch_name)
@current_branch = branch_name
ReturnObject.new(true, "Switched to branch #{branch_name}.", [])
end
def remove(branch_name)
return ReturnObject.new(false,
"Branch #{ branch_name } does not exist.",
[]) if ! @branches_names.include?(branch_name)
return ReturnObject.new(false,
"Cannot remove current branch.",
[]) if @current_branch == branch_name
@branches_names.delete(branch_name)
@branch_with_commits.delete(branch_name)
ReturnObject.new(true, "Removed branch #{ branch_name }.", [])
end
def list
new_branches_names = []
@branches_names.sort!.each{ |branch|
if @current_branch == branch
new_branches_names.push("* " + branch + "\n")
else
new_branches_names.push(" " + branch + "\n")
end
}
new_branches_names = new_branches_names.join("")
new_list = new_branches_names.slice(0,new_branches_names.length - 1)
ReturnObject.new(true,
new_list,
[])
end
end

Лог от изпълнението

.FFFF.FFFFFFFF..FFF..F...FFFFF

Failures:

  1) ObjectStore can commit objects
     Failure/Error: expect(repo.commit("So cool!")).to be_success("So cool!\n\t2 objects changed", repo.head.result)
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:153:in `head'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:30:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) ObjectStore cannot commit without changed objects
     Failure/Error: expect(repo.commit("So cool!!")).to be_error("Nothing to commit, working directory clean.")
       expected #<ReturnObject:0x007fea90800f70 @result=#<Commit:0x007fea90801380 @message="So cool!!", @date="Mon Jan 11 11:54 2016 +0200", @hash="1d49f4dc26c925b1c389968c8fd445ed6c6e7d54", @objects={}>, @success=true, @message="So cool!!\n\t0 objects changed"> to be error "Nothing to commit, working directory clean."
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:35:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) ObjectStore can remove objects
     Failure/Error: expect(repo.remove("object1")).to be_success("Added object1 for removal.", "content1")
       expected #<ReturnObject:0x007fea907ec1d8 @result=[nil], @success=true, @message="Added object1 for removal."> to be success "Added object1 for removal." and "content1"
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:43:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) ObjectStore can commit changes which include only removed objects
     Failure/Error: expect(repo.commit("Removed object2")).to be_success("Removed object2\n\t1 objects changed", repo.head.result)
     NameError:
       undefined local variable or method `message' for #<ObjectStore:0x007fea90480968>
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:65:in `check_if_there_is_nothing_to_commit'
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:71:in `commit'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:53:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) ObjectStore can show head
     Failure/Error: expect(repo.head).to be_success("There we go", last_commit)
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:153:in `head'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:69:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) ObjectStore cannot show head for empty repository
     Failure/Error: expect(repo.head).to be_error("Branch master does not have any commits yet.")
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:153:in `head'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:74:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  7) ObjectStore can show log of changes for a single commit
     Failure/Error: commit_hash = Digest::SHA1.hexdigest("#{commit.date.strftime("%a %b %d %H:%M %Y %z")}#{commit.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:54 2016 +0200":String
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:82:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  8) ObjectStore can show log of changes for a single commit
     Failure/Error: commit_hash = Digest::SHA1.hexdigest("#{commit.date.strftime("%a %b %d %H:%M %Y %z")}#{commit.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:54 2016 +0200":String
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:91:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  9) ObjectStore can show log of changes for multiple commits
     Failure/Error: commit1_hash = Digest::SHA1.hexdigest("#{commit1.date.strftime(time_format)}#{commit1.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:54 2016 +0200":String
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:105:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  10) ObjectStore shows the log for the current branch only
     Failure/Error: commit1_hash = Digest::SHA1.hexdigest("#{commit1.date.strftime(time_format)}#{commit1.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:54 2016 +0200":String
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:126:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  11) ObjectStore cannot show log for empty repository
     Failure/Error: expect(repo.log).to be_error("Branch master does not have any commits yet.")
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:139:in `log'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:133:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  12) ObjectStore can list branches
     Failure/Error: expect(repo.branch.list).to be_success("  develop\n  feature\n* master")
     ArgumentError:
       comparison of String with Symbol failed
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:212:in `sort!'
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:212:in `list'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:140:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  13) ObjectStore can switch branches
     Failure/Error: expect(repo.branch.checkout("develop")).to be_success("Switched to branch develop.")
       expected #<ReturnObject:0x007fea9037f0a0 @result=[], @success=false, @message="Branch develop already exists."> to be success "Switched to branch develop."
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:158:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  14) ObjectStore cannot switch to nonexisting branch
     Failure/Error: expect(repo.branch.checkout("develop")).to be_error("Branch develop does not exist.")
       expected #<ReturnObject:0x007fea90372aa8 @result=[], @success=false, @message="Branch develop already exists."> to be error "Branch develop does not exist."
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:168:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  15) ObjectStore can remove branch
     Failure/Error: expect(repo.branch.remove("develop")).to be_success("Removed branch develop.")
       expected #<ReturnObject:0x007fea902e6bc0 @result=[], @success=false, @message="Branch develop does not exist."> to be success "Removed branch develop."
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:174:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  16) ObjectStore can be initialized with block
     Failure/Error: expect(repo.head).to be_success("Second commit", $second_commit)
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:153:in `head'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:195:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  17) ObjectStore can checkout commits
     Failure/Error: expect(repo.checkout(first_commit.hash)).to be_success("HEAD is now at #{first_commit.hash}.", first_commit)
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:112:in `block in checkout'
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:106:in `each'
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:106:in `checkout'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:223:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  18) ObjectStore cannot checkout commits with nonexisting hashes
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NameError:
       undefined local variable or method `commit_hash' for #<ObjectStore:0x007fea9007fdc8>
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:99:in `error'
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:115:in `checkout'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:231:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  19) ObjectStore cannot checkout commits in empty repository
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NameError:
       undefined local variable or method `commit_hash' for #<ObjectStore:0x007fea90073e38>
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:99:in `error'
     # /tmp/d20160111-5693-1n3nrt7/solution.rb:115:in `checkout'
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:236:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  20) ObjectStore can show the objects in a repo after overwriting an object
     Failure/Error: expect(first_commit.objects).to match_array(["content1"])
       expected an array, actual collection was {:object1=>"content1"}
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:243:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  21) ObjectStore can show the objects of a repo after removing an object
     Failure/Error: expect(first_commit.objects).to match_array(["content1", "content2", "content3"])
       expected an array, actual collection was {:object1=>"content1", :object2=>"content2", :object3=>"content3"}
     # /tmp/d20160111-5693-1n3nrt7/spec.rb:259:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.02677 seconds
30 examples, 21 failures

Failed examples:

rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:26 # ObjectStore can commit objects
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:33 # ObjectStore cannot commit without changed objects
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:38 # ObjectStore can remove objects
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:46 # ObjectStore can commit changes which include only removed objects
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:63 # ObjectStore can show head
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:72 # ObjectStore cannot show head for empty repository
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:131 # ObjectStore cannot show log for empty repository
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:136 # ObjectStore can list branches
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:153 # ObjectStore can switch branches
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:166 # ObjectStore cannot switch to nonexisting branch
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:171 # ObjectStore can remove branch
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:187 # ObjectStore can be initialized with block
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:217 # ObjectStore can checkout commits
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:227 # ObjectStore cannot checkout commits with nonexisting hashes
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:234 # ObjectStore cannot checkout commits in empty repository
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:239 # ObjectStore can show the objects in a repo after overwriting an object
rspec /tmp/d20160111-5693-1n3nrt7/spec.rb:253 # ObjectStore can show the objects of a repo after removing an object

История (1 версия и 0 коментара)

Клара обнови решението на 23.11.2015 08:37 (преди над 8 години)

+require 'digest/sha1'
+require 'date'
+
+class Commit
+
+ def initialize(message, objects)
+ @message = message
+ @date = DateTime.now.strftime("%a %b %d %H:%M %Y %z")
+ @hash = Digest::SHA1.hexdigest(@date + @message)
+ @objects = objects
+ end
+
+ attr_reader :hash,:date,:message,:objects
+
+end
+
+class ReturnObject
+
+ def initialize(is_success, message, result)
+ @result = result
+ @success = is_success
+ @message = message
+ end
+
+ def message
+ @message
+ end
+
+ def success?
+ @success
+ end
+
+ def error?
+ ! @success
+ end
+
+ def result
+ raise NoMethodError if ! @success
+ @result
+ end
+end
+
+class ObjectStore
+
+ def initialize
+ @add_history = {}
+ @object_for_remove = []
+ @current_branch = "master"
+ @branches_names = [@current_branch]
+ @branch_with_commits = {}
+ @branch_with_commits[@current_branch.to_sym] = {}
+ @count_times = 0
+ end
+
+ def add(name, object)
+ @add_history[name.to_sym] = object
+ ReturnObject.new(true, "Added #{ name } to stage.", object)
+ end
+
+ def check_if_there_is_nothing_to_commit(length,remove_length)
+ return ReturnObject.new(false,
+ "Nothing to commit, working directory clean.",
+ []) if length == 0 and remove_length == 0
+ return ReturnObject.new(true,
+ message + "\n\t#{length2} objects changed",
+ []) if remove_length > 0
+ end
+
+ def commit(message)
+ length, remove_length = @add_history.length, @object_for_remove.length
+ check_if_there_is_nothing_to_commit(length,remove_length)
+ @branch_with_commits[@current_branch.to_sym][message], @add_history =
+ Commit.new(message,@add_history), {}
+ ReturnObject.new(true,
+ message + "\n\t#{ length } objects changed",
+ @branch_with_commits[@current_branch.to_sym][message])
+ end
+
+ def remove(name)
+ @branch_with_commits[@current_branch.to_sym].each{ |commit_name,obj|
+ if obj.objects.has_key?(name.to_sym)
+ commit, current_branch = commit_name.to_sym, @current_branch.to_sym
+ @object_for_remove.push(@branch_with_commits[current_branch][commit])
+ return ReturnObject.new(true,
+ "Added #{ name } for removal.",
+ @object_for_remove)
+ end
+ }
+ ReturnObject.new(false, "Object #{ name } is not committed.", [])
+ end
+
+ def delete_commits_before_date(last_commit_date)
+ branch = @branch_with_commits[@current_branch.to_sym]
+ branch.each{ |key, value|
+ branch.delete(key) if value.date > last_commit_date }
+ end
+
+ def error
+ error_comit = Commit.new("Commit #{ commit_hash } does not exist.", [])
+ ReturnObject.new(false, error_comit.message, [])
+ end
+
+ def checkout(commit_hash)
+ last_commit_date = DateTime.new
+ branch = @branch_with_commits
+ branch[@current_branch.to_sym].each{ |key, value|
+ if commit_hash == value.hash
+ last_commit_date, current_branch = value.date, @current_branch.to_sym
+ delete_commits_before_date(last_commit_date)
+ return ReturnObject.new(true,
+ "HEAD is now at #{ value.hash }.",
+ @branch[current_branch][key.to_sym])
+ end
+ }
+ error
+ end
+
+ def branch
+ return @branches if @count_times != 0
+ @branches = Branch.new
+ @branches.set_branches(@branch_with_commits)
+ @count_times += 1
+ @branches
+ end
+
+ def self.init(&block)
+ new_repo = ObjectStore.new
+ if block_given?
+ new_repo.instance_eval &block
+ end
+ new_repo
+ end
+
+ def log
+ message = "Branch #{ @current_branch } does not have any commits yet."
+ branch, log_message = @branch_with_commits, ""
+ return ReturnObject.new(false,
+ message,
+ []) if @branch[@current_branch.to_sym].empty?
+ @branch_with_commits[@current_branch.to_sym].each { |message, commit_object|
+ commit = "Commit #{ commit_object.hash }\nDate: #{ commit_object.date }" +
+ "\n\n\t#{ message }"
+ log_message << commit + "\n\n"
+ }
+ ReturnObject.new(true, log_message, [])
+ end
+
+ def head
+ branch = @branch_with_commits
+ message = "Branch #{ @current_branch } does not have any commits yet."
+ return ReturnObject.new(false,
+ message,
+ []) if @branch[@current_branch.to_sym].empty?
+ message, result_object = @branch[@current_branch.to_sym].first
+ ReturnObject.new(true, message, result_object)
+ end
+
+ def get(name)
+ name = name.to_sym
+ @branch_with_commits[@current_branch.to_sym].each{ |commit_name, obj|
+ return ReturnObject.new(true,
+ "Found object #{ name }.",
+ obj.objects[name]) if obj.objects.has_key?(name)
+ }
+ ReturnObject.new(false, "Object #{ name } is not committed.", [])
+ end
+end
+
+class Branch < ObjectStore
+
+ def initialize
+ super
+ end
+
+ def set_branches(branches)
+ @branch_with_commits = branches
+ end
+
+ def create(branch_name)
+ return ReturnObject.new(false,
+ "Branch #{ branch_name } already exists.",
+ []) if @branches_names.include?(branch_name)
+ current_branch, branch_name = @current_branch.to_sym, branch_name.to_sym
+ @branch_with_commits[branch_name] = @branch_with_commits[current_branch]
+ @branches_names.push(branch_name)
+ ReturnObject.new(true, "Created branch #{ branch_name }.", [])
+ end
+
+ def checkout(branch_name)
+ return ReturnObject.new(false,
+ "Branch #{ branch_name } already exists.",
+ []) if ! @branches_names.include?(branch_name)
+ @current_branch = branch_name
+ ReturnObject.new(true, "Switched to branch #{branch_name}.", [])
+ end
+
+ def remove(branch_name)
+ return ReturnObject.new(false,
+ "Branch #{ branch_name } does not exist.",
+ []) if ! @branches_names.include?(branch_name)
+
+ return ReturnObject.new(false,
+ "Cannot remove current branch.",
+ []) if @current_branch == branch_name
+ @branches_names.delete(branch_name)
+ @branch_with_commits.delete(branch_name)
+ ReturnObject.new(true, "Removed branch #{ branch_name }.", [])
+ end
+
+ def list
+ new_branches_names = []
+ @branches_names.sort!.each{ |branch|
+ if @current_branch == branch
+ new_branches_names.push("* " + branch + "\n")
+ else
+ new_branches_names.push(" " + branch + "\n")
+ end
+ }
+ new_branches_names = new_branches_names.join("")
+ new_list = new_branches_names.slice(0,new_branches_names.length - 1)
+ ReturnObject.new(true,
+ new_list,
+ [])
+ end
+ end