Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 package git | |
| 5 | |
| 6 import ( | |
| 7 "crypto/sha1" | |
| 8 "encoding/hex" | |
| 9 "fmt" | |
| 10 ) | |
| 11 | |
| 12 type ObjectType uint8 | |
|
M-A Ruel
2014/10/21 00:55:54
If it's exported, it's worth documenting. :)
| |
| 13 | |
| 14 const ( | |
| 15 UnknownType ObjectType = iota | |
| 16 CommitType | |
| 17 BlobType | |
| 18 TreeType | |
|
M-A Ruel
2014/10/21 00:55:54
Y U NO TAG? Even if you explicitly do not support
iannucci
2016/05/23 21:53:42
Omission, though "tag" doesn't show up in tree obj
| |
| 19 ) | |
| 20 | |
| 21 func (o ObjectType) String() string { | |
| 22 switch o { | |
| 23 case CommitType: | |
| 24 return "commit" | |
| 25 case BlobType: | |
| 26 return "blob" | |
| 27 case TreeType: | |
| 28 return "tree" | |
| 29 default: | |
| 30 return "UNKNOWN" | |
|
Vadim Sh.
2014/10/21 15:26:59
panic too?
| |
| 31 } | |
| 32 } | |
| 33 | |
| 34 func MakeObjectType(s string) ObjectType { | |
| 35 switch s { | |
| 36 case "commit": | |
| 37 return CommitType | |
| 38 case "blob": | |
| 39 return BlobType | |
| 40 case "tree": | |
| 41 return TreeType | |
| 42 default: | |
| 43 panic(fmt.Errorf("unknown object type %s", s)) | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 // Object is the barest essence of a git object. It has a Type, and Id, and it | |
| 48 // can tell you if this instance is 'complete' (does it contain all the data | |
| 49 // necessary to re-create ID()?). | |
| 50 // | |
| 51 // If Complete() is true, you can down-cast this to: | |
| 52 // *Tree, *Blob, *Commit | |
| 53 // | |
| 54 // If Complete() is false, you can down-cast this to: | |
| 55 // *Tree, EmptyObject | |
| 56 // | |
| 57 // Note that Tree's are never EmptyObject's. | |
|
agable
2014/10/21 17:01:35
nit: apostrophes
| |
| 58 type Object interface { | |
| 59 ID() ObjectID | |
| 60 | |
| 61 Type() ObjectType | |
| 62 | |
| 63 // Returns True iff RawString will produce a string which, when hashed, | |
| 64 // matches ID() | |
| 65 Complete() bool | |
| 66 } | |
| 67 | |
| 68 // ObjectID is a 20-byte git-sha for any Object type. | |
| 69 type ObjectID struct { | |
|
M-A Ruel
2014/10/21 00:55:54
It's fine and shorter to use
type ObjectID [20] b
agable
2014/10/21 17:01:35
Was going to say the same thing. Not sure why this
iannucci
2016/05/23 21:53:42
Modifiable, and I can't have a type alias whose 'r
| |
| 70 raw [20]byte | |
| 71 } | |
| 72 | |
| 73 // The empty ObjectID (all zeros) | |
| 74 var NoID = ObjectID{} | |
| 75 | |
| 76 // MakeObjectIDForData hashes |data| as the git type |typ| (blob, commit, tree), | |
| 77 // and returns an ObjectID for it. | |
| 78 func MakeObjectIDForData(typ ObjectType, data []byte) ObjectID { | |
| 79 h := sha1.New() | |
| 80 h.Write([]byte(fmt.Sprintf("%s %d\x00", typ, len(data)))) | |
| 81 h.Write(data) | |
| 82 return MakeObjectIDRaw(h.Sum(nil)) | |
| 83 } | |
| 84 | |
| 85 // MakeObjectIDRaw treats |raw| as a 20-byte Id. panic()'s if len(raw) is not 20 | |
| 86 func MakeObjectIDRaw(raw []byte) (ret ObjectID) { | |
| 87 if len(raw) != 20 { | |
| 88 panic("MakeObjectIdRaw() must be invoked with a 20 byte string") | |
| 89 } | |
| 90 copy(ret.raw[:], raw) | |
| 91 return | |
|
Vadim Sh.
2014/10/21 15:26:59
is this 'return' required here?
| |
| 92 } | |
| 93 | |
| 94 // MakeObjectID decodes the 40-byte |hexval| into an ObjectID. panic()'s if | |
| 95 // len(hexval) is not 40, or if it is not valid hexadecimal. | |
| 96 func MakeObjectID(hexval string) ObjectID { | |
| 97 if len(hexval) != 40 { | |
| 98 panic("MakeObjectID() must be invoked with a 40 byte hex string" ) | |
|
M-A Ruel
2014/10/21 00:55:54
In general, packages should not panic. It's really
Vadim Sh.
2014/10/21 15:26:59
IMHO, panic is like assert. If caller doesn't full
| |
| 99 } | |
| 100 raw, err := hex.DecodeString(hexval) | |
| 101 if err != nil { | |
| 102 panic(err) | |
| 103 } | |
| 104 return MakeObjectIDRaw(raw) | |
| 105 } | |
| 106 | |
| 107 func (o ObjectID) String() string { | |
| 108 if o != NoID { | |
| 109 return hex.EncodeToString(o.raw[:]) | |
| 110 } | |
| 111 return "<NoID>" | |
| 112 } | |
| 113 | |
| 114 // RawString returns a git hash-object compatible (binary) representation | |
| 115 // of the ObjectID (e.g. suitable for inclusion in a tree object output) | |
| 116 func (o ObjectID) RawString() string { | |
| 117 return string(o.raw[:]) | |
| 118 } | |
| 119 | |
| 120 // EmptyObject is a placeholder Object which is not Internable, but can be | |
| 121 // used to create a Complete() Tree. It can be of type "commit" or "blob". | |
| 122 // It is never Complete(). | |
| 123 type EmptyObject struct { | |
| 124 id ObjectID | |
| 125 typ ObjectType | |
| 126 } | |
| 127 | |
| 128 func (o EmptyObject) ID() ObjectID { return o.id } | |
| 129 func (o EmptyObject) Type() ObjectType { return o.typ } | |
| 130 func (o EmptyObject) Complete() bool { return false } | |
| 131 func (o EmptyObject) String() string { | |
| 132 return fmt.Sprintf("EmptyObject(%s, %s)", o.ID(), o.Type()) | |
| 133 } | |
| 134 | |
| 135 // NewEmptyObject returns an Object of type |typ| with no data. For "tree" types , | |
| 136 // this returns an empty Tree (which is mutable). All other types are an | |
| 137 // EmptyObject. | |
| 138 func NewEmptyObject(typ ObjectType, id ObjectID) Object { | |
| 139 switch typ { | |
| 140 case BlobType, CommitType: | |
| 141 return EmptyObject{id, typ} | |
| 142 case TreeType: | |
| 143 return NewEmptyTree(id, 0) | |
| 144 default: | |
| 145 panic("unknown type " + typ.String()) | |
| 146 } | |
| 147 } | |
| OLD | NEW |