Решение на Пета задача от Милена Дренска

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

Към профила на Милена Дренска

Резултати

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

Код

require 'digest/sha1'
class OperationStatus
def initialize(is_successfull, message, result = nil)
@success = is_successfull
@message = message
@result = result
end
end
class ObjectStore
attr_reader :branch, :stage
def initialize
@stage = {}
@branch = Branch.new
@head_index = -1
end
def self.init
new_repo = self.new
new_repo.instance_eval(&Proc.new) if block_given?
return new_repo
end
def add(name, object)
@stage[name] = object
OperationStatus.new(true, "Added #{name} to stage.", object)
end
def commit(message)
count = @stage.length
if count == 0
OperationStatus.new(false, "Nothing to commit, working directory clean.")
else
@branch.add_commit(Commit.new(message, @stage))
@stage = {}
OperationStatus.new(true, "#{message}\n\t#{count} objects changed")
end
end
def head
@branch.get_all_commits[@head_index]
end
def log
commit_list = ""
@branch.get_all_commits.each do |commit|
commit_list += "Commit #{commit.hash}\nDate: #{commit.date}\n\n"
commit_list += "\t#{commit.message}\n\n"
end
return commit_list.strip
end
end
class Branch
attr_reader :current, :branches, :checkout
def initialize
@branches = {'master' => {'parent' => nil, 'commits' => []}}
@current = 'master'
end
def create(name)
if @branches[name] == nil
@branches[name] = {}
@branches[name]['commits'] = @branches[@current]['commits'].dup
OperationStatus.new(true, "Created branch #{name}.")
else
OperationStatus.new(false, "Branch #{name} already exists.")
end
end
def checkout(name)
if @branches[name] != nil
@current = name
OperationStatus.new(true, "Switched to branch #{name}.")
else
OperationStatus.new(false, "Branch #{name} does not exist.")
end
end
def remove(name)
if name == @current
OperationStatus.new(false, "Cannot remove current branch.")
elsif @branches[name] != nil
@branches.delete(name)
OperationStatus.new(true, "Removed branch #{name}.")
else
OperationStatus.new(false, "Branch #{name} does not exist.")
end
end
def list
list = ""
@branches.each do |name, val|
prefix = @current == name ? '* ' : ' '
list += "#{prefix}#{name}\n"
end
return list
end
def add_commit(new_commit)
@branches[@current]['commits'] << new_commit
end
def get_all_commits
@branches[@current]['commits'].reverse
end
def find(hash)
result = @branches[@current]['commits'].select do |commit|
commit.instance_eval{ hash } == hash
end
return result.length == 0 ? nil : result[0]
end
end
class Commit
attr_reader :message, :objects, :date, :hash
def initialize(message, changes)
@message, @objects = message, changes
@date = Time.now.strftime("%a %b %e %H:%M %Y %z")
@hash = Digest::SHA1.hexdigest("#{@date}#{@message}")
end
end

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

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Failures:

  1) ObjectStore can add objects
     Failure/Error: actual.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042abc6990>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:6:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/spec.rb:23: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 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 `result' for #<Commit:0x007f042abbc6c0>
     # /tmp/d20160111-5693-hnsfm3/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)>'

  3) ObjectStore cannot commit without changed objects
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042abb7be8>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/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)>'

  4) ObjectStore can remove objects
     Failure/Error: expect(repo.remove("object1")).to be_success("Added object1 for removal.", "content1")
     NoMethodError:
       undefined method `remove' for #<ObjectStore:0x007f042abac770>
     # /tmp/d20160111-5693-hnsfm3/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)>'

  5) ObjectStore can commit changes which include only removed objects
     Failure/Error: repo.remove("object2")
     NoMethodError:
       undefined method `remove' for #<ObjectStore:0x007f042abaa240>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:52: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 remove objects that are not committed
     Failure/Error: expect(repo.remove("object2")).to be_error("Object object2 is not committed.")
     NoMethodError:
       undefined method `remove' for #<ObjectStore:0x007f042aba2f90>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:60: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 head
     Failure/Error: last_commit = repo.commit("There we go").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042ab9bba0>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:68: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 cannot show head for empty repository
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for nil:NilClass
     # /tmp/d20160111-5693-hnsfm3/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/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)>'

  9) ObjectStore can show log of changes for a single commit
     Failure/Error: commit = repo.commit("So cool!").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a81b548>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:81: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 can show log of changes for a single commit
     Failure/Error: commit = repo.commit("So cool!").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a814928>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:90: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 can show log of changes for multiple commits
     Failure/Error: commit1 = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a611180>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:98: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 shows the log for the current branch only
     Failure/Error: commit1 = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a7fc030>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:114: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 cannot show log for empty repository
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for "":String
     # /tmp/d20160111-5693-hnsfm3/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/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)>'

  14) ObjectStore can list branches
     Failure/Error: actual.message == message &&
     NoMethodError:
       undefined method `message' for "* master\n  develop\n  feature\n":String
     # /tmp/d20160111-5693-hnsfm3/spec.rb:6:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/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)>'

  15) ObjectStore can create branches
     Failure/Error: actual.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042a7aad70>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:6:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/spec.rb:145: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 cannot create branch if already exists
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042a792ef0>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/spec.rb:150: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 switch branches
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a7806d8>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:156: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 switch to nonexisting branch
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042a759b00>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/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)>'

  19) ObjectStore can remove branch
     Failure/Error: actual.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042a729e50>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:6:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/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)>'

  20) ObjectStore cannot remove current branch
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042a710ef0>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/spec.rb:179: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 cannot remove nonexisting branch
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for #<OperationStatus:0x007f042a708660>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/spec.rb:184: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)>'

  22) ObjectStore can be initialized with block
     Failure/Error: $second_commit = commit("Second commit").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a664920>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:193:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-hnsfm3/solution.rb:22:in `instance_eval'
     # /tmp/d20160111-5693-hnsfm3/solution.rb:22:in `init'
     # /tmp/d20160111-5693-hnsfm3/spec.rb:188: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)>'

  23) ObjectStore can return objects
     Failure/Error: expect(repo.get("number")).to be_success("Found object number.", 21)
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007f042a659f98>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:202: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)>'

  24) ObjectStore cannot return not committed objects
     Failure/Error: expect(repo.get("string")).to be_error("Object string is not committed.")
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007f042a64e738>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:209: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)>'

  25) ObjectStore cannot return objects when no commits
     Failure/Error: expect(repo.get("string")).to be_error("Object string is not committed.")
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007f042a642460>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:214: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)>'

  26) ObjectStore can checkout commits
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a620680>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:220: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)>'

  27) ObjectStore cannot checkout commits with nonexisting hashes
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NoMethodError:
       undefined method `checkout' for #<ObjectStore:0x007f042a5f5e80>
     # /tmp/d20160111-5693-hnsfm3/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)>'

  28) ObjectStore cannot checkout commits in empty repository
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NoMethodError:
       undefined method `checkout' for #<ObjectStore:0x007f042a43aa78>
     # /tmp/d20160111-5693-hnsfm3/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)>'

  29) ObjectStore can show the objects in a repo after overwriting an object
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a434380>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:242: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)>'

  30) ObjectStore can show the objects of a repo after removing an object
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<OperationStatus:0x007f042a42a998>
     # /tmp/d20160111-5693-hnsfm3/spec.rb:258: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.01807 seconds
30 examples, 30 failures

Failed examples:

rspec /tmp/d20160111-5693-hnsfm3/spec.rb:21 # ObjectStore can add objects
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:26 # ObjectStore can commit objects
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:33 # ObjectStore cannot commit without changed objects
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:38 # ObjectStore can remove objects
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:46 # ObjectStore can commit changes which include only removed objects
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:56 # ObjectStore cannot remove objects that are not committed
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:63 # ObjectStore can show head
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:72 # ObjectStore cannot show head for empty repository
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:131 # ObjectStore cannot show log for empty repository
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:136 # ObjectStore can list branches
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:143 # ObjectStore can create branches
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:148 # ObjectStore cannot create branch if already exists
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:153 # ObjectStore can switch branches
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:166 # ObjectStore cannot switch to nonexisting branch
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:171 # ObjectStore can remove branch
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:177 # ObjectStore cannot remove current branch
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:182 # ObjectStore cannot remove nonexisting branch
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:187 # ObjectStore can be initialized with block
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:198 # ObjectStore can return objects
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:205 # ObjectStore cannot return not committed objects
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:212 # ObjectStore cannot return objects when no commits
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:217 # ObjectStore can checkout commits
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:227 # ObjectStore cannot checkout commits with nonexisting hashes
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:234 # ObjectStore cannot checkout commits in empty repository
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:239 # ObjectStore can show the objects in a repo after overwriting an object
rspec /tmp/d20160111-5693-hnsfm3/spec.rb:253 # ObjectStore can show the objects of a repo after removing an object

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

Милена обнови решението на 22.11.2015 19:55 (преди над 8 години)

+require 'digest/sha1'
+
+class OperationStatus
+ def initialize(is_successfull, message, result = nil)
+ @success = is_successfull
+ @message = message
+ @result = result
+ end
+end
+
+class ObjectStore
+ attr_reader :branch, :stage
+
+ def initialize
+ @stage = {}
+ @branch = Branch.new
+ @head_index = -1
+ end
+
+ def self.init
+ new_repo = self.new
+ new_repo.instance_eval(&Proc.new) if block_given?
+ return new_repo
+ end
+
+ def add(name, object)
+ @stage[name] = object
+ OperationStatus.new(true, "Added #{name} to stage.", object)
+ end
+
+ def commit(message)
+ count = @stage.length
+ if count == 0
+ OperationStatus.new(false, "Nothing to commit, working directory clean.")
+ else
+ @branch.add_commit(Commit.new(message, @stage))
+ @stage = {}
+ OperationStatus.new(true, "#{message}\n\t#{count} objects changed")
+ end
+ end
+
+ def head
+ @branch.get_all_commits[@head_index]
+ end
+
+ def log
+ commit_list = ""
+ @branch.get_all_commits.each do |commit|
+ commit_list += "Commit #{commit.hash}\nDate: #{commit.date}\n\n"
+ commit_list += "\t#{commit.message}\n\n"
+ end
+ return commit_list.strip
+
+ end
+
+end
+
+class Branch
+ attr_reader :current, :branches, :checkout
+
+ def initialize
+ @branches = {'master' => {'parent' => nil, 'commits' => []}}
+ @current = 'master'
+ end
+
+ def create(name)
+ if @branches[name] == nil
+ @branches[name] = {}
+ @branches[name]['commits'] = @branches[@current]['commits'].dup
+ OperationStatus.new(true, "Created branch #{name}.")
+ else
+ OperationStatus.new(false, "Branch #{name} already exists.")
+ end
+ end
+
+ def checkout(name)
+ if @branches[name] != nil
+ @current = name
+ OperationStatus.new(true, "Switched to branch #{name}.")
+ else
+ OperationStatus.new(false, "Branch #{name} does not exist.")
+ end
+ end
+
+ def remove(name)
+ if name == @current
+ OperationStatus.new(false, "Cannot remove current branch.")
+ elsif @branches[name] != nil
+ @branches.delete(name)
+ OperationStatus.new(true, "Removed branch #{name}.")
+ else
+ OperationStatus.new(false, "Branch #{name} does not exist.")
+ end
+ end
+
+ def list
+ list = ""
+ @branches.each do |name, val|
+ prefix = @current == name ? '* ' : ' '
+ list += "#{prefix}#{name}\n"
+ end
+ return list
+ end
+
+ def add_commit(new_commit)
+ @branches[@current]['commits'] << new_commit
+ end
+
+ def get_all_commits
+ @branches[@current]['commits'].reverse
+ end
+
+ def find(hash)
+ result = @branches[@current]['commits'].select do |commit|
+ commit.instance_eval{ hash } == hash
+ end
+ return result.length == 0 ? nil : result[0]
+ end
+end
+
+class Commit
+ attr_reader :message, :objects, :date, :hash
+
+ def initialize(message, changes)
+ @message, @objects = message, changes
+ @date = Time.now.strftime("%a %b %e %H:%M %Y %z")
+ @hash = Digest::SHA1.hexdigest("#{@date}#{@message}")
+ end
+end