# Git LFS Changelog
+## 2.5.2 (17 September, 2018)
+
+### Bugs
+
+* config: Treat [host:port]:path URLs correctly #3226 (@saschpe)
+* tq: Always provide a Content-Type when uploading files #3201 (@bk2204)
+* commands/track: Properly `lfs track` files with escaped characters in their
+ name #3192 (@leonid-s-usov)
+
+### Misc
+
+* packagecloud.rb: remove older versions #3210 (@andyneff)
+
## 2.5.1 (2 August, 2018)
This release contains miscellaneous bug fixes since v2.5.0. Most notably,
pattern := trimCurrentPrefix(cleanRootPath(unsanitizedPattern))
if !trackNoModifyAttrsFlag {
for _, known := range knownPatterns {
- if known.Path == filepath.Join(relpath, pattern) &&
+ if unescapeAttrPattern(known.Path) == filepath.Join(relpath, pattern) &&
((trackLockableFlag && known.Lockable) || // enabling lockable & already lockable (no change)
(trackNotLockableFlag && !known.Lockable) || // disabling lockable & not lockable (no change)
(!trackLockableFlag && !trackNotLockableFlag)) { // leave lockable as-is in all cases
continue
}
- pattern := fields[0]
+ pattern := unescapeAttrPattern(fields[0])
if newline, ok := changedAttribLines[pattern]; ok {
// Replace this line (newline already embedded)
attributesFile.WriteString(newline)
)
const (
- Version = "2.5.1"
+ Version = "2.5.2"
)
func init() {
+git-lfs (2.5.2) stable; urgency=low
+
+ * New upstream version
+
+ -- Taylor Blau <me@ttaylorr.com> Mon, 17 Sep 2018 14:29:00 +0000
+
git-lfs (2.5.1) stable; urgency=low
* New upstream version
// endpointFromBareSshUrl constructs a new endpoint from a bare SSH URL:
//
-// user@host.com:path/to/repo.git
+// user@host.com:path/to/repo.git or
+// [user@host.com:port]:path/to/repo.git
//
func endpointFromBareSshUrl(rawurl string) Endpoint {
parts := strings.Split(rawurl, ":")
// Treat presence of ':' as a bare URL
var newPath string
if len(parts) > 2 { // port included; really should only ever be 3 parts
+ // Correctly handle [host:port]:path URLs
+ parts[0] = strings.TrimPrefix(parts[0], "[")
+ parts[1] = strings.TrimSuffix(parts[1], "]")
newPath = fmt.Sprintf("%v:%v", parts[0], strings.Join(parts[1:], "/"))
} else {
newPath = strings.Join(parts, "/")
assert.Equal(t, "", e.SshPort)
}
+func TestBareSSSHEndpointWithCustomPortInBrackets(t *testing.T) {
+ finder := NewEndpointFinder(NewContext(nil, nil, map[string]string{
+ "remote.origin.url": "[git@example.com:2222]:foo/bar.git",
+ }))
+
+ e := finder.Endpoint("download", "")
+ assert.Equal(t, "https://example.com/foo/bar.git/info/lfs", e.Url)
+ assert.Equal(t, "git@example.com", e.SshUserAndHost)
+ assert.Equal(t, "foo/bar.git", e.SshPath)
+ assert.Equal(t, "2222", e.SshPort)
+}
+
func TestSSHEndpointFromGlobalLfsUrl(t *testing.T) {
finder := NewEndpointFinder(NewContext(nil, nil, map[string]string{
"lfs.url": "git@example.com:foo/bar.git",
Name: git-lfs
-Version: 2.5.1
+Version: 2.5.2
Release: 1%{?dist}
Summary: Git extension for versioning large files
),
"centos/7" => %w(
el/7
- fedora/22
- fedora/23
- fedora/24
- fedora/25
- fedora/26
+ fedora/27
+ fedora/28
+ opensuse/42.3
+ sles/11.4
+ sles/12.3
),
"debian/7" => %w(
debian/wheezy
linuxmint/serena
linuxmint/sonya
linuxmint/sylvia
+ linuxmint/tara
ubuntu/xenial
ubuntu/yakkety
ubuntu/zesty
GIT_CURL_VERBOSE=1 git push origin master 2>&1 | tee push.log
[ 1 -eq "$(grep -c "Content-Type: application/x-gzip" push.log)" ]
+ [ 0 -eq "$(grep -c "Content-Type: application/octet-stream" push.log)" ]
)
end_test
GIT_CURL_VERBOSE=1 git push origin master 2>&1 | tee push.log
[ 0 -eq "$(grep -c "Content-Type: application/x-gzip" push.log)" ]
+ [ 1 -eq "$(grep -c "Content-Type: application/octet-stream" push.log)" ]
)
end_test
grep "*.dat" track.log
)
end_test
+
+begin_test "track: escaped pattern in .gitattributes"
+(
+ set -e
+
+ reponame="track-escaped"
+ git init "$reponame"
+ cd "$reponame"
+
+ filename="file with spaces.#"
+
+ echo "I need escaping" > "$filename"
+
+ [ "Tracking \"$filename\"" = "$(git lfs track "$filename")" ]
+ [ "\"$filename\" already supported" = "$(git lfs track "$filename")" ]
+
+ #changing flags should track the file again
+ [ "Tracking \"$filename\"" = "$(git lfs track -l "$filename")" ]
+
+ if [ 1 -ne "$(wc -l .gitattributes | awk '{ print $1 }')" ]; then
+ echo >&2 "changing flag for an existing tracked file shouldn't add another line"
+ exit 1
+ fi
+)
+end_test
git lfs untrack "./a.dat"
if [ ! -z "$(cat .gitattributes)" ]; then
- echo &>2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
+ echo >&2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
exit 1
fi
git lfs untrack "a.dat"
if [ ! -z "$(cat .gitattributes)" ]; then
- echo &>2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
+ echo >&2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
exit 1
fi
)
git lfs untrack "./a.dat"
if [ ! -z "$(cat .gitattributes)" ]; then
- echo &>2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
+ echo >&2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
exit 1
fi
git lfs untrack "a.dat"
if [ ! -z "$(cat .gitattributes)" ]; then
- echo &>2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
+ echo >&2 "fatal: expected 'git lfs untrack' to clear .gitattributes"
+ exit 1
+ fi
+)
+end_test
+
+begin_test "untrack removes escaped pattern in .gitattributes"
+(
+ set -e
+
+ reponame="untrack-escaped"
+ git init "$reponame"
+ cd "$reponame"
+
+ filename="file with spaces.#"
+
+ # emulate multiple instances of the same file in gitattributes
+ echo 'file[[:space:]]with[[:space:]]spaces.\# filter=lfs diff=lfs merge=lfs -text' >> .gitattributes
+ echo 'file[[:space:]]with[[:space:]]spaces.\# filter=lfs diff=lfs merge=lfs -text' >> .gitattributes
+ echo 'file[[:space:]]with[[:space:]]spaces.\# filter=lfs diff=lfs merge=lfs -text' >> .gitattributes
+
+ git lfs untrack "$filename"
+
+ if [ ! -z "$(cat .gitattributes)" ]; then
+ echo >&2 "fatal: expected 'git lfs untrack' to clear .gitattributes even if the file name was escaped"
exit 1
fi
)
func (a *adapterBase) setContentTypeFor(req *http.Request, r io.ReadSeeker) error {
uc := config.NewURLConfig(a.apiClient.GitEnv())
disabled := !uc.Bool("lfs", req.URL.String(), "contenttype", true)
- if len(req.Header.Get("Content-Type")) != 0 || disabled {
+ if len(req.Header.Get("Content-Type")) != 0 {
return nil
}
- buffer := make([]byte, 512)
- n, err := r.Read(buffer)
- if err != nil && err != io.EOF {
- return errors.Wrap(err, "content type detect")
- }
+ var contentType string
+
+ if !disabled {
+ buffer := make([]byte, 512)
+ n, err := r.Read(buffer)
+ if err != nil && err != io.EOF {
+ return errors.Wrap(err, "content type detect")
+ }
- contentType := http.DetectContentType(buffer[:n])
- if _, err := r.Seek(0, 0); err != nil {
- return errors.Wrap(err, "content type rewind")
+ contentType = http.DetectContentType(buffer[:n])
+ if _, err := r.Seek(0, io.SeekStart); err != nil {
+ return errors.Wrap(err, "content type rewind")
+ }
}
if contentType == "" {
"FileVersion": {
"Major": 2,
"Minor": 5,
- "Patch": 1,
+ "Patch": 2,
"Build": 0
}
},
"FileDescription": "Git LFS",
"LegalCopyright": "GitHub, Inc. and Git LFS contributors",
"ProductName": "Git Large File Storage (LFS)",
- "ProductVersion": "2.5.1"
+ "ProductVersion": "2.5.2"
},
"IconPath": "script/windows-installer/git-lfs-logo.ico"
}