diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-02-24 11:26:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-24 11:26:08 +0100 |
commit | 39f43b52a2bdfbc73703e2d09b575d49cd70ede8 (patch) | |
tree | 81d9845f9ba1c16975c24084e9023492e9e7ee33 /plumbing/object/change.go | |
parent | f93e5712a86b96370673a02fa7ffbe5e0aec0c66 (diff) | |
parent | cb51ef358e081b5214e3884bd618d1d3fedf8eb1 (diff) | |
download | go-git-39f43b52a2bdfbc73703e2d09b575d49cd70ede8.tar.gz |
Merge pull request #284 from ajnavarro/improvement/move-difftree-to-object
plumbing/object: move difftree to object package
Diffstat (limited to 'plumbing/object/change.go')
-rw-r--r-- | plumbing/object/change.go | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/plumbing/object/change.go b/plumbing/object/change.go new file mode 100644 index 0000000..5e32e5b --- /dev/null +++ b/plumbing/object/change.go @@ -0,0 +1,120 @@ +package object + +import ( + "bytes" + "fmt" + "strings" + + "srcd.works/go-git.v4/utils/merkletrie" +) + +// Change values represent a detected change between two git trees. For +// modifications, From is the original status of the node and To is its +// final status. For insertions, From is the zero value and for +// deletions To is the zero value. +type Change struct { + From ChangeEntry + To ChangeEntry +} + +var empty = ChangeEntry{} + +// Action returns the kind of action represented by the change, an +// insertion, a deletion or a modification. +func (c *Change) Action() (merkletrie.Action, error) { + if c.From == empty && c.To == empty { + return merkletrie.Action(0), + fmt.Errorf("malformed change: empty from and to") + } + if c.From == empty { + return merkletrie.Insert, nil + } + if c.To == empty { + return merkletrie.Delete, nil + } + + return merkletrie.Modify, nil +} + +// Files return the files before and after a change. +// For insertions from will be nil. For deletions to will be nil. +func (c *Change) Files() (from, to *File, err error) { + action, err := c.Action() + if err != nil { + return + } + + if action == merkletrie.Insert || action == merkletrie.Modify { + to, err = c.To.Tree.TreeEntryFile(&c.To.TreeEntry) + if err != nil { + return + } + } + + if action == merkletrie.Delete || action == merkletrie.Modify { + from, err = c.From.Tree.TreeEntryFile(&c.From.TreeEntry) + if err != nil { + return + } + } + + return +} + +func (c *Change) String() string { + action, err := c.Action() + if err != nil { + return fmt.Sprintf("malformed change") + } + + return fmt.Sprintf("<Action: %s, Path: %s>", action, c.name()) +} + +func (c *Change) name() string { + if c.From != empty { + return c.From.Name + } + + return c.To.Name +} + +// ChangeEntry values represent a node that has suffered a change. +type ChangeEntry struct { + // Full path of the node using "/" as separator. + Name string + // Parent tree of the node that has changed. + Tree *Tree + // The entry of the node. + TreeEntry TreeEntry +} + +// Changes represents a collection of changes between two git trees. +// Implements sort.Interface lexicographically over the path of the +// changed files. +type Changes []*Change + +func (c Changes) Len() int { + return len(c) +} + +func (c Changes) Swap(i, j int) { + c[i], c[j] = c[j], c[i] +} + +func (c Changes) Less(i, j int) bool { + return strings.Compare(c[i].name(), c[j].name()) < 0 +} + +func (c Changes) String() string { + var buffer bytes.Buffer + buffer.WriteString("[") + comma := "" + for _, v := range c { + buffer.WriteString(comma) + buffer.WriteString(v.String()) + comma = ", " + } + buffer.WriteString("]") + + return buffer.String() +} |