Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 3713791

Browse files
authored
Merge pull request #526 from joshbetz/fix/filename-form
Normalize filenames before comparing.
2 parents a0885c5 + 5c1a2ec commit 3713791

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

utils/merkletrie/noder/path.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package noder
33
import (
44
"bytes"
55
"strings"
6+
7+
"golang.org/x/text/unicode/norm"
68
)
79

810
// Path values represent a noder and its ancestors. The root goes first
@@ -78,7 +80,11 @@ func (p Path) Compare(other Path) int {
7880
case i == len(p):
7981
return -1
8082
default:
81-
cmp := strings.Compare(p[i].Name(), other[i].Name())
83+
form := norm.Form(norm.NFC)
84+
this := form.String(p[i].Name())
85+
that := form.String(other[i].Name())
86+
87+
cmp := strings.Compare(this, that)
8288
if cmp != 0 {
8389
return cmp
8490
}

utils/merkletrie/noder/path_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package noder
22

3-
import . "gopkg.in/check.v1"
3+
import (
4+
"golang.org/x/text/unicode/norm"
5+
. "gopkg.in/check.v1"
6+
)
47

58
type PathSuite struct{}
69

@@ -149,3 +152,10 @@ func (s *PathSuite) TestCompareMixedDepths(c *C) {
149152
c.Assert(p1.Compare(p2), Equals, 1)
150153
c.Assert(p2.Compare(p1), Equals, -1)
151154
}
155+
156+
func (s *PathSuite) TestCompareNormalization(c *C) {
157+
p1 := Path([]Noder{&noderMock{name: norm.Form(norm.NFKC).String("페")}})
158+
p2 := Path([]Noder{&noderMock{name: norm.Form(norm.NFKD).String("페")}})
159+
c.Assert(p1.Compare(p2), Equals, 0)
160+
c.Assert(p2.Compare(p1), Equals, 0)
161+
}

worktree_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"os"
88
"path/filepath"
99

10+
"golang.org/x/text/unicode/norm"
11+
1012
"gopkg.in/src-d/go-git.v4/config"
1113
"gopkg.in/src-d/go-git.v4/plumbing"
1214
"gopkg.in/src-d/go-git.v4/plumbing/filemode"
@@ -304,6 +306,47 @@ func (s *WorktreeSuite) TestCheckoutSymlink(c *C) {
304306
c.Assert(err, IsNil)
305307
}
306308

309+
func (s *WorktreeSuite) TestFilenameNormalization(c *C) {
310+
url := c.MkDir()
311+
path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
312+
313+
server, err := PlainClone(url, false, &CloneOptions{
314+
URL: path,
315+
})
316+
317+
filename := "페"
318+
319+
w, err := server.Worktree()
320+
c.Assert(err, IsNil)
321+
util.WriteFile(w.Filesystem, filename, []byte("foo"), 0755)
322+
_, err = w.Add(filename)
323+
c.Assert(err, IsNil)
324+
_, err = w.Commit("foo", &CommitOptions{Author: defaultSignature()})
325+
c.Assert(err, IsNil)
326+
327+
r, err := Clone(memory.NewStorage(), memfs.New(), &CloneOptions{
328+
URL: url,
329+
})
330+
331+
w, err = r.Worktree()
332+
c.Assert(err, IsNil)
333+
334+
status, err := w.Status()
335+
c.Assert(err, IsNil)
336+
c.Assert(status.IsClean(), Equals, true)
337+
338+
err = w.Filesystem.Remove(filename)
339+
c.Assert(err, IsNil)
340+
341+
modFilename := norm.Form(norm.NFKD).String(filename)
342+
util.WriteFile(w.Filesystem, modFilename, []byte("foo"), 0755)
343+
_, err = w.Add(filename)
344+
345+
status, err = w.Status()
346+
c.Assert(err, IsNil)
347+
c.Assert(status.IsClean(), Equals, true)
348+
}
349+
307350
func (s *WorktreeSuite) TestCheckoutSubmodule(c *C) {
308351
url := "https://github.com/git-fixtures/submodule.git"
309352
r := s.NewRepositoryWithEmptyWorktree(fixtures.ByURL(url).One())

0 commit comments

Comments
 (0)