Example #1
0
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
}
Example #2
0
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
}