Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 package git | |
| 2 | |
| 3 import "crypto/sha1" | |
| 4 import "encoding/hex" | |
| 5 import "fmt" | |
| 6 | |
| 7 // The empty ObjectID (all zeros) | |
| 8 var NoID = ObjectID{} | |
| 9 | |
| 10 // MakeObjectIDForData hashes |data| as the git type |typ| (blob, commit, tree), | |
| 11 // and returns an ObjectID for it. | |
| 12 func MakeObjectIDForData(typ string, data []byte) ObjectID { | |
| 13 h := sha1.New() | |
| 14 h.Write([]byte(fmt.Sprintf("%s %d\x00", typ, len(data)))) | |
| 15 h.Write(data) | |
| 16 return MakeObjectIDRaw(h.Sum(nil)) | |
| 17 } | |
| 18 | |
| 19 // MakeObjectIDRaw treats |raw| as a 20-byte Id. panic()'s if len(raw) is not 20 | |
| 20 func MakeObjectIDRaw(raw []byte) (ret ObjectID) { | |
| 21 if len(raw) != 20 { | |
| 22 panic("MakeObjectIdRaw() must be invoked with a 20 byte string") | |
| 23 } | |
| 24 copy(ret.raw[:], raw) | |
|
M-A Ruel
2014/10/18 00:47:06
Why not ret.raw = raw?
iannucci
2014/10/20 21:11:57
because I can't trust that the caller won't modify
| |
| 25 return | |
| 26 } | |
| 27 | |
| 28 // MakeObjectID decodes the 40-byte |hexval| into an ObjectID. panic()'s if | |
| 29 // len(hexval) is not 40, or if it is not valid hexadecimal. | |
| 30 func MakeObjectID(hexval string) ObjectID { | |
| 31 if len(hexval) != 40 { | |
| 32 panic("MakeObjectID() must be invoked with a 40 byte hex string" ) | |
| 33 } | |
| 34 raw, err := hex.DecodeString(hexval) | |
| 35 if err != nil { | |
| 36 panic(err) | |
| 37 } | |
| 38 return MakeObjectIDRaw(raw) | |
| 39 } | |
| 40 | |
| 41 func (o ObjectID) String() string { | |
| 42 if o != NoID { | |
| 43 return hex.EncodeToString(o.raw[:]) | |
|
M-A Ruel
2014/10/18 00:47:06
Why raw[:]?
iannucci
2014/10/20 21:11:57
Because raw is a [20]byte and not a []byte.
| |
| 44 } | |
| 45 return "<NoID>" | |
| 46 } | |
| 47 | |
| 48 // RawString returns a git hash-object compatible (binary) representation | |
| 49 // of the ObjectID (e.g. suitable for inclusion in a tree object output) | |
| 50 func (o ObjectID) RawString() string { | |
| 51 return string(o.raw[:]) | |
| 52 } | |
| 53 | |
| 54 // EmptyObject is a placeholder Object which is not Internable, but can be | |
| 55 // used to create a Complete() Tree. It can be of type "commit" or "blob". | |
| 56 // It is never Complete(). | |
| 57 type EmptyObject struct { | |
| 58 id ObjectID | |
| 59 typ string | |
| 60 } | |
| 61 | |
| 62 func (o EmptyObject) ID() ObjectID { return o.id } | |
| 63 func (o EmptyObject) Type() string { return o.typ } | |
| 64 func (o EmptyObject) Complete() bool { return false } | |
| 65 func (o EmptyObject) String() string { | |
| 66 return fmt.Sprintf("EmptyObject(%s, %s)", o.ID(), o.Type()) | |
| 67 } | |
| 68 | |
| 69 // NewEmptyObject returns an Object of type |typ| with no data. For "tree" types , | |
| 70 // this returns an empty Tree (which is mutable). All other types are an | |
| 71 // EmptyObject. | |
| 72 func NewEmptyObject(typ string, id ObjectID) Object { | |
| 73 switch typ { | |
| 74 case "blob", "commit": | |
| 75 return EmptyObject{id, typ} | |
| 76 case "tree": | |
| 77 return NewEmptyTree(id, 0) | |
| 78 default: | |
| 79 panic("unknown type " + typ) | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 // NewEmptyChild returns a Child containing an EmptyObject of id. | |
| 84 func NewEmptyChild(mode Mode, id ObjectID) *Child { | |
| 85 return &Child{ | |
| 86 NewEmptyObject(mode.Type(), id), | |
| 87 mode, | |
| 88 } | |
| 89 } | |
| OLD | NEW |