Борис обнови решението на 22.11.2015 23:29 (преди около 9 години)
+require 'digest'
+require 'date'
+
+class Class
+ alias init new
+end
+
+class ObjectAdd
+
+ def initialize(name, object)
+ @name = name
+ @object = object
+ @victory = true
+ end
+
+ def message
+ "Added #{@name} to stage."
+ end
+
+ def result
+ @object
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class CommitMessage
+ def initialize(message, count)
+ @victory = (count != 0)
+ @count = count
+ @message = message
+ end
+
+ def message
+ if @victory
+ "#{@message}\n\t#{@count} objects changed"
+ else
+ "Nothing to commit, working directory clean."
+ end
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class RemoveMessage
+
+ def initialize(name, object)
+ @victory = (object != false)
+ @object = object
+ @name = name
+ end
+
+ def result
+ @object
+ end
+
+ def message
+ if @victory
+ "Added #{@name} for removal."
+ else
+ "Object #{@name} is not committed."
+ end
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class CheckoutCommit
+ def initialize(comit_hash, object)
+ @victory = (object != false)
+ @hash = comit_hash
+ @object = object
+ end
+
+ def message
+ if @victory
+ "HEAD is now at #{@hash}."
+ else
+ "Commit #{hash} does not exist."
+ end
+ end
+
+ def result
+ @object
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class LastCommit
+ def initialize(name, message, commit)
+ @victory = (commit != false)
+ @object = commit
+ @message = message
+ @name = name
+ end
+
+ def message
+ if @victory
+ "#{message}"
+ else
+ "Branch #{name} does not have any commits yet."
+ end
+ end
+
+ def result
+ @object
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class CreateBranch
+ def initialize(name, condition)
+ @victory = condition
+ @name = name
+ end
+
+ def message
+ if @victory
+ "Created branch #{name}."
+ else
+ "Branch #{name} already exists."
+ end
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class CheckoutBranch
+ def initialize(name, condition)
+ @victory = condition
+ @name = name
+ end
+
+ def message
+ if @victory
+ "Switched to branch #{name}."
+ else
+ "Branch #{name} does not exist."
+ end
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class RemoveBranch
+ def initialize(name, condition, exists)
+ @victory = (condition != false) and (exists != false)
+ @exists = exists
+ @name = name
+ end
+
+ def message
+ if @victory
+ "Removed branch #{name}."
+ elsif (@exists == false)
+ "Branch #{name} does not exist."
+ else
+ "Cannot remove current branch."
+ end
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class BranchList
+ def initialize(names, current_index)
+ @victory = true
+ @names = names
+ @index = current_index
+ end
+
+ def message
+ message = @names.map { |n| " " + n }
+ message[@index][1] = "*"
+ message.join"\n"
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class BranchLog
+ def initialize(name, commits)
+ @victory = commits.any?
+ @name = name
+ @commits = commits
+ end
+
+ def message
+ if @victory
+ m = @commits.map{|n| "Commit #{n.hash}\nDate: #{n.date}\n\n\t#{n.message}"}
+ m.join"\n\n"
+ else
+ "Branch #{@name} does not have any commits yet."
+ end
+ end
+
+ def success?
+ @victory
+ end
+
+ def error?
+ ! @victory
+ end
+end
+
+class ObjectStore
+
+ class Commit
+
+ def initialize (objects = {}, message)
+ @objects , @message = objects, message
+ @date = Time.new
+ @date = @date.strftime("%a %b %d %k:%M:%S %Y %z")
+ @commit_hash = Digest::SHA1.hexdigest(@date + @message)
+ end
+
+ def date
+ @date
+ end
+
+ def message
+ @message
+ end
+
+ def objects
+ @objects.values
+ end
+
+ def get_names
+ @objects.keys
+ end
+
+ def remove(name)
+ @objects.delete(name)
+ end
+
+ def hash
+ @commit_hash
+ end
+
+ end
+
+ class Branch
+
+ def initialize(name = nil)
+ @name = name
+ @commits = []
+ @storage = {}
+ @removed = 0
+ end
+
+ def name
+ @name
+ end
+
+ def create(branch_name)
+ if @branches.any? { |n| n.name == branch_name }
+ CreateBranch.new(branch_name, false)
+ else
+ @name = branch_name
+ @branches.push(self)
+ CreateBranch.new(branch_name, true)
+ end
+ end
+
+ def add(name, object)
+ @storage.merge!(name => object)
+ end
+
+ def commit(message)
+ return false if @storage.empty? and (@removed == 0)
+ helper = @storage.invert.invert
+ count, @removed = @removed, 0
+ @storage.clear
+ @commits.push(Commit.new(helper, message))
+ count + helper.size
+ end
+
+ def get_commits
+ @commits
+ end
+
+ def remove_object(name)
+ commit = @commits.last
+ return false if ! commit.get_names.include?(name)
+ @removed += 1
+ commit.delete(name)
+ end
+
+ def checkout_commit(commit_hash)
+ return false if @commits.none? { |n| n.hash == commit_hash }
+ length = @commits.find_index { |n| n.hash == commit_hash } + 1
+ @commits = @commits.take(length)
+ @comits.last
+ end
+
+ def checkout(branch_name)
+ if @branches.none? { |n| n.name == branch_name }
+ CheckoutBranch.new(branch_name, false)
+ else
+ index = @branches.find_index { |n| n.name == branch_name }
+ @current_branch = @branches[index]
+ CheckoutBranch.new(branch_name, true)
+ end
+ end
+
+ def remove(branch_name)
+ if @branches.none? { |n| n.name == branch_name }
+ RemoveBranch.new(branch_name, true, false)
+ elsif @current_branch.name == branch_name
+ RemoveBranch.new(branch_name, false, true)
+ else
+ index = @branches.find_index { |n| n.name == branch_name }
+ @branches.delete_at(index)
+ RemoveBranch.new(branch_name, true, true)
+ end
+ end
+
+ def list
+ branch_names = @branches.map { |n| n.name }.sort
+ index = branch_names.find_index { |name| name == @current_branch.name }
+ BranchList.new(branch_names,index)
+ end
+
+ end
+
+ def initialize
+ @branches = []
+ @branches.push(Branch.new('master'))
+ @current_branch = @branches.first
+ end
+
+ def add(name, object)
+ @current_branch.add(name, object)
+ ObjectAdd.new(name, object)
+ end
+
+ def commit(message)
+ count
+ if (@current_branch.commit(message) == false)
+ count = 0
+ else
+ count = @current_branch.commit(message)
+ end
+ CommitMessage.new(message, count)
+ end
+
+ def remove(name)
+ RemoveMessage.new(name, @current_branch.remove_object(name))
+ end
+
+ def checkout(commit_hash)
+ if @current_branch.checkout_commit(commit_hash)
+ end
+
+ def branch
+ Branch.new
+ end
+
+ def log
+ BranchLog(@current_branch.name, @current_branch.get_commits)
+ end
+
+ def head
+ if @current_branch.get_commits.empty?
+ LastCommit.new(@current_branch.name, 0, false)
+ else
+ head = @current_branch.get_commits.last
+ LastCommit.new(@current_branch.name, head.message, head)
+ end
+ end
+end
+end