Skip to content

Instantly share code, notes, and snippets.

@shogo82148
Created March 20, 2019 07:10
Show Gist options
  • Save shogo82148/dc9a0ae6ce894b3fcf030fbee015dace to your computer and use it in GitHub Desktop.
Save shogo82148/dc9a0ae6ce894b3fcf030fbee015dace to your computer and use it in GitHub Desktop.
git diff HEAD...origin/support-multi-byte-char
diff --git a/diff/parse.go b/diff/parse.go
index ab481d0..12b54e8 100644
--- a/diff/parse.go
+++ b/diff/parse.go
@@ -136,9 +136,75 @@ func parseFileHeader(line string) (filename, timestamp string) {
ss := line[len(tokenOldFile)+1:]
tabi := strings.LastIndex(ss, "\t")
if tabi == -1 {
- return ss, ""
+ return unescapeCString(ss), ""
}
- return ss[:tabi], ss[tabi+1:]
+ return unescapeCString(ss[:tabi]), ss[tabi+1:]
+}
+
+func unescapeCString(str string) string {
+ if !strings.HasPrefix(str, `"`) {
+ // no need to unescape
+ return str
+ }
+ str = strings.TrimPrefix(strings.TrimSuffix(str, `"`), `"`)
+
+ res := make([]byte, 0, len(str))
+ r := strings.NewReader(str)
+LOOP:
+ for {
+ ch, err := r.ReadByte()
+ if err != nil {
+ break
+ }
+ if ch != '\\' {
+ res = append(res, ch)
+ continue
+ }
+
+ ch, err = r.ReadByte()
+ if err != nil {
+ break
+ }
+ switch ch {
+ case 'a':
+ res = append(res, '\a')
+ case 'b':
+ res = append(res, '\b')
+ case 't':
+ res = append(res, '\t')
+ case 'n':
+ res = append(res, '\n')
+ case 'v':
+ res = append(res, '\v')
+ case 'f':
+ res = append(res, '\f')
+ case 'r':
+ res = append(res, '\r')
+ case '"':
+ res = append(res, '"')
+ case '\\':
+ res = append(res, '\\')
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ if err := r.UnreadByte(); err != nil {
+ break LOOP
+ }
+ var oct [3]byte
+ if n, _ := r.Read(oct[:]); n < 3 {
+ res = append(res, oct[:n]...)
+ break LOOP
+ }
+ ch, err := strconv.ParseUint(string(oct[:]), 8, 8)
+ if err != nil {
+ res = append(res, oct[:]...)
+ break
+ }
+ res = append(res, byte(ch))
+ default:
+ res = append(res, ch)
+ }
+ }
+
+ return string(res)
}
func parseExtendedHeader(r *bufio.Reader) []string {
diff --git "a/diff/testdata/\"日本語\".diff" "b/diff/testdata/\"日本語\".diff"
new file mode 100644
index 0000000..08f812a
--- /dev/null
+++ "b/diff/testdata/\"日本語\".diff"
@@ -0,0 +1,10 @@
+diff --git "a/\"\346\227\245\346\234\254\350\252\236\".old.txt" "b/\"\346\227\245\346\234\254\350\252\236\".new.txt"
+index 5f5a9e4..feeb01f 100644
+--- "a/\"\346\227\245\346\234\254\350\252\236\".old.txt"
++++ "b/\"\346\227\245\346\234\254\350\252\236\".new.txt"
+@@ -1,3 +1,4 @@
+ 変更なし
+-行削除
++行追加
++行追加
+ 変更なし
diff --git "a/diff/testdata/\"日本語\".diff.json" "b/diff/testdata/\"日本語\".diff.json"
new file mode 100644
index 0000000..51c6b9c
--- /dev/null
+++ "b/diff/testdata/\"日本語\".diff.json"
@@ -0,0 +1,58 @@
+[
+ {
+ "PathOld": "a/\"日本語\".old.txt",
+ "PathNew": "b/\"日本語\".new.txt",
+ "TimeOld": "",
+ "TimeNew": "",
+ "Hunks": [
+ {
+ "StartLineOld": 1,
+ "LineLengthOld": 3,
+ "StartLineNew": 1,
+ "LineLengthNew": 4,
+ "Section": "",
+ "Lines": [
+ {
+ "Type": 0,
+ "Content": "変更なし",
+ "LnumDiff": 1,
+ "LnumOld": 1,
+ "LnumNew": 1
+ },
+ {
+ "Type": 2,
+ "Content": "行削除",
+ "LnumDiff": 2,
+ "LnumOld": 2,
+ "LnumNew": 0
+ },
+ {
+ "Type": 1,
+ "Content": "行追加",
+ "LnumDiff": 3,
+ "LnumOld": 0,
+ "LnumNew": 2
+ },
+ {
+ "Type": 1,
+ "Content": "行追加",
+ "LnumDiff": 4,
+ "LnumOld": 0,
+ "LnumNew": 3
+ },
+ {
+ "Type": 0,
+ "Content": "変更なし",
+ "LnumDiff": 5,
+ "LnumOld": 3,
+ "LnumNew": 4
+ }
+ ]
+ }
+ ],
+ "Extended": [
+ "diff --git \"a/\\\"\\346\\227\\245\\346\\234\\254\\350\\252\\236\\\".old.txt\" \"b/\\\"\\346\\227\\245\\346\\234\\254\\350\\252\\236\\\".new.txt\"",
+ "index 5f5a9e4..feeb01f 100644"
+ ]
+ }
+]
diff --git "a/diff/testdata/\"日本語\".new.txt" "b/diff/testdata/\"日本語\".new.txt"
new file mode 100644
index 0000000..feeb01f
--- /dev/null
+++ "b/diff/testdata/\"日本語\".new.txt"
@@ -0,0 +1,4 @@
+変更なし
+行追加
+行追加
+変更なし
diff --git "a/diff/testdata/\"日本語\".old.txt" "b/diff/testdata/\"日本語\".old.txt"
new file mode 100644
index 0000000..5f5a9e4
--- /dev/null
+++ "b/diff/testdata/\"日本語\".old.txt"
@@ -0,0 +1,3 @@
+変更なし
+行削除
+変更なし
diff --git a/diff/testdata/gen.sh b/diff/testdata/gen.sh
index 048fd60..65f089c 100644
--- a/diff/testdata/gen.sh
+++ b/diff/testdata/gen.sh
@@ -11,3 +11,4 @@ git diff --no-index /dev/null "empty space.txt" > empty_space.diff
git diff --no-index golint.{old,new}.go > golint.diff
git diff --no-index empty.txt /dev/null > newline_and_empty_deleted.diff
git diff --no-index golint.{old,new}.go >> newline_and_empty_deleted.diff
+git diff --no-index \"日本語\".{old,new}.txt >> \"日本語\".diff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment