commit git-lfs for openSUSE:Factory
Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package git-lfs for openSUSE:Factory checked in at 2021-11-03 17:26:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/git-lfs (Old) and /work/SRC/openSUSE:Factory/.git-lfs.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "git-lfs" Wed Nov 3 17:26:16 2021 rev:8 rq:928942 version:3.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/git-lfs/git-lfs.changes 2021-10-06 19:50:15.228066029 +0200 +++ /work/SRC/openSUSE:Factory/.git-lfs.new.1890/git-lfs.changes 2021-11-03 17:27:07.449365386 +0100 @@ -1,0 +2,6 @@ +Sun Oct 31 10:22:55 UTC 2021 - Marcus Rueckert <mrueckert@suse.de> + +- update to 3.0.2 + https://github.com/git-lfs/git-lfs/releases/tag/v3.0.2 + +------------------------------------------------------------------- Old: ---- git-lfs-3.0.1.tar.gz New: ---- git-lfs-3.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ git-lfs.spec ++++++ --- /var/tmp/diff_new_pack.QMUbkv/_old 2021-11-03 17:27:07.925365647 +0100 +++ /var/tmp/diff_new_pack.QMUbkv/_new 2021-11-03 17:27:07.929365649 +0100 @@ -18,13 +18,15 @@ %define rb_build_ruby_abis %{rb_default_ruby_abi} %define rb_build_versions %{rb_default_ruby} + %if 0%{?suse_version} >= 1550 || (0%{?suse_version} >= 1500 && 0%{?is_opensuse}) %bcond_with build_docs %else %bcond_with build_docs %endif + Name: git-lfs -Version: 3.0.1 +Version: 3.0.2 Release: 0 Summary: Git extension for versioning large files License: MIT ++++++ git-lfs-3.0.1.tar.gz -> git-lfs-3.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/CHANGELOG.md new/git-lfs-3.0.2/CHANGELOG.md --- old/git-lfs-3.0.1/CHANGELOG.md 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/CHANGELOG.md 2021-10-28 18:50:56.000000000 +0200 @@ -1,5 +1,33 @@ # Git LFS Changelog +## 3.0.2 (28 Oct 2021) + +This release is a bugfix release which fixes a variety of problems seen since +3.0.0, including problems with empty files, `git lfs fsck --pointers`, and +the testsuite. + +We would like to extend a special thanks to the following open-source +contributors: + +* @fh1ch for patches to make things work better on Alpine Linux +* @pyckle for fixing our handling of filenames in `git lfs migrate import` +* @ycongal-smile for fixing `git lfs migrate import` with similarly named files + +### Bugs + +* Fix two types of misdetection in git lfs fsck #4697 (@bk2204) +* lfs: don't flag non-LFS files as invalid pointers #4691 (@bk2204) +* git: honor GIT_OBJECT_DIRECTORY #4686 (@bk2204) +* migrate: properly escape blob filenames #4683 (@pyckle) +* ls-files: don't process empty files as pointers #4681 (@bk2204) +* Call migrate() BlobFn on every blob #4671 (@ycongal-smile) +* Correct t-lock regular expression to be musl compatible #4673 (@fh1ch) + +### Misc + +* Allow git-lfs-transfer integration tests to be skipped #4677 (@fh1ch) +* Make CI environment GIT prefix grep more specific #4678 (@fh1ch) + ## 3.0.1 (28 Sep 2021) This release is a bugfix release which fixes the Windows ARM64 build process and diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/commands/command_ls_files.go new/git-lfs-3.0.2/commands/command_ls_files.go --- old/git-lfs-3.0.1/commands/command_ls_files.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/commands/command_ls_files.go 2021-10-28 18:50:56.000000000 +0200 @@ -68,6 +68,10 @@ return } + if p.Size == 0 { + return + } + if !lsFilesScanAll && !scanRange { if _, ok := seen[p.Name]; ok { return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/commands/command_migrate_export.go new/git-lfs-3.0.2/commands/command_migrate_export.go --- old/git-lfs-3.0.1/commands/command_migrate_export.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/commands/command_migrate_export.go 2021-10-28 18:50:56.000000000 +0200 @@ -43,7 +43,7 @@ opts := &githistory.RewriteOptions{ Verbose: migrateVerbose, ObjectMapFilePath: objectMapFilePath, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, oid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { if filepath.Base(path) == ".gitattributes" { return b, nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/commands/command_migrate_import.go new/git-lfs-3.0.2/commands/command_migrate_import.go --- old/git-lfs-3.0.1/commands/command_migrate_import.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/commands/command_migrate_import.go 2021-10-28 18:50:56.000000000 +0200 @@ -139,10 +139,12 @@ ExitWithError(errors.Wrap(err, "fatal: cannot parse --above=<n>")) } + blobCache := make(map[string]bytes.Buffer) + migrate(args, rewriter, l, &githistory.RewriteOptions{ Verbose: migrateVerbose, ObjectMapFilePath: objectMapFilePath, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { if filepath.Base(path) == ".gitattributes" { return b, nil } @@ -166,14 +168,18 @@ var buf bytes.Buffer - if _, err := clean(gitfilter, &buf, b.Contents, path, b.Size); err != nil { - return nil, err + buf, cached := blobCache[hex.EncodeToString(origOid)] + if !cached { + if _, err := clean(gitfilter, &buf, b.Contents, path, b.Size); err != nil { + return nil, err + } + blobCache[hex.EncodeToString(origOid)] = buf } if ext := filepath.Ext(path); len(ext) > 0 && above == 0 { exts.Add(fmt.Sprintf("*%s filter=lfs diff=lfs merge=lfs -text", ext)) } else { - exts.Add(fmt.Sprintf("/%s filter=lfs diff=lfs merge=lfs -text", path)) + exts.Add(fmt.Sprintf("/%s filter=lfs diff=lfs merge=lfs -text", escapeGlobCharacters(path))) } return &gitobj.Blob{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/commands/command_migrate_info.go new/git-lfs-3.0.2/commands/command_migrate_info.go --- old/git-lfs-3.0.1/commands/command_migrate_info.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/commands/command_migrate_info.go 2021-10-28 18:50:56.000000000 +0200 @@ -1,6 +1,7 @@ package commands import ( + "encoding/hex" "fmt" "io" "os" @@ -114,8 +115,10 @@ pointersInfoEntry := &MigrateInfoEntry{Qualifier: "LFS Objects", Separate: true} var fixups *gitattr.Tree + blobSeenSet := make(map[string]struct{}) + migrate(args, rewriter, l, &githistory.RewriteOptions{ - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { var entry *MigrateInfoEntry var size int64 var p *lfs.Pointer @@ -138,25 +141,31 @@ } } - if migrateInfoPointersMode != migrateInfoPointersNoFollow { - p, err = lfs.DecodePointerFromBlob(b) - } - if p != nil && err == nil { - if migrateInfoPointersMode == migrateInfoPointersIgnore { - return b, nil + _, seen := blobSeenSet[hex.EncodeToString(origOid)] + if !seen { + blobSeenSet[hex.EncodeToString(origOid)] = struct{}{} + + if migrateInfoPointersMode != migrateInfoPointersNoFollow { + p, err = lfs.DecodePointerFromBlob(b) + } + if p != nil && err == nil { + if migrateInfoPointersMode == migrateInfoPointersIgnore { + return b, nil + } + entry = pointersInfoEntry + size = p.Size + } else { + entry = findEntryByExtension(exts, path) + size = b.Size } - entry = pointersInfoEntry - size = p.Size - } else { - entry = findEntryByExtension(exts, path) - size = b.Size - } - entry.Total++ + entry.Total++ + + if size > int64(migrateInfoAbove) { + entry.TotalAbove++ + entry.BytesAbove += size + } - if size > int64(migrateInfoAbove) { - entry.TotalAbove++ - entry.BytesAbove += size } return b, nil diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/config/version.go new/git-lfs-3.0.2/config/version.go --- old/git-lfs-3.0.1/config/version.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/config/version.go 2021-10-28 18:50:56.000000000 +0200 @@ -13,7 +13,7 @@ ) const ( - Version = "3.0.1" + Version = "3.0.2" ) func init() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/debian/changelog new/git-lfs-3.0.2/debian/changelog --- old/git-lfs-3.0.1/debian/changelog 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/debian/changelog 2021-10-28 18:50:56.000000000 +0200 @@ -1,3 +1,9 @@ +git-lfs (3.0.2) stable; urgency=low + + * New upstream version + + -- brian m. carlson <bk2204@github.com> Thu, 28 Oct 2021 14:29:00 -0000 + git-lfs (3.0.1) stable; urgency=low * New upstream version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/git/git.go new/git-lfs-3.0.2/git/git.go --- old/git-lfs-3.0.1/git/git.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/git/git.go 2021-10-28 18:50:56.000000000 +0200 @@ -1404,6 +1404,10 @@ func ObjectDatabase(osEnv, gitEnv Environment, gitdir, tempdir string) (*gitobj.ObjectDatabase, error) { var options []gitobj.Option + objdir, ok := osEnv.Get("GIT_OBJECT_DIRECTORY") + if !ok { + objdir = filepath.Join(gitdir, "objects") + } alternates, _ := osEnv.Get("GIT_ALTERNATE_OBJECT_DIRECTORIES") if alternates != "" { options = append(options, gitobj.Alternates(alternates)) @@ -1412,7 +1416,7 @@ if hashAlgo != "" { options = append(options, gitobj.ObjectFormat(gitobj.ObjectFormatAlgorithm(hashAlgo))) } - odb, err := gitobj.FromFilesystem(filepath.Join(gitdir, "objects"), tempdir, options...) + odb, err := gitobj.FromFilesystem(objdir, tempdir, options...) if err != nil { return nil, err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/git/githistory/rewriter.go new/git-lfs-3.0.2/git/githistory/rewriter.go --- old/git-lfs-3.0.1/git/githistory/rewriter.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/git/githistory/rewriter.go 2021-10-28 18:50:56.000000000 +0200 @@ -116,9 +116,11 @@ // instance, a file "b.txt" in directory "dir" would be given as "/dir/b.txt", // where as a file "a.txt" in the root would be given as "/a.txt". // +// The origOid argument is the OID (i.e. the SHA) of the blob to be rewritten. +// // As above, the path separators are OS specific, and equivalent to the result // of filepath.Join(...) or os.PathSeparator. -type BlobRewriteFn func(path string, b *gitobj.Blob) (*gitobj.Blob, error) +type BlobRewriteFn func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) // TreePreCallbackFn specifies a function to call upon opening a new tree for // rewriting. @@ -176,7 +178,7 @@ // noopBlobFn is a no-op implementation of the BlobRewriteFn. It returns // the blob that it was given, and returns no error. - noopBlobFn = func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { return b, nil } + noopBlobFn = func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { return b, nil } // noopTreePreFn is a no-op implementation of the TreePreRewriteFn. It // returns the tree that it was given, and returns no error. noopTreePreFn = func(path string, t *gitobj.Tree) error { return nil } @@ -383,12 +385,6 @@ continue } - if cached := r.uncacheEntry(entry); cached != nil { - entries = append(entries, copyEntryMode(cached, - entry.Filemode)) - continue - } - var oid []byte switch entry.Type() { @@ -465,7 +461,7 @@ return nil, err } - b, err := fn(path, blob) + b, err := fn(path, from, blob) if err != nil { return nil, err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/git/githistory/rewriter_test.go new/git-lfs-3.0.2/git/githistory/rewriter_test.go --- old/git-lfs-3.0.1/git/githistory/rewriter_test.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/git/githistory/rewriter_test.go 2021-10-28 18:50:56.000000000 +0200 @@ -21,7 +21,7 @@ r := NewRewriter(db) tip, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { contents, err := ioutil.ReadAll(b.Contents) if err != nil { return nil, err @@ -82,7 +82,7 @@ r := NewRewriter(db) tip, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { return &gitobj.Blob{ Contents: io.MultiReader(b.Contents, strings.NewReader("_new")), Size: b.Size + int64(len("_new")), @@ -129,7 +129,7 @@ var contents []byte _, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { var err error contents, err = ioutil.ReadAll(b.Contents) @@ -148,14 +148,14 @@ assert.Equal(t, string(contents), "Hello, world!\n") } -func TestRewriterDoesntVisitUnchangedSubtrees(t *testing.T) { +func TestRewriterDoesVisitUnchangedSubtrees(t *testing.T) { db := DatabaseFromFixture(t, "repeated-subtrees.git") r := NewRewriter(db) seen := make(map[string]int) _, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { seen[path] = seen[path] + 1 return b, nil @@ -165,7 +165,7 @@ assert.Nil(t, err) assert.Equal(t, 2, seen["a.txt"]) - assert.Equal(t, 1, seen["subdir/b.txt"]) + assert.Equal(t, 2, seen["subdir/b.txt"]) } func TestRewriterVisitsUniqueEntriesWithIdenticalContents(t *testing.T) { @@ -173,7 +173,7 @@ r := NewRewriter(db) tip, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { if path == "b.txt" { return b, nil } @@ -213,7 +213,7 @@ seen := make(map[string]int) _, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { seen[path] = seen[path] + 1 return b, nil @@ -221,7 +221,7 @@ }) assert.Nil(t, err) - assert.Equal(t, 1, seen["a.txt"]) + assert.Equal(t, 2, seen["a.txt"]) assert.Equal(t, 0, seen["subdir/b.txt"]) } @@ -236,7 +236,7 @@ assert.Nil(t, err) tip, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { return b, nil }, @@ -307,7 +307,7 @@ // is received. collectCalls = func(calls *[]*CallbackCall) *RewriteOptions { return &RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { *calls = append(*calls, &CallbackCall{ Type: "blob", Path: path, @@ -366,15 +366,16 @@ assert.Nil(t, err) - assert.Len(t, calls, 8) + assert.Len(t, calls, 9) assert.Equal(t, calls[0], &CallbackCall{Type: "tree-pre", Path: "/"}) assert.Equal(t, calls[1], &CallbackCall{Type: "blob", Path: "a.txt"}) assert.Equal(t, calls[2], &CallbackCall{Type: "tree-post", Path: "/"}) assert.Equal(t, calls[3], &CallbackCall{Type: "tree-pre", Path: "/"}) - assert.Equal(t, calls[4], &CallbackCall{Type: "tree-pre", Path: "/subdir"}) - assert.Equal(t, calls[5], &CallbackCall{Type: "blob", Path: "subdir/b.txt"}) - assert.Equal(t, calls[6], &CallbackCall{Type: "tree-post", Path: "/subdir"}) - assert.Equal(t, calls[7], &CallbackCall{Type: "tree-post", Path: "/"}) + assert.Equal(t, calls[4], &CallbackCall{Type: "blob", Path: "a.txt"}) + assert.Equal(t, calls[5], &CallbackCall{Type: "tree-pre", Path: "/subdir"}) + assert.Equal(t, calls[6], &CallbackCall{Type: "blob", Path: "subdir/b.txt"}) + assert.Equal(t, calls[7], &CallbackCall{Type: "tree-post", Path: "/subdir"}) + assert.Equal(t, calls[8], &CallbackCall{Type: "tree-post", Path: "/"}) } func TestHistoryRewriterTreePreCallbackPropagatesErrors(t *testing.T) { @@ -384,7 +385,7 @@ r := NewRewriter(db) _, err := r.Rewrite(&RewriteOptions{Include: []string{"refs/heads/master"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { return b, nil }, @@ -404,7 +405,7 @@ Include: []string{"refs/heads/master"}, Exclude: []string{"refs/tags/middle"}, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { return b, nil }, }) @@ -441,7 +442,7 @@ UpdateRefs: true, - BlobFn: func(path string, b *gitobj.Blob) (*gitobj.Blob, error) { + BlobFn: func(path string, origOid []byte, b *gitobj.Blob) (*gitobj.Blob, error) { suffix := strings.NewReader("_suffix") return &gitobj.Blob{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/git/ls_tree_scanner.go new/git-lfs-3.0.2/git/ls_tree_scanner.go --- old/git-lfs-3.0.1/git/ls_tree_scanner.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/git/ls_tree_scanner.go 2021-10-28 18:50:56.000000000 +0200 @@ -12,6 +12,7 @@ type TreeBlob struct { Oid string Size int64 + Mode int32 Filename string } @@ -53,6 +54,11 @@ return nil, hasNext } + mode, err := strconv.ParseInt(strings.TrimSpace(attrs[0]), 8, 32) + if err != nil { + return nil, hasNext + } + if attrs[1] != "blob" { return nil, hasNext } @@ -64,7 +70,7 @@ oid := attrs[2] filename := parts[1] - return &TreeBlob{Oid: oid, Size: sz, Filename: filename}, hasNext + return &TreeBlob{Oid: oid, Size: sz, Mode: int32(mode), Filename: filename}, hasNext } func scanNullLines(data []byte, atEOF bool) (advance int, token []byte, err error) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/lfs/gitscanner_tree.go new/git-lfs-3.0.2/lfs/gitscanner_tree.go --- old/git-lfs-3.0.1/lfs/gitscanner_tree.go 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/lfs/gitscanner_tree.go 2021-10-28 18:50:56.000000000 +0200 @@ -199,19 +199,25 @@ return nil, nil, err } - patterns := make([]filepathfilter.Pattern, 0, len(paths)) + includes := make([]filepathfilter.Pattern, 0, len(paths)) + excludes := make([]filepathfilter.Pattern, 0, len(paths)) for _, path := range paths { // Convert all separators to `/` before creating a pattern to // avoid characters being escaped in situations like `subtree\*.md` - patterns = append(patterns, filepathfilter.NewPattern(filepath.ToSlash(path.Path), filepathfilter.GitAttributes)) + pattern := filepathfilter.NewPattern(filepath.ToSlash(path.Path), filepathfilter.GitAttributes) + if path.Tracked { + includes = append(includes, pattern) + } else { + excludes = append(excludes, pattern) + } } - return pointers, filepathfilter.NewFromPatterns(patterns, nil), nil + return pointers, filepathfilter.NewFromPatterns(includes, excludes, filepathfilter.DefaultValue(false)), nil } func runScanTreeForPointers(cb GitScannerFoundPointer, tree string, gitEnv, osEnv config.Environment) error { treeShas, err := lsTreeBlobs(tree, func(t *git.TreeBlob) bool { - return t != nil + return t != nil && (t.Mode == 0100644 || t.Mode == 0100755) }) if err != nil { return err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/rpm/SPECS/git-lfs.spec new/git-lfs-3.0.2/rpm/SPECS/git-lfs.spec --- old/git-lfs-3.0.1/rpm/SPECS/git-lfs.spec 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/rpm/SPECS/git-lfs.spec 2021-10-28 18:50:56.000000000 +0200 @@ -1,5 +1,5 @@ Name: git-lfs -Version: 3.0.1 +Version: 3.0.2 Release: 1%{?dist} Summary: Git extension for versioning large files diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/t/fixtures/migrate.sh new/git-lfs-3.0.2/t/fixtures/migrate.sh --- old/git-lfs-3.0.1/t/fixtures/migrate.sh 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/t/fixtures/migrate.sh 2021-10-28 18:50:56.000000000 +0200 @@ -652,6 +652,50 @@ printf "2" >> a.txt } +# setup_local_branch_with_copied_file creates a repository as follows: +# +# A +# \ +# refs/heads/main +# +# - Commit 'A' has the contents "a.txt" in a.txt, and anoter identical file +# (same name and content) in another directory. +setup_local_branch_with_copied_file() { + set -e + + reponame="migrate-single-local-branch-with-copied-file" + remove_and_create_local_repo "$reponame" + + printf "a.txt" > a.txt + mkdir dir + cp a.txt dir/ + + git add a.txt dir/a.txt + git commit -m "initial commit" +} + +# setup_local_branch_with_special_character_files creates a repository as follows: +# +# A +# \ +# refs/heads/main +# +# - Commit 'A' has binary files with special characters +setup_local_branch_with_special_character_files() { + set -e + + reponame="migrate-single-local-branch-with-special-filenames" + remove_and_create_local_repo "$reponame" + + head -c 80 /dev/urandom > './test - special.bin' + head -c 100 /dev/urandom > './test (test2) special.bin' + # Windows does not allow creation of files with '*' + [ "$IS_WINDOWS" -eq '1' ] || head -c 120 /dev/urandom > './test * ** special.bin' + + git add *.bin + git commit -m "initial commit" +} + # make_bare converts the existing full checkout of a repository into a bare one, # and then `cd`'s into it. make_bare() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/t/t-env.sh new/git-lfs-3.0.2/t/t-env.sh --- old/git-lfs-3.0.1/t/t-env.sh 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/t/t-env.sh 2021-10-28 18:50:56.000000000 +0200 @@ -26,7 +26,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -79,7 +79,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -138,7 +138,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -196,7 +196,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -255,7 +255,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -316,7 +316,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -377,7 +377,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -447,7 +447,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -504,7 +504,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars="$(GIT_DIR=$gitDir GIT_WORK_TREE=$workTree env | grep "^GIT" | sort)" + envVars="$(GIT_DIR=$gitDir GIT_WORK_TREE=$workTree env | grep "^GIT_" | sort)" expected=$(printf '%s %s @@ -553,7 +553,7 @@ | grep -v "^GIT_EXEC_PATH=") contains_same_elements "$expected" "$actual4" - envVars="$(GIT_DIR=$gitDir GIT_WORK_TREE=a/b env | grep "^GIT" | sort)" + envVars="$(GIT_DIR=$gitDir GIT_WORK_TREE=a/b env | grep "^GIT_" | sort)" # `a/b` is an invalid relative path from where we are now and results in an # error, so resulting output will have many fields blank or invalid @@ -594,7 +594,7 @@ contains_same_elements "$expected5" "$actual5" cd $TRASHDIR/$reponame/a/b - envVars="$(GIT_DIR=$gitDir env | grep "^GIT" | sort)" + envVars="$(GIT_DIR=$gitDir env | grep "^GIT_" | sort)" expected7=$(printf '%s %s @@ -627,7 +627,7 @@ contains_same_elements "$expected7" "$actual7" cd $TRASHDIR/$reponame/a - envVars="$(GIT_WORK_TREE=$workTree env | grep "^GIT" | sort)" + envVars="$(GIT_WORK_TREE=$workTree env | grep "^GIT_" | sort)" expected8=$(printf '%s %s @@ -674,7 +674,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf "%s\n%s\n LocalWorkingDir= @@ -744,7 +744,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") localwd=$(canonical_path "$TRASHDIR/$reponame") localgit=$(canonical_path "$TRASHDIR/$reponame/.git") @@ -752,7 +752,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expectedenabled=$(printf '%s %s @@ -819,7 +819,7 @@ contains_same_elements "$expecteddisabled" "$actual" # now enable via env var - envVarsEnabled=$(printf "%s" "$(GIT_LFS_SKIP_DOWNLOAD_ERRORS=1 env | grep "^GIT")") + envVarsEnabled=$(printf "%s" "$(GIT_LFS_SKIP_DOWNLOAD_ERRORS=1 env | grep "^GIT_")") expectedenabled2=$(printf '%s %s @@ -873,7 +873,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") localwd=$(canonical_path "$TRASHDIR/$reponame") localgit=$(canonical_path "$TRASHDIR/$reponame/.git") @@ -881,7 +881,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expectedenabled=$(printf '%s %s @@ -940,7 +940,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s @@ -1005,7 +1005,7 @@ lfsstorage=$(canonical_path "$TRASHDIR/$reponame/.git/lfs") localmedia=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/objects") tempdir=$(canonical_path "$TRASHDIR/$reponame/.git/lfs/tmp") - envVars=$(printf "%s" "$(env | grep "^GIT")") + envVars=$(printf "%s" "$(env | grep "^GIT_")") expected=$(printf '%s %s diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/t/t-fsck.sh new/git-lfs-3.0.2/t/t-fsck.sh --- old/git-lfs-3.0.1/t/t-fsck.sh 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/t/t-fsck.sh 2021-10-28 18:50:56.000000000 +0200 @@ -180,6 +180,90 @@ ) end_test +begin_test "fsck detects invalid pointers with GIT_OBJECT_DIRECTORY" +( + set -e + + reponame="fsck-pointers-object-directory" + setup_invalid_pointers + + head=$(git rev-parse HEAD) + objdir="$(lfstest-realpath .git/objects)" + cd .. + git init "$reponame-2" + gitdir="$(lfstest-realpath "$reponame-2/.git")" + GIT_WORK_TREE="$reponame-2" GIT_DIR="$gitdir" GIT_OBJECT_DIRECTORY="$objdir" git update-ref refs/heads/main "$head" + set +e + GIT_WORK_TREE="$reponame-2" GIT_DIR="$gitdir" GIT_OBJECT_DIRECTORY="$objdir" git lfs fsck --pointers >test.log 2>&1 + RET=$? + set -e + + [ "$RET" -eq 1 ] + grep 'pointer: nonCanonicalPointer: Pointer.*was not canonical' test.log + grep 'pointer: unexpectedGitObject: "large.dat".*should have been a pointer but was not' test.log +) +end_test + +begin_test "fsck does not detect invalid pointers with no LFS objects" +( + set -e + + reponame="fsck-pointers-none" + git init "$reponame" + cd "$reponame" + + echo "# README" > README.md + git add README.md + git commit -m "Add README" + + git lfs fsck + git lfs fsck --pointers +) +end_test + +begin_test "fsck does not detect invalid pointers with symlinks" +( + set -e + + reponame="fsck-pointers-symlinks" + git init "$reponame" + cd "$reponame" + + git lfs track '*.dat' + + echo "# Test" > a.dat + ln -s a.dat b.dat + git add .gitattributes *.dat + git commit -m "Add files" + + git lfs fsck + git lfs fsck --pointers +) +end_test + +begin_test "fsck does not detect invalid pointers with negated patterns" +( + set -e + + reponame="fsck-pointers-none" + git init "$reponame" + cd "$reponame" + + cat > .gitattributes <<EOF +*.dat filter=lfs diff=lfs merge=lfs -text +b.dat !filter !diff !merge text +EOF + + echo "# Test" > a.dat + cp a.dat b.dat + git add .gitattributes *.dat + git commit -m "Add files" + + git lfs fsck + git lfs fsck --pointers +) +end_test + begin_test "fsck operates on specified refs" ( set -e diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/t/t-lock.sh new/git-lfs-3.0.2/t/t-lock.sh --- old/git-lfs-3.0.1/t/t-lock.sh 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/t/t-lock.sh 2021-10-28 18:50:56.000000000 +0200 @@ -113,7 +113,7 @@ git push origin main:other git lfs lock --json *.dat | tee lock.json - grep -E '\[{"id":"[^"]+","path":"a\.dat","owner":{"name":"Git LFS Tests"},"locked_at":"[^"]+"},{"id":"[^"]+","path":"b\.dat","owner":{"name":"Git LFS Tests"},"locked_at":"[^"]+"}\]' lock.json + grep -E '\[\{"id":"[^"]+","path":"a\.dat","owner":\{"name":"Git LFS Tests"\},"locked_at":"[^"]+"\},\{"id":"[^"]+","path":"b\.dat","owner":\{"name":"Git LFS Tests"\},"locked_at":"[^"]+"\}\]' lock.json ) end_test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/t/t-migrate-import.sh new/git-lfs-3.0.2/t/t-migrate-import.sh --- old/git-lfs-3.0.1/t/t-migrate-import.sh 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/t/t-migrate-import.sh 2021-10-28 18:50:56.000000000 +0200 @@ -1001,3 +1001,32 @@ assert_local_object "$md_feature_oid" "30" ) end_test + +begin_test "migrate import (copied file)" +( + set -e + + setup_local_branch_with_copied_file + + git lfs migrate import --above=1b + + # Expect attributes for "/dir/a" and "/a" + if ! grep -q "^/dir/a.txt" ./.gitattributes || ! grep -q "^/a.txt" ./.gitattributes; then + exit 1 + fi +) +end_test + +begin_test "migrate import (filename special characters)" +( + set -e + setup_local_branch_with_special_character_files + git lfs migrate import --above=1b + # Windows does not allow creation of files with '*', so expect 2 files, not 3 + if [ "$IS_WINDOWS" -eq "1" ] ; then + test "$(git check-attr filter -- *.bin |grep lfs | wc -l)" -eq 2 || exit 1 + else + test "$(git check-attr filter -- *.bin |grep lfs | wc -l)" -eq 3 || exit 1 + fi +) +end_test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/t/t-worktree.sh new/git-lfs-3.0.2/t/t-worktree.sh --- old/git-lfs-3.0.1/t/t-worktree.sh 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/t/t-worktree.sh 2021-10-28 18:50:56.000000000 +0200 @@ -49,7 +49,7 @@ AccessUpload=none DownloadTransfers=basic,lfs-standalone-file,ssh UploadTransfers=basic,lfs-standalone-file,ssh -$(escape_path "$(env | grep "^GIT")") +$(escape_path "$(env | grep "^GIT_")") %s " "$(git lfs version)" "$(git version)" "$envInitConfig") actual=$(git lfs env | grep -v "^GIT_EXEC_PATH=") @@ -85,7 +85,7 @@ AccessUpload=none DownloadTransfers=basic,lfs-standalone-file,ssh UploadTransfers=basic,lfs-standalone-file,ssh -$(escape_path "$(env | grep "^GIT")") +$(escape_path "$(env | grep "^GIT_")") %s " "$(git lfs version)" "$(git version)" "$envInitConfig") actual=$(git lfs env | grep -v "^GIT_EXEC_PATH=") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/t/testhelpers.sh new/git-lfs-3.0.2/t/testhelpers.sh --- old/git-lfs-3.0.1/t/testhelpers.sh 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/t/testhelpers.sh 2021-10-28 18:50:56.000000000 +0200 @@ -846,7 +846,7 @@ export PATH="$ROOTDIR/t/scutiger/bin:$PATH" if ! command -v git-lfs-transfer >/dev/null 2>&1 then - if [ -z "$CI" ] + if [ -z "$CI" ] || [ -n "$TEST_SKIP_LFS_TRANSFER" ] then echo "No git-lfs-transfer. Skipping..." exit 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-lfs-3.0.1/versioninfo.json new/git-lfs-3.0.2/versioninfo.json --- old/git-lfs-3.0.1/versioninfo.json 2021-09-28 19:01:18.000000000 +0200 +++ new/git-lfs-3.0.2/versioninfo.json 2021-10-28 18:50:56.000000000 +0200 @@ -4,7 +4,7 @@ "FileVersion": { "Major": 3, "Minor": 0, - "Patch": 1, + "Patch": 2, "Build": 0 } }, @@ -13,7 +13,7 @@ "FileDescription": "Git LFS", "LegalCopyright": "GitHub, Inc. and Git LFS contributors", "ProductName": "Git Large File Storage (LFS)", - "ProductVersion": "3.0.1" + "ProductVersion": "3.0.2" }, "IconPath": "script/windows-installer/git-lfs-logo.ico" }
participants (1)
-
Source-Sync