cd1577af24
Git doesn't know about untracked files, so we should avoid modifying them when we adjust permissions in the post-checkout hook. Add an option to our invocation of git ls-files that controls the use of the --others flag (which controls listing untracked files), and disable it when we're looking for files to process with the post-checkout hook.
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
|
|
}
|