diff options
author | Miguel Molina <miguel@erizocosmi.co> | 2020-05-04 09:14:42 +0200 |
---|---|---|
committer | Miguel Molina <miguel@erizocosmi.co> | 2020-05-04 09:14:42 +0200 |
commit | 8cdf70ac123b26d2234014bce344332f9b0787b3 (patch) | |
tree | 848a70f42abc28f125109d9ec3412993810e7b5a /plumbing | |
parent | 8543c83ab70a33834b90df74fef7f398791fb4ae (diff) | |
download | go-git-8cdf70ac123b26d2234014bce344332f9b0787b3.tar.gz |
plumbing: exact renames detection could leave gaps in the changes
This fixes an issue where exact renames detection could leave gaps
with nil changes in the added and deleted change slices. That could
lead to panics in the content rename detection and others if the
user had set OnlyExact to true.
Signed-off-by: Miguel Molina <miguel@erizocosmi.co>
Diffstat (limited to 'plumbing')
-rw-r--r-- | plumbing/object/rename.go | 12 | ||||
-rw-r--r-- | plumbing/object/rename_test.go | 26 |
2 files changed, 30 insertions, 8 deletions
diff --git a/plumbing/object/rename.go b/plumbing/object/rename.go index 9ce41b3..b0c62b2 100644 --- a/plumbing/object/rename.go +++ b/plumbing/object/rename.go @@ -177,14 +177,14 @@ func (d *renameDetector) detectExactRenames() { } for _, c := range added { - if _, ok := usedAdds[c]; !ok { + if _, ok := usedAdds[c]; !ok && c != nil { addedLeft = append(addedLeft, c) } } var newDeletes = make([]*Change, 0, len(deleted)-len(usedDeletes)) for _, c := range deleted { - if _, ok := usedDeletes[c]; !ok { + if _, ok := usedDeletes[c]; !ok && c != nil { newDeletes = append(newDeletes, c) } } @@ -197,11 +197,7 @@ func (d *renameDetector) detectExactRenames() { d.added = addedLeft d.deleted = nil for _, dels := range deletes { - for _, del := range dels { - if del != nil { - d.deleted = append(d.deleted, del) - } - } + d.deleted = append(d.deleted, dels...) } } @@ -713,7 +709,7 @@ func (i *similarityIndex) common(dst *similarityIndex) uint64 { } func (i *similarityIndex) add(key int, cnt uint64) error { - key = int(uint32(key)*0x9e370001 >> 1) + key = int(uint32(key) * 0x9e370001 >> 1) j := i.slot(key) for { diff --git a/plumbing/object/rename_test.go b/plumbing/object/rename_test.go index bf5044d..5dd77e8 100644 --- a/plumbing/object/rename_test.go +++ b/plumbing/object/rename_test.go @@ -271,6 +271,32 @@ func (s *RenameSuite) TestRenameLimit(c *C) { } } +func (s *RenameSuite) TestRenameExactManyAddsManyDeletesNoGaps(c *C) { + content := "a" + detector := &renameDetector{ + added: []*Change{ + makeAdd(c, makeFile(c, pathA, filemode.Regular, content)), + makeAdd(c, makeFile(c, pathQ, filemode.Regular, content)), + makeAdd(c, makeFile(c, "something", filemode.Regular, content)), + }, + deleted: []*Change{ + makeDelete(c, makeFile(c, pathA, filemode.Regular, content)), + makeDelete(c, makeFile(c, pathB, filemode.Regular, content)), + makeDelete(c, makeFile(c, "foo/bar/other", filemode.Regular, content)), + }, + } + + detector.detectExactRenames() + + for _, added := range detector.added { + c.Assert(added, NotNil) + } + + for _, deleted := range detector.deleted { + c.Assert(deleted, NotNil) + } +} + func detectRenames(c *C, changes Changes, opts *DiffTreeOptions, expectedResults int) Changes { result, err := DetectRenames(changes, opts) c.Assert(err, IsNil) |