(parent, child *Patch)
| 149 | } |
| 150 | |
| 151 | func Diff(parent, child *Patch) (*Patch, error) { |
| 152 | var dirty bool |
| 153 | p := NewPatch(parent) |
| 154 | deletedObjects := make(map[ksuid.KSUID]struct{}) |
| 155 | for _, id := range child.deletedObjects { |
| 156 | deletedObjects[id] = struct{}{} |
| 157 | } |
| 158 | // For each object in the child patch that isn't in the parent, create an add, |
| 159 | // unless the parent deletes it, then return an error. |
| 160 | for _, o := range child.SelectAll() { |
| 161 | if !Exists(parent, o.ID) { |
| 162 | if _, ok := deletedObjects[o.ID]; ok { |
| 163 | return nil, fmt.Errorf("parent branch deletes object that child branch adds: %d", o.ID) |
| 164 | } |
| 165 | if err := p.AddDataObject(o); err != nil { |
| 166 | return nil, err |
| 167 | } |
| 168 | dirty = true |
| 169 | } |
| 170 | } |
| 171 | // For each delete in the child patch, create a delete. |
| 172 | // If the object doesn't exist in the parent, then we have a |
| 173 | // delete conflict. |
| 174 | for _, id := range child.deletedObjects { |
| 175 | if Exists(parent, id) { |
| 176 | if err := p.DeleteObject(id); err != nil { |
| 177 | return nil, err |
| 178 | } |
| 179 | dirty = true |
| 180 | } else { |
| 181 | return nil, fmt.Errorf("delete conflict: %s", id) |
| 182 | } |
| 183 | } |
| 184 | if !dirty { |
| 185 | return nil, errors.New("difference is empty") |
| 186 | } |
| 187 | return p, nil |
| 188 | } |
no test coverage detected