func flatten(r api.Repository, base string, treeEntry *objects.TreeEntry) (result []*objects.TreeEntry, err error) { result = make([]*objects.TreeEntry, 0) var object objects.Object object, err = r.ObjectFromOid(treeEntry.ObjectId()) if err != nil { return nil, err } tree, _ := object.(*objects.Tree) for _, entry := range tree.Entries() { result = append(result, objects.NewTreeEntry(entry.Mode(), entry.ObjectType(), base+entry.Name(), entry.ObjectId())) } return result, nil }
func (result *TreeDiff) detectRenamed(r api.Repository, blobMatcher BlobMatcher) (err error) { //build a matrix of similarity scores deletes, inserts := result.deleteEdits, result.insertEdits scores := make([]float64, len(deletes)*len(inserts)) for di, delete := range deletes { for ii, insert := range inserts { var objA, objB objects.Object if objA, err = r.ObjectFromOid(delete.Before.ObjectId()); err != nil { return } if objB, err = r.ObjectFromOid(insert.After.ObjectId()); err != nil { return err } a, _ := objA.(*objects.Blob) b, _ := objB.(*objects.Blob) index := di*(len(deletes)-1) + ii scores[index] = blobMatcher.Match(a, b) } } //get the indices of the score matrix in sorted order (i.e., from greatest score to least) sorted := indexedInOrder(scores) deletesDone, insertsDone := make([]bool, len(deletes)), make([]bool, len(inserts)) renameCount := 0 for _, index := range sorted { score := scores[index] if score < 60 { break } di := int(index) / (len(deletes) - 1) ii := int(index) - (di * (len(deletes) - 1)) if deletesDone[di] || insertsDone[ii] { continue } renameCount++ rename, insert := result.deleteEdits[di], result.insertEdits[ii] result.insertEdits[ii], result.deleteEdits[di] = nil, nil rename.After = insert.After rename.action = Rename rename.score = score result.renamed = append(result.renamed, rename) deletesDone[di], insertsDone[ii] = true, true } //prune the removed (nil) edits and populate the \deleted\ []*objects.TreeEntry and \inserted\ []*objects.TreeEntry deleteEdits, insertEdits := result.deleteEdits, result.insertEdits result.edits, result.deleteEdits, result.insertEdits = nil, nil, nil for _, v := range insertEdits { if v == nil { continue } result.edits = append(result.edits, v) result.insertEdits = append(result.insertEdits, v) result.inserted = append(result.inserted, v.After) } for _, v := range deleteEdits { if v == nil { continue } result.edits = append(result.edits, v) result.deleteEdits = append(result.deleteEdits, v) result.deleted = append(result.deleted, v.Before) } result.edits = append(result.edits, result.modified...) result.edits = append(result.edits, result.renamed...) return }