Skip to content

Commit

Permalink
Convert octal notation file names in Git (#380)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomiceli authored Nov 17, 2024
1 parent 92bac3b commit c1e046f
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 11 deletions.
52 changes: 49 additions & 3 deletions internal/git/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"fmt"
"io"
"net/url"
"os"
"os/exec"
"path"
Expand Down Expand Up @@ -115,6 +116,9 @@ func GetFilesOfRepository(user string, gist string, revision string) ([]string,
}

slice := strings.Split(string(stdout), "\n")
for i, s := range slice {
slice[i] = convertOctalToUTF8(s)
}
return slice[:len(slice)-1], nil
}

Expand Down Expand Up @@ -153,7 +157,7 @@ func CatFileBatch(user string, gist string, revision string, truncate bool) ([]*
fileMap = append(fileMap, &catFileBatch{
Hash: hash,
Size: size,
Name: name,
Name: convertOctalToUTF8(name),
})
}

Expand Down Expand Up @@ -249,7 +253,7 @@ func GetFileContent(user string, gist string, revision string, filename string,
"git",
"--no-pager",
"show",
revision+":"+filename,
revision+":"+convertURLToOctal(filename),
)
cmd.Dir = repositoryPath

Expand All @@ -273,7 +277,7 @@ func GetFileSize(user string, gist string, revision string, filename string) (ui
"git",
"cat-file",
"-s",
revision+":"+filename,
revision+":"+convertURLToOctal(filename),
)
cmd.Dir = repositoryPath

Expand Down Expand Up @@ -565,6 +569,48 @@ func removeFilesExceptGit(dir string) error {
})
}

func convertOctalToUTF8(name string) string {
name = strings.Trim(name, `"`)
utf8Name, err := strconv.Unquote(name)
if err != nil {
utf8Name, err = strconv.Unquote(`"` + name + `"`)
if err != nil {
return name
}
}
return utf8Name
}

func convertUTF8ToOctal(name string) string {
if strings.Contains(name, "\\") {
return name
}

needsQuoting := false
for _, r := range name {
if r > 127 {
needsQuoting = true
break
}
}

if !needsQuoting {
return name
}

quoted := fmt.Sprintf("%q", name)
return strings.Trim(quoted, `"`)
}

func convertURLToOctal(name string) string {
decoded, err := url.QueryUnescape(name)
if err != nil {
return name
}

return convertUTF8ToOctal(decoded)
}

const hookTemplate = `#!/bin/sh
"$OG_OPENGIST_HOME_INTERNAL/symlinks/opengist" --config=$OG_OPENGIST_HOME_INTERNAL/symlinks/config.yml hook %s
`
11 changes: 9 additions & 2 deletions internal/git/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ func TestContent(t *testing.T) {
"my_other_file.txt": `I really
hate Opengist`,
"rip.txt": "byebye",
"中文名.txt": "中文内容",
})

files, err := GetFilesOfRepository("thomas", "gist1", "HEAD")
require.NoError(t, err, "Could not get files of repository")
require.Subset(t, []string{"my_file.txt", "my_other_file.txt", "rip.txt"}, files, "Files are not correct")
require.Subset(t, []string{"my_file.txt", "my_other_file.txt", "rip.txt", "中文名.txt"}, files, "Files are not correct")

content, truncated, err := GetFileContent("thomas", "gist1", "HEAD", "my_file.txt", false)
require.NoError(t, err, "Could not get content")
Expand All @@ -77,16 +78,22 @@ hate Opengist`,
require.False(t, truncated, "Content should not be truncated")
require.Equal(t, "I really\nhate Opengist", content, "Content is not correct")

content, truncated, err = GetFileContent("thomas", "gist1", "HEAD", "中文名.txt", false)
require.NoError(t, err, "Could not get content")
require.False(t, truncated, "Content should not be truncated")
require.Equal(t, "中文内容", content, "Content is not correct")

CommitToBare(t, "thomas", "gist1", map[string]string{
"my_renamed_file.txt": "I love Opengist\n",
"my_other_file.txt": `I really
like Opengist actually`,
"new_file.txt": "Wait now there is a new file",
"中文名.txt": "中文内容",
})

files, err = GetFilesOfRepository("thomas", "gist1", "HEAD")
require.NoError(t, err, "Could not get files of repository")
require.Subset(t, []string{"my_renamed_file.txt", "my_other_file.txt", "new_file.txt"}, files, "Files are not correct")
require.Subset(t, []string{"my_renamed_file.txt", "my_other_file.txt", "new_file.txt", "中文名.txt"}, files, "Files are not correct")

content, truncated, err = GetFileContent("thomas", "gist1", "HEAD", "my_other_file.txt", false)
require.NoError(t, err, "Could not get content")
Expand Down
12 changes: 6 additions & 6 deletions internal/git/output_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,28 +193,28 @@ loopLog:
case strings.HasPrefix(line, "dissimilarity index"):
continue
case strings.HasPrefix(line, "rename from "):
currentFile.OldFilename = line[12 : len(line)-1]
currentFile.OldFilename = convertOctalToUTF8(line[12 : len(line)-1])
case strings.HasPrefix(line, "rename to "):
currentFile.Filename = line[10 : len(line)-1]
currentFile.Filename = convertOctalToUTF8(line[10 : len(line)-1])
parseRename = false
case strings.HasPrefix(line, "copy from "):
currentFile.OldFilename = line[10 : len(line)-1]
currentFile.OldFilename = convertOctalToUTF8(line[10 : len(line)-1])
case strings.HasPrefix(line, "copy to "):
currentFile.Filename = line[8 : len(line)-1]
currentFile.Filename = convertOctalToUTF8(line[8 : len(line)-1])
parseRename = false
case strings.HasPrefix(line, "new file"):
currentFile.IsCreated = true
case strings.HasPrefix(line, "deleted file"):
currentFile.IsDeleted = true
case strings.HasPrefix(line, "--- "):
name := line[4 : len(line)-1]
name := convertOctalToUTF8(line[4 : len(line)-1])
if parseRename && currentFile.IsDeleted {
currentFile.Filename = name[2:]
} else if parseRename && strings.HasPrefix(name, "a/") {
currentFile.OldFilename = name[2:]
}
case strings.HasPrefix(line, "+++ "):
name := line[4 : len(line)-1]
name := convertOctalToUTF8(line[4 : len(line)-1])
if parseRename && strings.HasPrefix(name, "b/") {
currentFile.Filename = name[2:]
}
Expand Down

0 comments on commit c1e046f

Please sign in to comment.