| 121 | } |
| 122 | |
| 123 | func (p *Patch) Revert(tip *Snapshot, commit, parent ksuid.KSUID, retries int, author, message string) (*Object, error) { |
| 124 | object := NewObject(parent, author, message, super.Null, retries) |
| 125 | // For each data object that is added in the patch and is also in the tip, we do a delete. |
| 126 | for _, dataObject := range p.diff.SelectAll() { |
| 127 | if Exists(tip, dataObject.ID) { |
| 128 | object.appendDelete(dataObject.ID) |
| 129 | } |
| 130 | } |
| 131 | // For each delete in the patch that is absent in the tip, we do an add. |
| 132 | for _, id := range p.deletedObjects { |
| 133 | // Reach back to get the object before it was deleted in this patch. |
| 134 | dataObject, err := p.base.Lookup(id) |
| 135 | if err != nil { |
| 136 | return nil, err |
| 137 | } |
| 138 | if dataObject == nil { |
| 139 | return nil, fmt.Errorf("corrupt snapshot: ID %s is in patch's deleted objects but not in patch's base snapshot", id) |
| 140 | } |
| 141 | if !Exists(tip, dataObject.ID) { |
| 142 | object.appendAdd(dataObject) |
| 143 | } |
| 144 | } |
| 145 | if len(object.Actions) == 1 { |
| 146 | return nil, errors.New("revert commit is empty") |
| 147 | } |
| 148 | return object, nil |
| 149 | } |
| 150 | |
| 151 | func Diff(parent, child *Patch) (*Patch, error) { |
| 152 | var dirty bool |