Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to merge if file path contains " or \ #8629

Merged
merged 9 commits into from
Nov 1, 2019
Merged
38 changes: 36 additions & 2 deletions services/pull/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -378,22 +379,55 @@ func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) {
getDiffTreeFromBranch := func(repoPath, baseBranch, headBranch string) (string, error) {
var outbuf, errbuf strings.Builder
// Compute the diff-tree for sparse-checkout
if err := git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "--root", baseBranch, headBranch, "--").RunInDirPipeline(repoPath, &outbuf, &errbuf); err != nil {
if err := git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-z", "--root", baseBranch, headBranch, "--").RunInDirPipeline(repoPath, &outbuf, &errbuf); err != nil {
return "", fmt.Errorf("git diff-tree [%s base:%s head:%s]: %s", repoPath, baseBranch, headBranch, errbuf.String())
}
return outbuf.String(), nil
}

scanNullTerminatedStrings := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, '\x00'); i >= 0 {
return i + 1, data[0:i], nil
}
if atEOF {
return len(data), data, nil
}
return 0, nil, nil
}

list, err := getDiffTreeFromBranch(repoPath, baseBranch, headBranch)
if err != nil {
return "", err
}

// Prefixing '/' for each entry, otherwise all files with the same name in subdirectories would be matched.
rightTrailingSpacesRE := regexp.MustCompile(`\ +$`)
optionalNPrefixRE := regexp.MustCompile(`(?:^|/)(!.+?)$`)
zeripath marked this conversation as resolved.
Show resolved Hide resolved

out := bytes.Buffer{}
scanner := bufio.NewScanner(strings.NewReader(list))
scanner.Split(scanNullTerminatedStrings)
for scanner.Scan() {
fmt.Fprintf(&out, "/%s\n", scanner.Text())
filepath := scanner.Text()

// Trailing spaces
filepath = rightTrailingSpacesRE.ReplaceAllStringFunc(filepath, func(s string) string {
return strings.Repeat(`\ `, len(s))
})

// An optional prefix !
filepath = optionalNPrefixRE.ReplaceAllString(filepath, `\$1`)

// * ? [
filepath = strings.Replace(filepath, "*", `\*`, -1)
zeripath marked this conversation as resolved.
Show resolved Hide resolved
filepath = strings.Replace(filepath, "?", `\?`, -1)
filepath = strings.Replace(filepath, "[", `\[`, -1)
fmt.Printf("%s\n", filepath)
fmt.Fprintf(&out, "/%s\n", filepath)
zeripath marked this conversation as resolved.
Show resolved Hide resolved
}

return out.String(), nil
}