@@ -66,12 +66,44 @@ func (o *ObjectDatabase) Close() error {
6666 return nil
6767}
6868
69+ // Object returns an Object (of unknown implementation) satisfying the type
70+ // associated with the object named "sha".
71+ //
72+ // If the object could not be opened, is of unknown type, or could not be
73+ // decoded, than an appropriate error is returned instead.
74+ func (o * ObjectDatabase ) Object (sha []byte ) (Object , error ) {
75+ r , err := o .open (sha )
76+ if err != nil {
77+ return nil , err
78+ }
79+
80+ typ , _ , err := r .Header ()
81+ if err != nil {
82+ return nil , err
83+ }
84+
85+ var into Object
86+ switch typ {
87+ case BlobObjectType :
88+ into = new (Blob )
89+ case TreeObjectType :
90+ into = new (Tree )
91+ case CommitObjectType :
92+ into = new (Commit )
93+ case TagObjectType :
94+ into = new (Tag )
95+ default :
96+ return nil , fmt .Errorf ("gitobj: unknown object type: %s" , typ )
97+ }
98+ return into , o .decode (r , into )
99+ }
100+
69101// Blob returns a *Blob as identified by the SHA given, or an error if one was
70102// encountered.
71103func (o * ObjectDatabase ) Blob (sha []byte ) (* Blob , error ) {
72104 var b Blob
73105
74- if err := o .decode (sha , & b ); err != nil {
106+ if err := o .openDecode (sha , & b ); err != nil {
75107 return nil , err
76108 }
77109 return & b , nil
@@ -81,7 +113,7 @@ func (o *ObjectDatabase) Blob(sha []byte) (*Blob, error) {
81113// encountered.
82114func (o * ObjectDatabase ) Tree (sha []byte ) (* Tree , error ) {
83115 var t Tree
84- if err := o .decode (sha , & t ); err != nil {
116+ if err := o .openDecode (sha , & t ); err != nil {
85117 return nil , err
86118 }
87119 return & t , nil
@@ -92,7 +124,7 @@ func (o *ObjectDatabase) Tree(sha []byte) (*Tree, error) {
92124func (o * ObjectDatabase ) Commit (sha []byte ) (* Commit , error ) {
93125 var c Commit
94126
95- if err := o .decode (sha , & c ); err != nil {
127+ if err := o .openDecode (sha , & c ); err != nil {
96128 return nil , err
97129 }
98130 return & c , nil
@@ -103,7 +135,7 @@ func (o *ObjectDatabase) Commit(sha []byte) (*Commit, error) {
103135func (o * ObjectDatabase ) Tag (sha []byte ) (* Tag , error ) {
104136 var t Tag
105137
106- if err := o .decode (sha , & t ); err != nil {
138+ if err := o .openDecode (sha , & t ); err != nil {
107139 return nil , err
108140 }
109141 return & t , nil
@@ -272,6 +304,16 @@ func (o *ObjectDatabase) open(sha []byte) (*ObjectReader, error) {
272304 return NewObjectReadCloser (f )
273305}
274306
307+ // openDecode calls decode (see: below) on the object named "sha" after openin
308+ // it.
309+ func (o * ObjectDatabase ) openDecode (sha []byte , into Object ) error {
310+ r , err := o .open (sha )
311+ if err != nil {
312+ return err
313+ }
314+ return o .decode (r , into )
315+ }
316+
275317// decode decodes an object given by the sha "sha []byte" into the given object
276318// "into", or returns an error if one was encountered.
277319//
@@ -280,12 +322,7 @@ func (o *ObjectDatabase) open(sha []byte) (*ObjectReader, error) {
280322// BlobObjectType. Blob's don't exhaust the buffer completely (they instead
281323// maintain a handle on the blob's contents via an io.LimitedReader) and
282324// therefore cannot be closed until signaled explicitly by gitobj.Blob.Close().
283- func (o * ObjectDatabase ) decode (sha []byte , into Object ) error {
284- r , err := o .open (sha )
285- if err != nil {
286- return err
287- }
288-
325+ func (o * ObjectDatabase ) decode (r * ObjectReader , into Object ) error {
289326 typ , size , err := r .Header ()
290327 if err != nil {
291328 return err
0 commit comments