More thorough singleton instanciation
authorSimon 'corecode' Schubert <[email protected]>
Tue, 23 Jan 2007 15:27:14 +0000 (23 16:27 +0100)
committerSimon 'corecode' Schubert <[email protected]>
Tue, 23 Jan 2007 15:35:09 +0000 (23 16:35 +0100)
git/object.rb

index 0221d7a..c40ed15 100644 (file)
@@ -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