ed3decf753
A number of message strings contain embedded Git or Git LFS commands, and while in many cases these are already delimited with backticks, in other cases they are not. We therefore rework the formatting of these messages to accord with the general practice of using backticks to delimit "git" and "git lfs" commands. In one case for the "git lfs clone" command this requires us to split a multi-line message into several parts, but that also has the advantage that we can move some of the fixed formatting and newlines out of the translatable message strings. Note that some of these messages are not yet passed as translation strings, but we will address that issue in a subsequent commit.
93 lines
1.9 KiB
Go
93 lines
1.9 KiB
Go
package git
|
|
|
|
import (
|
|
"bufio"
|
|
"io/ioutil"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/git-lfs/git-lfs/v3/errors"
|
|
"github.com/git-lfs/git-lfs/v3/tools"
|
|
"github.com/rubyist/tracerx"
|
|
)
|
|
|
|
type lsFileInfo struct {
|
|
BaseName string
|
|
FullPath string
|
|
}
|
|
type LsFiles struct {
|
|
Files map[string]*lsFileInfo
|
|
FilesByName map[string][]*lsFileInfo
|
|
}
|
|
|
|
func NewLsFiles(workingDir string, standardExclude bool, untracked bool) (*LsFiles, error) {
|
|
|
|
args := []string{
|
|
"ls-files",
|
|
"-z", // Use a NUL separator. This also disables the escaping of special characters.
|
|
"--cached",
|
|
}
|
|
|
|
if standardExclude {
|
|
args = append(args, "--exclude-standard")
|
|
}
|
|
if untracked {
|
|
args = append(args, "--others")
|
|
}
|
|
cmd := gitNoLFS(args...)
|
|
cmd.Dir = workingDir
|
|
|
|
tracerx.Printf("NewLsFiles: running in %s git %s",
|
|
workingDir, strings.Join(args, " "))
|
|
|
|
// Capture stdout and stderr
|
|
stdout, err := cmd.StdoutPipe()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stderr, err := cmd.StderrPipe()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
scanner := bufio.NewScanner(stdout)
|
|
scanner.Split(tools.SplitOnNul)
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rv := &LsFiles{
|
|
Files: make(map[string]*lsFileInfo),
|
|
FilesByName: make(map[string][]*lsFileInfo),
|
|
}
|
|
|
|
// Setup a goroutine to drain stderr as large amounts of error output may cause
|
|
// the subprocess to block.
|
|
errorMessages := make(chan []byte)
|
|
go func() {
|
|
msg, _ := ioutil.ReadAll(stderr)
|
|
errorMessages <- msg
|
|
}()
|
|
|
|
// Read all files
|
|
for scanner.Scan() {
|
|
base := path.Base(scanner.Text())
|
|
finfo := &lsFileInfo{
|
|
BaseName: base,
|
|
FullPath: scanner.Text(),
|
|
}
|
|
rv.Files[scanner.Text()] = finfo
|
|
rv.FilesByName[base] = append(rv.FilesByName[base], finfo)
|
|
}
|
|
|
|
// Check the output of the subprocess, output stderr if the command failed.
|
|
msg := <-errorMessages
|
|
if err := cmd.Wait(); err != nil {
|
|
return nil, errors.Errorf("Error in `git %s`: %v %s",
|
|
strings.Join(args, " "), err, msg)
|
|
}
|
|
|
|
return rv, nil
|
|
}
|