Skip to content

Commit

Permalink
Add support for special characters in file names (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
eseliger committed May 8, 2020
1 parent adde711 commit 8c3ae63
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
13 changes: 13 additions & 0 deletions diff/diff_test.go
Expand Up @@ -203,6 +203,19 @@ func TestParseFileDiffHeaders(t *testing.T) {
},
},
},
{
filename: "quoted_filename.diff",
wantDiff: &FileDiff{
OrigName: "a/商品详情.txt",
OrigTime: nil,
NewName: "b/商品详情.txt",
NewTime: nil,
Extended: []string{
"diff --git \"a/\\345\\225\\206\\345\\223\\201\\350\\257\\246\\346\\203\\205.txt\" \"b/\\345\\225\\206\\345\\223\\201\\350\\257\\246\\346\\203\\205.txt\"",
"index e69de29..c67479b 100644",
},
},
},
}
for _, test := range tests {
diffData, err := ioutil.ReadFile(filepath.Join("testdata", test.filename))
Expand Down
41 changes: 35 additions & 6 deletions diff/parse.go
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -234,6 +235,15 @@ func (r *FileDiffReader) ReadFileHeaders() (origName, newName string, origTimest
return "", "", nil, nil, err
}

unquotedOrigName, err := strconv.Unquote(origName)
if err == nil {
origName = unquotedOrigName
}
unquotedNewName, err := strconv.Unquote(newName)
if err == nil {
newName = unquotedNewName
}

return origName, newName, origTimestamp, newTimestamp, nil
}

Expand Down Expand Up @@ -329,30 +339,49 @@ func (r *FileDiffReader) ReadExtendedHeaders() ([]string, error) {
// handleEmpty detects when FileDiff was an empty diff and will not have any hunks
// that follow. It updates fd fields from the parsed extended headers.
func handleEmpty(fd *FileDiff) (wasEmpty bool) {
var err error
switch {
case (len(fd.Extended) == 3 || len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ")) &&
strings.HasPrefix(fd.Extended[1], "new file mode ") && strings.HasPrefix(fd.Extended[0], "diff --git "):

names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName = "/dev/null"
fd.NewName = names[1]
fd.NewName, err = strconv.Unquote(names[1])
if err != nil {
fd.NewName = names[1]
}
return true
case (len(fd.Extended) == 3 || len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ")) &&
strings.HasPrefix(fd.Extended[1], "deleted file mode ") && strings.HasPrefix(fd.Extended[0], "diff --git "):

names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName = names[0]
fd.OrigName, err = strconv.Unquote(names[0])
if err != nil {
fd.OrigName = names[0]
}
fd.NewName = "/dev/null"
return true
case len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[2], "rename from ") && strings.HasPrefix(fd.Extended[3], "rename to ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName = names[0]
fd.NewName = names[1]
fd.OrigName, err = strconv.Unquote(names[0])
if err != nil {
fd.OrigName = names[0]
}
fd.NewName, err = strconv.Unquote(names[1])
if err != nil {
fd.NewName = names[1]
}
return true
case len(fd.Extended) == 3 && strings.HasPrefix(fd.Extended[2], "Binary files ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName = names[0]
fd.NewName = names[1]
fd.OrigName, err = strconv.Unquote(names[0])
if err != nil {
fd.OrigName = names[0]
}
fd.NewName, err = strconv.Unquote(names[1])
if err != nil {
fd.NewName = names[1]
}
return true
default:
return false
Expand Down
8 changes: 8 additions & 0 deletions diff/testdata/quoted_filename.diff
@@ -0,0 +1,8 @@
diff --git "a/\345\225\206\345\223\201\350\257\246\346\203\205.txt" "b/\345\225\206\345\223\201\350\257\246\346\203\205.txt"
index e69de29..c67479b 100644
--- "a/\345\225\206\345\223\201\350\257\246\346\203\205.txt"
+++ "b/\345\225\206\345\223\201\350\257\246\346\203\205.txt"
@@ -0,0 +1,3 @@
+some
+test
+file

0 comments on commit 8c3ae63

Please sign in to comment.