Merge branch 'master' into status-in-sub-directory
This commit is contained in:
commit
5899e91ad7
@ -34,7 +34,9 @@ setup and preferences.
|
||||
|
||||
In addition, [binary packages](https://github.com/git-lfs/git-lfs/releases) are
|
||||
available for Linux, macOS, Windows, and FreeBSD. This repository can also be
|
||||
built-from-source using the latest version of [Go](https://golang.org).
|
||||
built from source using the latest version of [Go](https://golang.org), and the
|
||||
available instructions in our
|
||||
[Wiki](https://github.com/git-lfs/git-lfs/wiki/Installation#source).
|
||||
|
||||
### Usage
|
||||
|
||||
|
@ -49,6 +49,8 @@ func trackCommand(cmd *cobra.Command, args []string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Intentionally do _not_ consider global- and system-level
|
||||
// .gitattributes here.
|
||||
knownPatterns := git.GetAttributePaths(cfg.LocalWorkingDir(), cfg.LocalGitDir())
|
||||
lineEnd := getAttributeLineEnding(knownPatterns)
|
||||
if len(lineEnd) == 0 {
|
||||
@ -213,7 +215,7 @@ ArgsLoop:
|
||||
}
|
||||
|
||||
func listPatterns() {
|
||||
knownPatterns := git.GetAttributePaths(cfg.LocalWorkingDir(), cfg.LocalGitDir())
|
||||
knownPatterns := getAllKnownPatterns()
|
||||
if len(knownPatterns) < 1 {
|
||||
return
|
||||
}
|
||||
@ -228,6 +230,14 @@ func listPatterns() {
|
||||
}
|
||||
}
|
||||
|
||||
func getAllKnownPatterns() []git.AttributePath {
|
||||
knownPatterns := git.GetAttributePaths(cfg.LocalWorkingDir(), cfg.LocalGitDir())
|
||||
knownPatterns = append(knownPatterns, git.GetRootAttributePaths(cfg.Git)...)
|
||||
knownPatterns = append(knownPatterns, git.GetSystemAttributePaths(cfg.Os)...)
|
||||
|
||||
return knownPatterns
|
||||
}
|
||||
|
||||
func getAttributeLineEnding(attribs []git.AttributePath) string {
|
||||
for _, a := range attribs {
|
||||
if a.Source.Path == ".gitattributes" {
|
||||
|
@ -59,6 +59,6 @@ to match paths.
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
git-lfs-untrack(1), git-lfs-install(1), gitattributes(5).
|
||||
git-lfs-untrack(1), git-lfs-install(1), gitattributes(5), gitignore(5).
|
||||
|
||||
Part of the git-lfs(1) suite.
|
||||
|
@ -85,3 +85,28 @@ commands and low level ("plumbing") commands.
|
||||
Git process filter that converts between large files and pointers.
|
||||
* git-lfs-smudge(1):
|
||||
Git smudge filter that converts pointer in blobs to the actual content.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
To get started with Git LFS, the following commands can be used.
|
||||
|
||||
1. Setup Git LFS on your system. You only have to do this once per
|
||||
repository per machine:
|
||||
|
||||
git lfs install
|
||||
|
||||
2. Choose the type of files you want to track, for examples all `ISO`
|
||||
images, with git-lfs-track(1):
|
||||
|
||||
git lfs track "*.iso"
|
||||
|
||||
3. The above stores this information in gitattributes(5) files, so
|
||||
that file need to be added to the repository:
|
||||
|
||||
git add .gitattributes
|
||||
|
||||
3. Commit, push and work with the files normally:
|
||||
|
||||
git add file.iso
|
||||
git commit -m "Add disk image"
|
||||
git push
|
||||
|
122
git/attribs.go
122
git/attribs.go
@ -35,6 +35,36 @@ func (s *AttributeSource) String() string {
|
||||
return s.Path
|
||||
}
|
||||
|
||||
// GetRootAttributePaths beahves as GetRootAttributePaths, and loads information
|
||||
// only from the global gitattributes file.
|
||||
func GetRootAttributePaths(cfg Env) []AttributePath {
|
||||
af, ok := cfg.Get("core.attributesfile")
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
// The working directory for the root gitattributes file is blank.
|
||||
return attrPaths(af, "")
|
||||
}
|
||||
|
||||
// GetSystemAttributePaths behaves as GetAttributePaths, and loads information
|
||||
// only from the system gitattributes file, respecting the $PREFIX environment
|
||||
// variable.
|
||||
func GetSystemAttributePaths(env Env) []AttributePath {
|
||||
prefix, _ := env.Get("PREFIX")
|
||||
if len(prefix) == 0 {
|
||||
prefix = string(filepath.Separator)
|
||||
}
|
||||
|
||||
path := filepath.Join(prefix, "etc", "gitattributes")
|
||||
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return attrPaths(path, "")
|
||||
}
|
||||
|
||||
// GetAttributePaths returns a list of entries in .gitattributes which are
|
||||
// configured with the filter=lfs attribute
|
||||
// workingDir is the root of the working copy
|
||||
@ -43,58 +73,66 @@ func GetAttributePaths(workingDir, gitDir string) []AttributePath {
|
||||
paths := make([]AttributePath, 0)
|
||||
|
||||
for _, path := range findAttributeFiles(workingDir, gitDir) {
|
||||
attributes, err := os.Open(path)
|
||||
if err != nil {
|
||||
paths = append(paths, attrPaths(path, workingDir)...)
|
||||
}
|
||||
|
||||
return paths
|
||||
}
|
||||
|
||||
func attrPaths(path, workingDir string) []AttributePath {
|
||||
attributes, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var paths []AttributePath
|
||||
|
||||
relfile, _ := filepath.Rel(workingDir, path)
|
||||
reldir := filepath.Dir(relfile)
|
||||
source := &AttributeSource{Path: relfile}
|
||||
|
||||
le := &lineEndingSplitter{}
|
||||
scanner := bufio.NewScanner(attributes)
|
||||
scanner.Split(le.ScanLines)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
if strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
relfile, _ := filepath.Rel(workingDir, path)
|
||||
reldir := filepath.Dir(relfile)
|
||||
source := &AttributeSource{Path: relfile}
|
||||
// Check for filter=lfs (signifying that LFS is tracking
|
||||
// this file) or "lockable", which indicates that the
|
||||
// file is lockable (and may or may not be tracked by
|
||||
// Git LFS).
|
||||
if strings.Contains(line, "filter=lfs") ||
|
||||
strings.HasSuffix(line, "lockable") {
|
||||
|
||||
le := &lineEndingSplitter{}
|
||||
scanner := bufio.NewScanner(attributes)
|
||||
scanner.Split(le.ScanLines)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
if strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
fields := strings.Fields(line)
|
||||
pattern := fields[0]
|
||||
if len(reldir) > 0 {
|
||||
pattern = filepath.Join(reldir, pattern)
|
||||
}
|
||||
|
||||
// Check for filter=lfs (signifying that LFS is tracking
|
||||
// this file) or "lockable", which indicates that the
|
||||
// file is lockable (and may or may not be tracked by
|
||||
// Git LFS).
|
||||
if strings.Contains(line, "filter=lfs") ||
|
||||
strings.HasSuffix(line, "lockable") {
|
||||
|
||||
fields := strings.Fields(line)
|
||||
pattern := fields[0]
|
||||
if len(reldir) > 0 {
|
||||
pattern = filepath.Join(reldir, pattern)
|
||||
// Find lockable flag in any position after pattern to avoid
|
||||
// edge case of matching "lockable" to a file pattern
|
||||
lockable := false
|
||||
for _, f := range fields[1:] {
|
||||
if f == LockableAttrib {
|
||||
lockable = true
|
||||
break
|
||||
}
|
||||
// Find lockable flag in any position after pattern to avoid
|
||||
// edge case of matching "lockable" to a file pattern
|
||||
lockable := false
|
||||
for _, f := range fields[1:] {
|
||||
if f == LockableAttrib {
|
||||
lockable = true
|
||||
break
|
||||
}
|
||||
}
|
||||
paths = append(paths, AttributePath{
|
||||
Path: pattern,
|
||||
Source: source,
|
||||
Lockable: lockable,
|
||||
})
|
||||
}
|
||||
paths = append(paths, AttributePath{
|
||||
Path: pattern,
|
||||
Source: source,
|
||||
Lockable: lockable,
|
||||
})
|
||||
}
|
||||
|
||||
source.LineEnding = le.LineEnding()
|
||||
}
|
||||
|
||||
source.LineEnding = le.LineEnding()
|
||||
|
||||
return paths
|
||||
}
|
||||
|
||||
|
@ -49,13 +49,6 @@ func proxyFromClient(c *Client) func(req *http.Request) (*url.URL, error) {
|
||||
}
|
||||
|
||||
func getProxyServers(u *url.URL, urlCfg *config.URLConfig, osEnv config.Environment) (httpsProxy string, httpProxy string, noProxy string) {
|
||||
if urlCfg != nil {
|
||||
httpProxy, _ = urlCfg.Get("http", u.String(), "proxy")
|
||||
if strings.HasPrefix(httpProxy, "https://") {
|
||||
httpsProxy = httpProxy
|
||||
}
|
||||
}
|
||||
|
||||
if osEnv == nil {
|
||||
return
|
||||
}
|
||||
@ -76,6 +69,16 @@ func getProxyServers(u *url.URL, urlCfg *config.URLConfig, osEnv config.Environm
|
||||
httpProxy, _ = osEnv.Get("http_proxy")
|
||||
}
|
||||
|
||||
if urlCfg != nil {
|
||||
gitProxy, ok := urlCfg.Get("http", u.String(), "proxy")
|
||||
if len(gitProxy) > 0 && ok {
|
||||
if strings.HasPrefix(gitProxy, "https://") {
|
||||
httpsProxy = gitProxy
|
||||
}
|
||||
httpProxy = gitProxy
|
||||
}
|
||||
}
|
||||
|
||||
noProxy, _ = osEnv.Get("NO_PROXY")
|
||||
if len(noProxy) == 0 {
|
||||
noProxy, _ = osEnv.Get("no_proxy")
|
||||
|
@ -20,7 +20,7 @@ func TestHttpsProxyFromGitConfig(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
|
||||
proxyURL, err := proxyFromClient(c)(req)
|
||||
assert.Equal(t, "proxy-from-git-config:8080", proxyURL.Host)
|
||||
assert.Equal(t, "proxy-from-env:8080", proxyURL.Host)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
|
@ -558,3 +558,40 @@ begin_test "track (with current-directory prefix)"
|
||||
grep -e "^a.dat" .gitattributes
|
||||
)
|
||||
end_test
|
||||
|
||||
begin_test "track (global gitattributes)"
|
||||
(
|
||||
set -e
|
||||
|
||||
reponame="track-global-gitattributes"
|
||||
git init "$reponame"
|
||||
cd "$reponame"
|
||||
|
||||
global="$(cd .. && pwd)/gitattributes-global"
|
||||
|
||||
echo "*.dat filter=lfs diff=lfs merge=lfs -text" > "$global"
|
||||
git config --local core.attributesfile "$global"
|
||||
|
||||
git lfs track 2>&1 | tee track.log
|
||||
grep "*.dat" track.log
|
||||
)
|
||||
end_test
|
||||
|
||||
begin_test "track (system gitattributes)"
|
||||
(
|
||||
set -e
|
||||
|
||||
reponame="track-system-gitattributes"
|
||||
git init "$reponame"
|
||||
cd "$reponame"
|
||||
|
||||
pushd "$TRASHDIR" > /dev/null
|
||||
mkdir -p "prefix/${reponame}/etc"
|
||||
cd "prefix/${reponame}/etc"
|
||||
echo "*.dat filter=lfs diff=lfs merge=lfs -text" > gitattributes
|
||||
popd > /dev/null
|
||||
|
||||
PREFIX="${TRASHDIR}/prefix/${reponame}" git lfs track 2>&1 | tee track.log
|
||||
grep "*.dat" track.log
|
||||
)
|
||||
end_test
|
||||
|
Loading…
Reference in New Issue
Block a user