@@ -23,16 +23,18 @@ module Git
# base class for all git objects (blob, tree, commit, tag)
class Object
+ attr_accessor :repository
+
def Object.from_raw(rawobject, repository = nil)
case rawobject.type
when :blob
- return Blob.new(rawobject, repository)
+ return Blob.from_raw(rawobject, repository)
when :tree
- return Tree.new(rawobject, repository)
+ return Tree.from_raw(rawobject, repository)
when :commit
- return Commit.new(rawobject, repository)
+ return Commit.from_raw(rawobject, repository)
when :tag
- return Tag.new(rawobject, repository)
+ return Tag.from_raw(rawobject, repository)
else
raise RuntimeError, "got invalid object-type"
end
@@ -60,9 +62,13 @@ module Git
class Blob < Object
attr_accessor :content
- def initialize(rawobject, repository = nil)
+ def self.from_raw(rawobject, repository)
+ new(rawobject.content)
+ end
+
+ def initialize(content, repository=nil)
+ @content = content
@repository = repository
- @content = rawobject.content
end
def type
@@ -132,12 +138,17 @@ module Git
class Tree < Object
attr_accessor :entry
- def initialize(rawobject, repository = nil)
- @repository = repository
- @entry = []
- rawobject.content.scan(/\d+ .*?\0.{20}/m) do |i|
- @entry.push(DirectoryEntry.new(i))
+ def self.from_raw(rawobject, repository=nil)
+ entries = []
+ rawobject.content.scan(/\d+ .*?\0.{20}/m) do |raw|
+ entries << DirectoryEntry.new(raw)
end
+ new(entries, repository)
+ end
+
+ def initialize(entries=[], repository = nil)
+ @entry = entries
+ @repository = repository
end
def type
@@ -155,28 +166,39 @@ module Git
class Commit < Object
attr_accessor :author, :committer, :tree, :parent, :message
- def initialize(rawobject, repository = nil)
- @repository = repository
- @parent = []
-
- headers, @message = rawobject.content.split(/\n\n/, 2)
+ def self.from_raw(rawobject, repository=nil)
+ parent = []
+ tree = author = committer = nil
+ headers, message = rawobject.content.split(/\n\n/, 2)
headers = headers.split(/\n/).map { |header| header.split(/ /, 2) }
- headers.each do |header|
- key, value = header
+ headers.each do |key, value|
case key
when "tree"
- @tree = value
+ tree = value
when "parent"
- @parent.push(value)
+ parent.push(value)
when "author"
- @author = UserInfo.new(value)
+ author = UserInfo.new(value)
when "committer"
- @committer = UserInfo.new(value)
+ committer = UserInfo.new(value)
else
raise RuntimeError, "invalid header %s in commit" % key
end
end
+ if not tree && author && committer
+ raise RuntimeError, "incomplete raw commit object"
+ end
+ new(tree, parent, author, committer, message, repository)
+ end
+
+ def initialize(tree, parent, author, committer, message, repository=nil)
+ @tree = tree
+ @author = author
+ @parent = parent
+ @committer = committer
+ @message = message
+ @repository = repository
end
def type
@@ -194,31 +216,35 @@ module Git
class Tag < Object
attr_accessor :object, :type, :tag, :tagger, :message
- def initialize(rawobject, repository = nil)
- @repository = repository
- @parent = []
-
- headers, @message = rawobject.content.split(/\n\n/, 2)
-
+ def self.from_raw(rawobject, repository=nil)
+ headers, message = rawobject.content.split(/\n\n/, 2)
headers = headers.split(/\n/).map { |header| header.split(/ /, 2) }
- headers.each do |header|
- key, value = header
+ headers.each do |key, value|
case key
when "object"
- @object = value
+ object = value
when "type"
if !["blob", "tree", "commit", "tag"].include?(value)
raise RuntimeError, "invalid type in tag"
end
- @type = value.to_sym
+ type = value.to_sym
when "tag"
- @tag = value
+ tag = value
when "tagger"
- @tagger = UserInfo.new(value)
+ tagger = UserInfo.new(value)
else
raise RuntimeError, "invalid header %s in commit" % key
end
end
+ new(object, type, tag, tagger, repository)
+ end
+
+ def initialize(object, type, tag, tagger, repository=nil)
+ @object = object
+ @type = type
+ @tag = tag
+ @tagger = tagger
+ @repository = repository
end
def raw_content