diff options
83 files changed, 580 insertions, 190 deletions
diff --git a/_examples/README.md b/_examples/README.md index 80d4dd5..92b9d4d 100644 --- a/_examples/README.md +++ b/_examples/README.md @@ -10,6 +10,7 @@ Here you can find a list of annotated _go-git_ examples: using a username and password. - [personal access token](clone/auth/basic/access_token/main.go) - Cloning a repository using a GitHub personal access token. + - [ssh private key](clone/auth/ssh/main.go) - Cloning a repository using a ssh private key. - [commit](commit/main.go) - Commit changes to the current branch to an existent repository. - [push](push/main.go) - Push repository to default remote (origin). - [pull](pull/main.go) - Pull changes from a remote repository. diff --git a/_examples/clone/auth/ssh/main.go b/_examples/clone/auth/ssh/main.go new file mode 100644 index 0000000..1e06e44 --- /dev/null +++ b/_examples/clone/auth/ssh/main.go @@ -0,0 +1,52 @@ +package main + +import ( + "fmt" + "os" + + git "github.com/go-git/go-git/v5" + . "github.com/go-git/go-git/v5/_examples" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" +) + +func main() { + CheckArgs("<url>", "<directory>", "<private_key_file>") + url, directory, privateKeyFile := os.Args[1], os.Args[2], os.Args[3] + var password string + if len(os.Args) == 5 { + password = os.Args[4] + } + + _, err := os.Stat(privateKeyFile) + if err != nil { + Warning("read file %s failed %s\n", privateKeyFile, err.Error()) + return + } + + // Clone the given repository to the given directory + Info("git clone %s ", url) + publicKeys, err := ssh.NewPublicKeysFromFile("git", privateKeyFile, password) + if err != nil { + Warning("generate publickeys failed: %s\n", err.Error()) + return + } + + r, err := git.PlainClone(directory, false, &git.CloneOptions{ + // The intended use of a GitHub personal access token is in replace of your password + // because access tokens can easily be revoked. + // https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ + Auth: publicKeys, + URL: url, + Progress: os.Stdout, + }) + CheckIfError(err) + + // ... retrieving the branch being pointed by HEAD + ref, err := r.Head() + CheckIfError(err) + // ... retrieving the commit object + commit, err := r.CommitObject(ref.Hash()) + CheckIfError(err) + + fmt.Println(commit) +} diff --git a/blame_test.go b/blame_test.go index 398f839..7895b66 100644 --- a/blame_test.go +++ b/blame_test.go @@ -4,8 +4,8 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type BlameSuite struct { diff --git a/config/branch_test.go b/config/branch_test.go index a2c86cd..ae1fe85 100644 --- a/config/branch_test.go +++ b/config/branch_test.go @@ -1,8 +1,9 @@ package config import ( - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" + + . "gopkg.in/check.v1" ) type BranchSuite struct{} diff --git a/internal/revision/parser.go b/internal/revision/parser.go index 61de386..8facf17 100644 --- a/internal/revision/parser.go +++ b/internal/revision/parser.go @@ -28,7 +28,7 @@ func (e *ErrInvalidRevision) Error() string { type Revisioner interface { } -// Ref represents a reference name : HEAD, master +// Ref represents a reference name : HEAD, master, <hash> type Ref string // TildePath represents ~, ~{n} @@ -297,7 +297,7 @@ func (p *Parser) parseAt() (Revisioner, error) { } if t != cbrace { - return nil, &ErrInvalidRevision{fmt.Sprintf(`missing "}" in @{-n} structure`)} + return nil, &ErrInvalidRevision{s: `missing "}" in @{-n} structure`} } return AtCheckout{n}, nil @@ -419,7 +419,7 @@ func (p *Parser) parseCaretBraces() (Revisioner, error) { case re == "" && tok == emark && nextTok == minus: negate = true case re == "" && tok == emark: - return nil, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component sequences starting with "/!" others than those defined are reserved`)} + return nil, &ErrInvalidRevision{s: `revision suffix brace component sequences starting with "/!" others than those defined are reserved`} case re == "" && tok == slash: p.unscan() case tok != slash && start: @@ -490,7 +490,7 @@ func (p *Parser) parseColonSlash() (Revisioner, error) { case re == "" && tok == emark && nextTok == minus: negate = true case re == "" && tok == emark: - return nil, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component sequences starting with "/!" others than those defined are reserved`)} + return nil, &ErrInvalidRevision{s: `revision suffix brace component sequences starting with "/!" others than those defined are reserved`} case tok == eof: p.unscan() reg, err := regexp.Compile(re) diff --git a/internal/revision/parser_test.go b/internal/revision/parser_test.go index fe45228..98403cc 100644 --- a/internal/revision/parser_test.go +++ b/internal/revision/parser_test.go @@ -96,8 +96,8 @@ func (s *ParserSuite) TestParseWithValidExpression(c *C) { TildePath{3}, }, "@{2016-12-16T21:42:47Z}": []Revisioner{AtDate{tim}}, - "@{1}": []Revisioner{AtReflog{1}}, - "@{-1}": []Revisioner{AtCheckout{1}}, + "@{1}": []Revisioner{AtReflog{1}}, + "@{-1}": []Revisioner{AtCheckout{1}}, "master@{upstream}": []Revisioner{ Ref("master"), AtUpstream{}, @@ -211,12 +211,12 @@ func (s *ParserSuite) TestParseAtWithValidExpression(c *C) { tim, _ := time.Parse("2006-01-02T15:04:05Z", "2016-12-16T21:42:47Z") datas := map[string]Revisioner{ - "": Ref("HEAD"), - "{1}": AtReflog{1}, - "{-1}": AtCheckout{1}, - "{push}": AtPush{}, - "{upstream}": AtUpstream{}, - "{u}": AtUpstream{}, + "": Ref("HEAD"), + "{1}": AtReflog{1}, + "{-1}": AtCheckout{1}, + "{push}": AtPush{}, + "{upstream}": AtUpstream{}, + "{u}": AtUpstream{}, "{2016-12-16T21:42:47Z}": AtDate{tim}, } @@ -354,6 +354,7 @@ func (s *ParserSuite) TestParseRefWithValidName(c *C) { "refs/remotes/test", "refs/remotes/origin/HEAD", "refs/remotes/origin/master", + "0123abcd", // short hash } for _, d := range datas { diff --git a/plumbing/filemode/filemode.go b/plumbing/filemode/filemode.go index 594984f..b848a97 100644 --- a/plumbing/filemode/filemode.go +++ b/plumbing/filemode/filemode.go @@ -118,7 +118,7 @@ func isSetSymLink(m os.FileMode) bool { func (m FileMode) Bytes() []byte { ret := make([]byte, 4) binary.LittleEndian.PutUint32(ret, uint32(m)) - return ret[:] + return ret } // IsMalformed returns if the FileMode should not appear in a git packfile, diff --git a/plumbing/format/commitgraph/commitgraph_test.go b/plumbing/format/commitgraph/commitgraph_test.go index 7d7444b..de61ae9 100644 --- a/plumbing/format/commitgraph/commitgraph_test.go +++ b/plumbing/format/commitgraph/commitgraph_test.go @@ -6,10 +6,11 @@ import ( "path"
"testing"
- . "gopkg.in/check.v1"
- fixtures "github.com/go-git/go-git-fixtures/v4"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/commitgraph"
+
+ fixtures "github.com/go-git/go-git-fixtures/v4"
+ . "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
diff --git a/plumbing/format/config/option.go b/plumbing/format/config/option.go index 316ff52..cad3948 100644 --- a/plumbing/format/config/option.go +++ b/plumbing/format/config/option.go @@ -19,7 +19,7 @@ type Options []*Option // IsKey returns true if the given key matches // this option's key in a case-insensitive comparison. func (o *Option) IsKey(key string) bool { - return strings.ToLower(o.Key) == strings.ToLower(key) + return strings.EqualFold(o.Key, key) } func (opts Options) GoString() string { diff --git a/plumbing/format/config/section.go b/plumbing/format/config/section.go index b7a684a..07f72f3 100644 --- a/plumbing/format/config/section.go +++ b/plumbing/format/config/section.go @@ -61,7 +61,7 @@ func (s Subsections) GoString() string { // IsName checks if the name provided is equals to the Section name, case insensitive. func (s *Section) IsName(name string) bool { - return strings.ToLower(s.Name) == strings.ToLower(name) + return strings.EqualFold(s.Name, name) } // Subsection returns a Subsection from the specified Section. If the diff --git a/plumbing/format/gitignore/dir.go b/plumbing/format/gitignore/dir.go index f4444bf..4a26325 100644 --- a/plumbing/format/gitignore/dir.go +++ b/plumbing/format/gitignore/dir.go @@ -1,6 +1,7 @@ package gitignore import ( + "bufio" "bytes" "io/ioutil" "os" @@ -15,7 +16,6 @@ import ( const ( commentPrefix = "#" coreSection = "core" - eol = "\n" excludesfile = "excludesfile" gitDir = ".git" gitignoreFile = ".gitignore" @@ -29,11 +29,11 @@ func readIgnoreFile(fs billy.Filesystem, path []string, ignoreFile string) (ps [ if err == nil { defer f.Close() - if data, err := ioutil.ReadAll(f); err == nil { - for _, s := range strings.Split(string(data), eol) { - if !strings.HasPrefix(s, commentPrefix) && len(strings.TrimSpace(s)) > 0 { - ps = append(ps, ParsePattern(s, path)) - } + scanner := bufio.NewScanner(f) + for scanner.Scan() { + s := scanner.Text() + if !strings.HasPrefix(s, commentPrefix) && len(strings.TrimSpace(s)) > 0 { + ps = append(ps, ParsePattern(s, path)) } } } else if !os.IsNotExist(err) { diff --git a/plumbing/format/gitignore/dir_test.go b/plumbing/format/gitignore/dir_test.go index c0301f7..a3e7ba6 100644 --- a/plumbing/format/gitignore/dir_test.go +++ b/plumbing/format/gitignore/dir_test.go @@ -15,7 +15,7 @@ type MatcherSuite struct { RFS billy.Filesystem // root that contains user home MCFS billy.Filesystem // root that contains user home, but missing ~/.gitconfig MEFS billy.Filesystem // root that contains user home, but missing excludesfile entry - MIFS billy.Filesystem // root that contains user home, but missing .gitnignore + MIFS billy.Filesystem // root that contains user home, but missing .gitignore SFS billy.Filesystem // root that contains /etc/gitconfig } @@ -29,6 +29,8 @@ func (s *MatcherSuite) SetUpTest(c *C) { c.Assert(err, IsNil) _, err = f.Write([]byte("vendor/g*/\n")) c.Assert(err, IsNil) + _, err = f.Write([]byte("ignore.crlf\r\n")) + c.Assert(err, IsNil) err = f.Close() c.Assert(err, IsNil) @@ -41,9 +43,14 @@ func (s *MatcherSuite) SetUpTest(c *C) { err = f.Close() c.Assert(err, IsNil) - fs.MkdirAll("another", os.ModePerm) - fs.MkdirAll("vendor/github.com", os.ModePerm) - fs.MkdirAll("vendor/gopkg.in", os.ModePerm) + err = fs.MkdirAll("another", os.ModePerm) + c.Assert(err, IsNil) + err = fs.MkdirAll("ignore.crlf", os.ModePerm) + c.Assert(err, IsNil) + err = fs.MkdirAll("vendor/github.com", os.ModePerm) + c.Assert(err, IsNil) + err = fs.MkdirAll("vendor/gopkg.in", os.ModePerm) + c.Assert(err, IsNil) s.GFS = fs @@ -167,9 +174,10 @@ func (s *MatcherSuite) SetUpTest(c *C) { func (s *MatcherSuite) TestDir_ReadPatterns(c *C) { ps, err := ReadPatterns(s.GFS, nil) c.Assert(err, IsNil) - c.Assert(ps, HasLen, 2) + c.Assert(ps, HasLen, 3) m := NewMatcher(ps) + c.Assert(m.Match([]string{"ignore.crlf"}, true), Equals, true) c.Assert(m.Match([]string{"vendor", "gopkg.in"}, true), Equals, true) c.Assert(m.Match([]string{"vendor", "github.com"}, true), Equals, false) } diff --git a/plumbing/format/idxfile/encoder_test.go b/plumbing/format/idxfile/encoder_test.go index 81abb3b..32b60f9 100644 --- a/plumbing/format/idxfile/encoder_test.go +++ b/plumbing/format/idxfile/encoder_test.go @@ -6,8 +6,8 @@ import ( . "github.com/go-git/go-git/v5/plumbing/format/idxfile" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) func (s *IdxfileSuite) TestDecodeEncode(c *C) { diff --git a/plumbing/format/idxfile/idxfile_test.go b/plumbing/format/idxfile/idxfile_test.go index 5ef73d7..7a3d6bb 100644 --- a/plumbing/format/idxfile/idxfile_test.go +++ b/plumbing/format/idxfile/idxfile_test.go @@ -10,8 +10,8 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/format/idxfile" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) func BenchmarkFindOffset(b *testing.B) { diff --git a/plumbing/format/idxfile/writer_test.go b/plumbing/format/idxfile/writer_test.go index f86342f..fba3e42 100644 --- a/plumbing/format/idxfile/writer_test.go +++ b/plumbing/format/idxfile/writer_test.go @@ -9,8 +9,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/format/idxfile" "github.com/go-git/go-git/v5/plumbing/format/packfile" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type WriterSuite struct { diff --git a/plumbing/format/index/decoder.go b/plumbing/format/index/decoder.go index 79d0b9e..036b636 100644 --- a/plumbing/format/index/decoder.go +++ b/plumbing/format/index/decoder.go @@ -188,7 +188,7 @@ func (d *Decoder) doReadEntryNameV4() (string, error) { func (d *Decoder) doReadEntryName(len uint16) (string, error) { name := make([]byte, len) - _, err := io.ReadFull(d.r, name[:]) + _, err := io.ReadFull(d.r, name) return string(name), err } @@ -390,7 +390,9 @@ func (d *treeExtensionDecoder) readEntry() (*TreeEntry, error) { e.Trees = i _, err = io.ReadFull(d.r, e.Hash[:]) - + if err != nil { + return nil, err + } return e, nil } diff --git a/plumbing/format/index/decoder_test.go b/plumbing/format/index/decoder_test.go index 4e47dde..39ab336 100644 --- a/plumbing/format/index/decoder_test.go +++ b/plumbing/format/index/decoder_test.go @@ -6,8 +6,8 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/filemode" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) func Test(t *testing.T) { TestingT(t) } diff --git a/plumbing/format/index/encoder_test.go b/plumbing/format/index/encoder_test.go index 17585a0..b7a73cb 100644 --- a/plumbing/format/index/encoder_test.go +++ b/plumbing/format/index/encoder_test.go @@ -5,9 +5,10 @@ import ( "strings" "time" + "github.com/go-git/go-git/v5/plumbing" + "github.com/google/go-cmp/cmp" . "gopkg.in/check.v1" - "github.com/go-git/go-git/v5/plumbing" ) func (s *IndexSuite) TestEncode(c *C) { diff --git a/plumbing/format/objfile/common_test.go b/plumbing/format/objfile/common_test.go index ec8c280..de76902 100644 --- a/plumbing/format/objfile/common_test.go +++ b/plumbing/format/objfile/common_test.go @@ -4,8 +4,9 @@ import ( "encoding/base64" "testing" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" + + . "gopkg.in/check.v1" ) type objfileFixture struct { diff --git a/plumbing/format/objfile/reader_test.go b/plumbing/format/objfile/reader_test.go index 48e7f1c..d697d54 100644 --- a/plumbing/format/objfile/reader_test.go +++ b/plumbing/format/objfile/reader_test.go @@ -7,8 +7,9 @@ import ( "io" "io/ioutil" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" + + . "gopkg.in/check.v1" ) type SuiteReader struct{} diff --git a/plumbing/format/objfile/writer_test.go b/plumbing/format/objfile/writer_test.go index 73ee662..35a9510 100644 --- a/plumbing/format/objfile/writer_test.go +++ b/plumbing/format/objfile/writer_test.go @@ -6,8 +6,9 @@ import ( "fmt" "io" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" + + . "gopkg.in/check.v1" ) type SuiteWriter struct{} diff --git a/plumbing/format/packfile/encoder_advanced_test.go b/plumbing/format/packfile/encoder_advanced_test.go index 21bf3ae..95db5c0 100644 --- a/plumbing/format/packfile/encoder_advanced_test.go +++ b/plumbing/format/packfile/encoder_advanced_test.go @@ -6,7 +6,6 @@ import ( "math/rand" "testing" - "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/cache" "github.com/go-git/go-git/v5/plumbing/format/idxfile" @@ -14,8 +13,9 @@ import ( "github.com/go-git/go-git/v5/plumbing/storer" "github.com/go-git/go-git/v5/storage/filesystem" + "github.com/go-git/go-billy/v5/memfs" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type EncoderAdvancedSuite struct { diff --git a/plumbing/format/packfile/encoder_test.go b/plumbing/format/packfile/encoder_test.go index 2689762..d2db892 100644 --- a/plumbing/format/packfile/encoder_test.go +++ b/plumbing/format/packfile/encoder_test.go @@ -5,13 +5,13 @@ import ( "io" stdioutil "io/ioutil" - "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/format/idxfile" "github.com/go-git/go-git/v5/storage/memory" + "github.com/go-git/go-billy/v5/memfs" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type EncoderSuite struct { diff --git a/plumbing/format/packfile/patch_delta.go b/plumbing/format/packfile/patch_delta.go index 1dc8b8b..9e90f30 100644 --- a/plumbing/format/packfile/patch_delta.go +++ b/plumbing/format/packfile/patch_delta.go @@ -49,7 +49,6 @@ func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) (err error) { return err } - target.SetSize(int64(dst.Len())) b := byteSlicePool.Get().([]byte) @@ -113,7 +112,7 @@ func patchDelta(dst *bytes.Buffer, src, delta []byte) error { invalidOffsetSize(offset, sz, srcSz) { break } - dst.Write(src[offset:offset+sz]) + dst.Write(src[offset : offset+sz]) remainingTargetSz -= sz } else if isCopyFromDelta(cmd) { sz := uint(cmd) // cmd is the size itself diff --git a/plumbing/memory.go b/plumbing/memory.go index b8e1e1b..21337cc 100644 --- a/plumbing/memory.go +++ b/plumbing/memory.go @@ -3,7 +3,6 @@ package plumbing import ( "bytes" "io" - "io/ioutil" ) // MemoryObject on memory Object implementation @@ -39,9 +38,11 @@ func (o *MemoryObject) Size() int64 { return o.sz } // afterwards func (o *MemoryObject) SetSize(s int64) { o.sz = s } -// Reader returns a ObjectReader used to read the object's content. +// Reader returns an io.ReadCloser used to read the object's content. +// +// For a MemoryObject, this reader is seekable. func (o *MemoryObject) Reader() (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewBuffer(o.cont)), nil + return nopCloser{bytes.NewReader(o.cont)}, nil } // Writer returns a ObjectWriter used to write the object's content. @@ -59,3 +60,13 @@ func (o *MemoryObject) Write(p []byte) (n int, err error) { // Close releases any resources consumed by the object when it is acting as a // ObjectWriter. func (o *MemoryObject) Close() error { return nil } + +// nopCloser exposes the extra methods of bytes.Reader while nopping Close(). +// +// This allows clients to attempt seeking in a cached Blob's Reader. +type nopCloser struct { + *bytes.Reader +} + +// Close does nothing. +func (nc nopCloser) Close() error { return nil } diff --git a/plumbing/memory_test.go b/plumbing/memory_test.go index 879ed37..2a141f4 100644 --- a/plumbing/memory_test.go +++ b/plumbing/memory_test.go @@ -1,6 +1,7 @@ package plumbing import ( + "io" "io/ioutil" . "gopkg.in/check.v1" @@ -56,6 +57,33 @@ func (s *MemoryObjectSuite) TestReader(c *C) { c.Assert(b, DeepEquals, []byte("foo")) } +func (s *MemoryObjectSuite) TestSeekableReader(c *C) { + const pageSize = 4096 + const payload = "foo" + content := make([]byte, pageSize+len(payload)) + copy(content[pageSize:], []byte(payload)) + + o := &MemoryObject{cont: content} + + reader, err := o.Reader() + c.Assert(err, IsNil) + defer func() { c.Assert(reader.Close(), IsNil) }() + + rs, ok := reader.(io.ReadSeeker) + c.Assert(ok, Equals, true) + + _, err = rs.Seek(pageSize, io.SeekStart) + c.Assert(err, IsNil) + + b, err := ioutil.ReadAll(rs) + c.Assert(err, IsNil) + c.Assert(b, DeepEquals, []byte(payload)) + + // Check that our Reader isn't also accidentally writable + _, ok = reader.(io.WriteSeeker) + c.Assert(ok, Equals, false) +} + func (s *MemoryObjectSuite) TestWriter(c *C) { o := &MemoryObject{} diff --git a/plumbing/object/change.go b/plumbing/object/change.go index c9d1615..8b119bc 100644 --- a/plumbing/object/change.go +++ b/plumbing/object/change.go @@ -75,7 +75,7 @@ func (c *Change) Files() (from, to *File, err error) { func (c *Change) String() string { action, err := c.Action() if err != nil { - return fmt.Sprintf("malformed change") + return "malformed change" } return fmt.Sprintf("<Action: %s, Path: %s>", action, c.name()) diff --git a/plumbing/object/commit.go b/plumbing/object/commit.go index 113cb29..98664a1 100644 --- a/plumbing/object/commit.go +++ b/plumbing/object/commit.go @@ -243,16 +243,16 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) { } // Encode transforms a Commit into a plumbing.EncodedObject. -func (b *Commit) Encode(o plumbing.EncodedObject) error { - return b.encode(o, true) +func (c *Commit) Encode(o plumbing.EncodedObject) error { + return c.encode(o, true) } // EncodeWithoutSignature export a Commit into a plumbing.EncodedObject without the signature (correspond to the payload of the PGP signature). -func (b *Commit) EncodeWithoutSignature(o plumbing.EncodedObject) error { - return b.encode(o, false) +func (c *Commit) EncodeWithoutSignature(o plumbing.EncodedObject) error { + return c.encode(o, false) } -func (b *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) { +func (c *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) { o.SetType(plumbing.CommitObject) w, err := o.Writer() if err != nil { @@ -261,11 +261,11 @@ func (b *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) { defer ioutil.CheckClose(w, &err) - if _, err = fmt.Fprintf(w, "tree %s\n", b.TreeHash.String()); err != nil { + if _, err = fmt.Fprintf(w, "tree %s\n", c.TreeHash.String()); err != nil { return err } - for _, parent := range b.ParentHashes { + for _, parent := range c.ParentHashes { if _, err = fmt.Fprintf(w, "parent %s\n", parent.String()); err != nil { return err } @@ -275,7 +275,7 @@ func (b *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) { return err } - if err = b.Author.Encode(w); err != nil { + if err = c.Author.Encode(w); err != nil { return err } @@ -283,11 +283,11 @@ func (b *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) { return err } - if err = b.Committer.Encode(w); err != nil { + if err = c.Committer.Encode(w); err != nil { return err } - if b.PGPSignature != "" && includeSig { + if c.PGPSignature != "" && includeSig { if _, err = fmt.Fprint(w, "\n"+headerpgp+" "); err != nil { return err } @@ -296,14 +296,14 @@ func (b *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) { // newline. Use join for this so it's clear that a newline should not be // added after this section, as it will be added when the message is // printed. - signature := strings.TrimSuffix(b.PGPSignature, "\n") + signature := strings.TrimSuffix(c.PGPSignature, "\n") lines := strings.Split(signature, "\n") if _, err = fmt.Fprint(w, strings.Join(lines, "\n ")); err != nil { return err } } - if _, err = fmt.Fprintf(w, "\n\n%s", b.Message); err != nil { + if _, err = fmt.Fprintf(w, "\n\n%s", c.Message); err != nil { return err } diff --git a/plumbing/object/commit_stats_test.go b/plumbing/object/commit_stats_test.go index bce2953..4078ce8 100644 --- a/plumbing/object/commit_stats_test.go +++ b/plumbing/object/commit_stats_test.go @@ -11,8 +11,9 @@ import ( "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-billy/v5/util" + + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type CommitStatsSuite struct { diff --git a/plumbing/object/commit_walker_bfs_filtered.go b/plumbing/object/commit_walker_bfs_filtered.go index e87c3db..9d51813 100644 --- a/plumbing/object/commit_walker_bfs_filtered.go +++ b/plumbing/object/commit_walker_bfs_filtered.go @@ -173,4 +173,3 @@ func (w *filterCommitIter) addToQueue( return nil } - diff --git a/plumbing/object/commit_walker_path.go b/plumbing/object/commit_walker_path.go index af6f745..aa0ca15 100644 --- a/plumbing/object/commit_walker_path.go +++ b/plumbing/object/commit_walker_path.go @@ -4,7 +4,6 @@ import ( "io" "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" ) @@ -29,7 +28,7 @@ func NewCommitPathIterFromIter(pathFilter func(string) bool, commitIter CommitIt return iterator } -// this function is kept for compatibilty, can be replaced with NewCommitPathIterFromIter +// NewCommitFileIterFromIter is kept for compatibility, can be replaced with NewCommitPathIterFromIter func NewCommitFileIterFromIter(fileName string, commitIter CommitIter, checkParent bool) CommitIter { return NewCommitPathIterFromIter( func(path string) bool { diff --git a/plumbing/object/commitgraph/commitnode_test.go b/plumbing/object/commitgraph/commitnode_test.go index 38d3bce..6c9a643 100644 --- a/plumbing/object/commitgraph/commitnode_test.go +++ b/plumbing/object/commitgraph/commitnode_test.go @@ -4,13 +4,14 @@ import ( "path"
"testing"
- . "gopkg.in/check.v1"
- fixtures "github.com/go-git/go-git-fixtures/v4"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/cache"
"github.com/go-git/go-git/v5/plumbing/format/commitgraph"
"github.com/go-git/go-git/v5/plumbing/format/packfile"
"github.com/go-git/go-git/v5/storage/filesystem"
+
+ fixtures "github.com/go-git/go-git-fixtures/v4"
+ . "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
diff --git a/plumbing/object/commitgraph/commitnode_walker_ctime.go b/plumbing/object/commitgraph/commitnode_walker_ctime.go index f2ed663..281f10b 100644 --- a/plumbing/object/commitgraph/commitnode_walker_ctime.go +++ b/plumbing/object/commitgraph/commitnode_walker_ctime.go @@ -3,10 +3,10 @@ package commitgraph import (
"io"
- "github.com/emirpasic/gods/trees/binaryheap"
-
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/storer"
+
+ "github.com/emirpasic/gods/trees/binaryheap"
)
type commitNodeIteratorByCTime struct {
diff --git a/plumbing/object/file_test.go b/plumbing/object/file_test.go index 4dfd950..ada6654 100644 --- a/plumbing/object/file_test.go +++ b/plumbing/object/file_test.go @@ -9,8 +9,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/storer" "github.com/go-git/go-git/v5/storage/filesystem" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type FileSuite struct { diff --git a/plumbing/object/patch.go b/plumbing/object/patch.go index 1135a40..9b5f438 100644 --- a/plumbing/object/patch.go +++ b/plumbing/object/patch.go @@ -121,12 +121,12 @@ type Patch struct { filePatches []fdiff.FilePatch } -func (t *Patch) FilePatches() []fdiff.FilePatch { - return t.filePatches +func (p *Patch) FilePatches() []fdiff.FilePatch { + return p.filePatches } -func (t *Patch) Message() string { - return t.message +func (p *Patch) Message() string { + return p.message } func (p *Patch) Encode(w io.Writer) error { @@ -198,12 +198,12 @@ func (tf *textFilePatch) Files() (from fdiff.File, to fdiff.File) { return } -func (t *textFilePatch) IsBinary() bool { - return len(t.chunks) == 0 +func (tf *textFilePatch) IsBinary() bool { + return len(tf.chunks) == 0 } -func (t *textFilePatch) Chunks() []fdiff.Chunk { - return t.chunks +func (tf *textFilePatch) Chunks() []fdiff.Chunk { + return tf.chunks } // textChunk is an implementation of fdiff.Chunk interface diff --git a/plumbing/object/patch_test.go b/plumbing/object/patch_test.go index d4b6cd6..2cff795 100644 --- a/plumbing/object/patch_test.go +++ b/plumbing/object/patch_test.go @@ -1,11 +1,12 @@ package object import ( - . "gopkg.in/check.v1" - fixtures "github.com/go-git/go-git-fixtures/v4" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/cache" "github.com/go-git/go-git/v5/storage/filesystem" + + fixtures "github.com/go-git/go-git-fixtures/v4" + . "gopkg.in/check.v1" ) type PatchSuite struct { diff --git a/plumbing/object/rename.go b/plumbing/object/rename.go index 35af1d6..7fed72c 100644 --- a/plumbing/object/rename.go +++ b/plumbing/object/rename.go @@ -536,7 +536,7 @@ var errIndexFull = errors.New("index is full") // between two files. // To save space in memory, this index uses a space efficient encoding which // will not exceed 1MiB per instance. The index starts out at a smaller size -// (closer to 2KiB), but may grow as more distinct blocks withing the scanned +// (closer to 2KiB), but may grow as more distinct blocks within the scanned // file are discovered. // see: https://github.com/eclipse/jgit/blob/master/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java type similarityIndex struct { @@ -709,7 +709,7 @@ func (i *similarityIndex) common(dst *similarityIndex) uint64 { } func (i *similarityIndex) add(key int, cnt uint64) error { - key = int(uint32(key)*0x9e370001 >> 1) + key = int(uint32(key) * 0x9e370001 >> 1) j := i.slot(key) for { @@ -769,7 +769,7 @@ func (i *similarityIndex) slot(key int) int { // We use 31 - hashBits because the upper bit was already forced // to be 0 and we want the remaining high bits to be used as the // table slot. - return int(uint32(key) >> uint(31 - i.hashBits)) + return int(uint32(key) >> uint(31-i.hashBits)) } func shouldGrowAt(hashBits int) int { diff --git a/plumbing/protocol/packp/capability/list.go b/plumbing/protocol/packp/capability/list.go index 9609211..f41ec79 100644 --- a/plumbing/protocol/packp/capability/list.go +++ b/plumbing/protocol/packp/capability/list.go @@ -86,10 +86,7 @@ func (l *List) Get(capability Capability) []string { // Set sets a capability removing the previous values func (l *List) Set(capability Capability, values ...string) error { - if _, ok := l.m[capability]; ok { - delete(l.m, capability) - } - + delete(l.m, capability) return l.Add(capability, values...) } diff --git a/plumbing/protocol/packp/ulreq.go b/plumbing/protocol/packp/ulreq.go index 44db8e4..ddec06e 100644 --- a/plumbing/protocol/packp/ulreq.go +++ b/plumbing/protocol/packp/ulreq.go @@ -109,42 +109,42 @@ func NewUploadRequestFromCapabilities(adv *capability.List) *UploadRequest { // - is a DepthReference is given capability.DeepenNot MUST be present // - MUST contain only maximum of one of capability.Sideband and capability.Sideband64k // - MUST contain only maximum of one of capability.MultiACK and capability.MultiACKDetailed -func (r *UploadRequest) Validate() error { - if len(r.Wants) == 0 { +func (req *UploadRequest) Validate() error { + if len(req.Wants) == 0 { return fmt.Errorf("want can't be empty") } - if err := r.validateRequiredCapabilities(); err != nil { + if err := req.validateRequiredCapabilities(); err != nil { return err } - if err := r.validateConflictCapabilities(); err != nil { + if err := req.validateConflictCapabilities(); err != nil { return err } return nil } -func (r *UploadRequest) validateRequiredCapabilities() error { +func (req *UploadRequest) validateRequiredCapabilities() error { msg := "missing capability %s" - if len(r.Shallows) != 0 && !r.Capabilities.Supports(capability.Shallow) { + if len(req.Shallows) != 0 && !req.Capabilities.Supports(capability.Shallow) { return fmt.Errorf(msg, capability.Shallow) } - switch r.Depth.(type) { + switch req.Depth.(type) { case DepthCommits: - if r.Depth != DepthCommits(0) { - if !r.Capabilities.Supports(capability.Shallow) { + if req.Depth != DepthCommits(0) { + if !req.Capabilities.Supports(capability.Shallow) { return fmt.Errorf(msg, capability.Shallow) } } case DepthSince: - if !r.Capabilities.Supports(capability.DeepenSince) { + if !req.Capabilities.Supports(capability.DeepenSince) { return fmt.Errorf(msg, capability.DeepenSince) } case DepthReference: - if !r.Capabilities.Supports(capability.DeepenNot) { + if !req.Capabilities.Supports(capability.DeepenNot) { return fmt.Errorf(msg, capability.DeepenNot) } } @@ -152,15 +152,15 @@ func (r *UploadRequest) validateRequiredCapabilities() error { return nil } -func (r *UploadRequest) validateConflictCapabilities() error { +func (req *UploadRequest) validateConflictCapabilities() error { msg := "capabilities %s and %s are mutually exclusive" - if r.Capabilities.Supports(capability.Sideband) && - r.Capabilities.Supports(capability.Sideband64k) { + if req.Capabilities.Supports(capability.Sideband) && + req.Capabilities.Supports(capability.Sideband64k) { return fmt.Errorf(msg, capability.Sideband, capability.Sideband64k) } - if r.Capabilities.Supports(capability.MultiACK) && - r.Capabilities.Supports(capability.MultiACKDetailed) { + if req.Capabilities.Supports(capability.MultiACK) && + req.Capabilities.Supports(capability.MultiACKDetailed) { return fmt.Errorf(msg, capability.MultiACK, capability.MultiACKDetailed) } diff --git a/plumbing/protocol/packp/ulreq_decode.go b/plumbing/protocol/packp/ulreq_decode.go index 449b729..895a3bf 100644 --- a/plumbing/protocol/packp/ulreq_decode.go +++ b/plumbing/protocol/packp/ulreq_decode.go @@ -14,9 +14,9 @@ import ( // Decode reads the next upload-request form its input and // stores it in the UploadRequest. -func (u *UploadRequest) Decode(r io.Reader) error { +func (req *UploadRequest) Decode(r io.Reader) error { d := newUlReqDecoder(r) - return d.Decode(u) + return d.Decode(req) } type ulReqDecoder struct { diff --git a/plumbing/protocol/packp/ulreq_encode.go b/plumbing/protocol/packp/ulreq_encode.go index 4863076..c451e23 100644 --- a/plumbing/protocol/packp/ulreq_encode.go +++ b/plumbing/protocol/packp/ulreq_encode.go @@ -15,9 +15,9 @@ import ( // All the payloads will end with a newline character. Wants and // shallows are sorted alphabetically. A depth of 0 means no depth // request is sent. -func (u *UploadRequest) Encode(w io.Writer) error { +func (req *UploadRequest) Encode(w io.Writer) error { e := newUlReqEncoder(w) - return e.Encode(u) + return e.Encode(req) } type ulReqEncoder struct { diff --git a/plumbing/protocol/packp/updreq.go b/plumbing/protocol/packp/updreq.go index b63b023..4d927d8 100644 --- a/plumbing/protocol/packp/updreq.go +++ b/plumbing/protocol/packp/updreq.go @@ -68,12 +68,12 @@ func NewReferenceUpdateRequestFromCapabilities(adv *capability.List) *ReferenceU return r } -func (r *ReferenceUpdateRequest) validate() error { - if len(r.Commands) == 0 { +func (req *ReferenceUpdateRequest) validate() error { + if len(req.Commands) == 0 { return ErrEmptyCommands } - for _, c := range r.Commands { + for _, c := range req.Commands { if err := c.validate(); err != nil { return err } diff --git a/plumbing/protocol/packp/updreq_encode.go b/plumbing/protocol/packp/updreq_encode.go index 6a79653..2545e93 100644 --- a/plumbing/protocol/packp/updreq_encode.go +++ b/plumbing/protocol/packp/updreq_encode.go @@ -14,33 +14,33 @@ var ( ) // Encode writes the ReferenceUpdateRequest encoding to the stream. -func (r *ReferenceUpdateRequest) Encode(w io.Writer) error { - if err := r.validate(); err != nil { +func (req *ReferenceUpdateRequest) Encode(w io.Writer) error { + if err := req.validate(); err != nil { return err } e := pktline.NewEncoder(w) - if err := r.encodeShallow(e, r.Shallow); err != nil { + if err := req.encodeShallow(e, req.Shallow); err != nil { return err } - if err := r.encodeCommands(e, r.Commands, r.Capabilities); err != nil { + if err := req.encodeCommands(e, req.Commands, req.Capabilities); err != nil { return err } - if r.Packfile != nil { - if _, err := io.Copy(w, r.Packfile); err != nil { + if req.Packfile != nil { + if _, err := io.Copy(w, req.Packfile); err != nil { return err } - return r.Packfile.Close() + return req.Packfile.Close() } return nil } -func (r *ReferenceUpdateRequest) encodeShallow(e *pktline.Encoder, +func (req *ReferenceUpdateRequest) encodeShallow(e *pktline.Encoder, h *plumbing.Hash) error { if h == nil { @@ -51,7 +51,7 @@ func (r *ReferenceUpdateRequest) encodeShallow(e *pktline.Encoder, return e.Encodef("%s%s", shallow, objId) } -func (r *ReferenceUpdateRequest) encodeCommands(e *pktline.Encoder, +func (req *ReferenceUpdateRequest) encodeCommands(e *pktline.Encoder, cmds []*Command, cap *capability.List) error { if err := e.Encodef("%s\x00%s", diff --git a/plumbing/protocol/packp/uppackresp_test.go b/plumbing/protocol/packp/uppackresp_test.go index 8950fa9..260dc57 100644 --- a/plumbing/protocol/packp/uppackresp_test.go +++ b/plumbing/protocol/packp/uppackresp_test.go @@ -4,10 +4,10 @@ import ( "bytes" "io/ioutil" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" . "gopkg.in/check.v1" - "github.com/go-git/go-git/v5/plumbing" ) type UploadPackResponseSuite struct{} diff --git a/plumbing/storer/object_test.go b/plumbing/storer/object_test.go index 8dc3623..30424ff 100644 --- a/plumbing/storer/object_test.go +++ b/plumbing/storer/object_test.go @@ -4,8 +4,9 @@ import ( "fmt" "testing" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" + + . "gopkg.in/check.v1" ) func Test(t *testing.T) { TestingT(t) } diff --git a/plumbing/storer/reference_test.go b/plumbing/storer/reference_test.go index 0660043..7a4d8b4 100644 --- a/plumbing/storer/reference_test.go +++ b/plumbing/storer/reference_test.go @@ -4,8 +4,9 @@ import ( "errors" "io" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" + + . "gopkg.in/check.v1" ) type ReferenceSuite struct{} diff --git a/plumbing/transport/file/receive_pack_test.go b/plumbing/transport/file/receive_pack_test.go index 2ee4b86..686bdcc 100644 --- a/plumbing/transport/file/receive_pack_test.go +++ b/plumbing/transport/file/receive_pack_test.go @@ -5,8 +5,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport/test" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type ReceivePackSuite struct { diff --git a/plumbing/transport/git/common_test.go b/plumbing/transport/git/common_test.go index 551b50d..3391aaf 100644 --- a/plumbing/transport/git/common_test.go +++ b/plumbing/transport/git/common_test.go @@ -13,8 +13,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) func Test(t *testing.T) { TestingT(t) } diff --git a/plumbing/transport/git/receive_pack_test.go b/plumbing/transport/git/receive_pack_test.go index 1f730a4..b661d71 100644 --- a/plumbing/transport/git/receive_pack_test.go +++ b/plumbing/transport/git/receive_pack_test.go @@ -3,8 +3,8 @@ package git import ( "github.com/go-git/go-git/v5/plumbing/transport/test" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type ReceivePackSuite struct { diff --git a/plumbing/transport/git/upload_pack_test.go b/plumbing/transport/git/upload_pack_test.go index bbfdf58..5200953 100644 --- a/plumbing/transport/git/upload_pack_test.go +++ b/plumbing/transport/git/upload_pack_test.go @@ -3,8 +3,8 @@ package git import ( "github.com/go-git/go-git/v5/plumbing/transport/test" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type UploadPackSuite struct { diff --git a/plumbing/transport/http/common_test.go b/plumbing/transport/http/common_test.go index 5811139..4122e62 100644 --- a/plumbing/transport/http/common_test.go +++ b/plumbing/transport/http/common_test.go @@ -17,8 +17,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) func Test(t *testing.T) { TestingT(t) } diff --git a/plumbing/transport/http/receive_pack_test.go b/plumbing/transport/http/receive_pack_test.go index b977908..7e70986 100644 --- a/plumbing/transport/http/receive_pack_test.go +++ b/plumbing/transport/http/receive_pack_test.go @@ -3,8 +3,8 @@ package http import ( "github.com/go-git/go-git/v5/plumbing/transport/test" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type ReceivePackSuite struct { diff --git a/plumbing/transport/http/upload_pack_test.go b/plumbing/transport/http/upload_pack_test.go index b34441d..6fae443 100644 --- a/plumbing/transport/http/upload_pack_test.go +++ b/plumbing/transport/http/upload_pack_test.go @@ -11,8 +11,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/test" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type UploadPackSuite struct { diff --git a/plumbing/transport/server/receive_pack_test.go b/plumbing/transport/server/receive_pack_test.go index 2c5b0ae..6c704bd 100644 --- a/plumbing/transport/server/receive_pack_test.go +++ b/plumbing/transport/server/receive_pack_test.go @@ -60,4 +60,5 @@ func (s *ReceivePackSuite) TestReceivePackWithNilPackfile(c *C) { report, err := r.ReceivePack(context.Background(), req) c.Assert(report, IsNil, comment) + c.Assert(err, NotNil, comment) } diff --git a/plumbing/transport/ssh/common_test.go b/plumbing/transport/ssh/common_test.go index 22a8243..87c1148 100644 --- a/plumbing/transport/ssh/common_test.go +++ b/plumbing/transport/ssh/common_test.go @@ -3,12 +3,11 @@ package ssh import ( "testing" - "github.com/kevinburke/ssh_config" + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/kevinburke/ssh_config" "golang.org/x/crypto/ssh" - . "gopkg.in/check.v1" - "github.com/go-git/go-git/v5/plumbing/transport" ) func Test(t *testing.T) { TestingT(t) } diff --git a/plumbing/transport/test/upload_pack.go b/plumbing/transport/test/upload_pack.go index ee7b067..3ee029d 100644 --- a/plumbing/transport/test/upload_pack.go +++ b/plumbing/transport/test/upload_pack.go @@ -13,11 +13,11 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/format/packfile" "github.com/go-git/go-git/v5/plumbing/protocol/packp" + "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/storage/memory" . "gopkg.in/check.v1" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" ) type UploadPackSuite struct { diff --git a/prune_test.go b/prune_test.go index bd5168d..8c726d0 100644 --- a/prune_test.go +++ b/prune_test.go @@ -9,8 +9,8 @@ import ( "github.com/go-git/go-git/v5/storage" "github.com/go-git/go-git/v5/storage/filesystem" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type PruneSuite struct { diff --git a/references_test.go b/references_test.go index 7c26ce2..28d1bb9 100644 --- a/references_test.go +++ b/references_test.go @@ -8,8 +8,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/storage/memory" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type ReferencesSuite struct { @@ -126,7 +126,7 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) { if o.Force { for i := 0; i < len(o.RefSpecs); i++ { rs := &o.RefSpecs[i] - if !rs.IsForceUpdate() { + if !rs.IsForceUpdate() && !rs.IsDelete() { o.RefSpecs[i] = config.RefSpec("+" + rs.String()) } } @@ -218,9 +218,9 @@ func (r *Remote) newReferenceUpdateRequest( if o.Progress != nil { req.Progress = o.Progress if ar.Capabilities.Supports(capability.Sideband64k) { - req.Capabilities.Set(capability.Sideband64k) + _ = req.Capabilities.Set(capability.Sideband64k) } else if ar.Capabilities.Supports(capability.Sideband) { - req.Capabilities.Set(capability.Sideband) + _ = req.Capabilities.Set(capability.Sideband) } } @@ -498,10 +498,8 @@ func (r *Remote) deleteReferences(rs config.RefSpec, if _, ok := refsDict[rs.Dst(ref.Name()).String()]; ok { return nil } - } else { - if rs.Dst("") != ref.Name() { - return nil - } + } else if rs.Dst("") != ref.Name() { + return nil } cmd := &packp.Command{ @@ -1037,21 +1035,22 @@ func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) { } var resultRefs []*plumbing.Reference - refs.ForEach(func(ref *plumbing.Reference) error { + err = refs.ForEach(func(ref *plumbing.Reference) error { resultRefs = append(resultRefs, ref) return nil }) - + if err != nil { + return nil, err + } return resultRefs, nil } func objectsToPush(commands []*packp.Command) []plumbing.Hash { - var objects []plumbing.Hash + objects := make([]plumbing.Hash, 0, len(commands)) for _, cmd := range commands { if cmd.New == plumbing.ZeroHash { continue } - objects = append(objects, cmd.New) } return objects diff --git a/remote_test.go b/remote_test.go index ce46390..c6ea9ea 100644 --- a/remote_test.go +++ b/remote_test.go @@ -558,6 +558,31 @@ func (s *RemoteSuite) TestPushDeleteReference(c *C) { c.Assert(err, Equals, plumbing.ErrReferenceNotFound) } +func (s *RemoteSuite) TestForcePushDeleteReference(c *C) { + fs := fixtures.Basic().One().DotGit() + sto := filesystem.NewStorage(fs, cache.NewObjectLRUDefault()) + + r, err := PlainClone(c.MkDir(), true, &CloneOptions{ + URL: fs.Root(), + }) + c.Assert(err, IsNil) + + remote, err := r.Remote(DefaultRemoteName) + c.Assert(err, IsNil) + + err = remote.Push(&PushOptions{ + RefSpecs: []config.RefSpec{":refs/heads/branch"}, + Force: true, + }) + c.Assert(err, IsNil) + + _, err = sto.Reference(plumbing.ReferenceName("refs/heads/branch")) + c.Assert(err, Equals, plumbing.ErrReferenceNotFound) + + _, err = r.Storer.Reference(plumbing.ReferenceName("refs/heads/branch")) + c.Assert(err, Equals, plumbing.ErrReferenceNotFound) +} + func (s *RemoteSuite) TestPushRejectNonFastForward(c *C) { fs := fixtures.Basic().One().DotGit() server := filesystem.NewStorage(fs, cache.NewObjectLRUDefault()) diff --git a/repository.go b/repository.go index 1f6de76..36fc1f5 100644 --- a/repository.go +++ b/repository.go @@ -3,6 +3,7 @@ package git import ( "bytes" "context" + "encoding/hex" "errors" "fmt" "io" @@ -92,7 +93,7 @@ func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) { } if worktree == nil { - r.setIsBare(true) + _ = r.setIsBare(true) return r, nil } @@ -277,6 +278,14 @@ func dotGitToOSFilesystems(path string, detect bool) (dot, wt billy.Filesystem, if path, err = filepath.Abs(path); err != nil { return nil, nil, err } + + pathinfo, err := os.Stat(path) + if !os.IsNotExist(err) { + if !pathinfo.IsDir() && detect { + path = filepath.Dir(path) + } + } + var fs billy.Filesystem var fi os.FileInfo for { @@ -408,7 +417,7 @@ func PlainCloneContext(ctx context.Context, path string, isBare bool, o *CloneOp err = r.clone(ctx, o) if err != nil && err != ErrRepositoryAlreadyExists { if cleanup { - cleanUpDir(path, cleanupParent) + _ = cleanUpDir(path, cleanupParent) } } @@ -1426,7 +1435,7 @@ func (r *Repository) Worktree() (*Worktree, error) { // resolve to a commit hash, not a tree or annotated tag. // // Implemented resolvers : HEAD, branch, tag, heads/branch, refs/heads/branch, -// refs/tags/tag, refs/remotes/origin/branch, refs/remotes/origin/HEAD, tilde and caret (HEAD~1, master~^, tag~2, ref/heads/master~1, ...), selection by text (HEAD^{/fix nasty bug}) +// refs/tags/tag, refs/remotes/origin/branch, refs/remotes/origin/HEAD, tilde and caret (HEAD~1, master~^, tag~2, ref/heads/master~1, ...), selection by text (HEAD^{/fix nasty bug}), hash (prefix and full) func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, error) { p := revision.NewParserFromString(string(rev)) @@ -1439,17 +1448,13 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err var commit *object.Commit for _, item := range items { - switch item.(type) { + switch item := item.(type) { case revision.Ref: - revisionRef := item.(revision.Ref) + revisionRef := item var tryHashes []plumbing.Hash - maybeHash := plumbing.NewHash(string(revisionRef)) - - if !maybeHash.IsZero() { - tryHashes = append(tryHashes, maybeHash) - } + tryHashes = append(tryHashes, r.resolveHashPrefix(string(revisionRef))...) for _, rule := range append([]string{"%s"}, plumbing.RefRevParseRules...) { ref, err := storer.ResolveReference(r.Storer, plumbing.ReferenceName(fmt.Sprintf(rule, revisionRef))) @@ -1494,7 +1499,7 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err } case revision.CaretPath: - depth := item.(revision.CaretPath).Depth + depth := item.Depth if depth == 0 { break @@ -1522,7 +1527,7 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err commit = c case revision.TildePath: - for i := 0; i < item.(revision.TildePath).Depth; i++ { + for i := 0; i < item.Depth; i++ { c, err := commit.Parents().Next() if err != nil { @@ -1534,8 +1539,8 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err case revision.CaretReg: history := object.NewCommitPreorderIter(commit, nil, nil) - re := item.(revision.CaretReg).Regexp - negate := item.(revision.CaretReg).Negate + re := item.Regexp + negate := item.Negate var c *object.Commit @@ -1567,6 +1572,49 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err return &commit.Hash, nil } +// resolveHashPrefix returns a list of potential hashes that the given string +// is a prefix of. It quietly swallows errors, returning nil. +func (r *Repository) resolveHashPrefix(hashStr string) []plumbing.Hash { + // Handle complete and partial hashes. + // plumbing.NewHash forces args into a full 20 byte hash, which isn't suitable + // for partial hashes since they will become zero-filled. + + if hashStr == "" { + return nil + } + if len(hashStr) == len(plumbing.ZeroHash)*2 { + // Only a full hash is possible. + hexb, err := hex.DecodeString(hashStr) + if err != nil { + return nil + } + var h plumbing.Hash + copy(h[:], hexb) + return []plumbing.Hash{h} + } + + // Partial hash. + // hex.DecodeString only decodes to complete bytes, so only works with pairs of hex digits. + evenHex := hashStr[:len(hashStr)&^1] + hexb, err := hex.DecodeString(evenHex) + if err != nil { + return nil + } + candidates := expandPartialHash(r.Storer, hexb) + if len(evenHex) == len(hashStr) { + // The prefix was an exact number of bytes. + return candidates + } + // Do another prefix check to ensure the dangling nybble is correct. + var hashes []plumbing.Hash + for _, h := range candidates { + if strings.HasPrefix(h.String(), hashStr) { + hashes = append(hashes, h) + } + } + return hashes +} + type RepackConfig struct { // UseRefDeltas configures whether packfile encoder will use reference deltas. // By default OFSDeltaObject is used. @@ -1659,3 +1707,31 @@ func (r *Repository) createNewObjectPack(cfg *RepackConfig) (h plumbing.Hash, er return h, err } + +func expandPartialHash(st storer.EncodedObjectStorer, prefix []byte) (hashes []plumbing.Hash) { + // The fast version is implemented by storage/filesystem.ObjectStorage. + type fastIter interface { + HashesWithPrefix(prefix []byte) ([]plumbing.Hash, error) + } + if fi, ok := st.(fastIter); ok { + h, err := fi.HashesWithPrefix(prefix) + if err != nil { + return nil + } + return h + } + + // Slow path. + iter, err := st.IterEncodedObjects(plumbing.AnyObject) + if err != nil { + return nil + } + iter.ForEach(func(obj plumbing.EncodedObject) error { + h := obj.Hash() + if bytes.HasPrefix(h[:], prefix) { + hashes = append(hashes, h) + } + return nil + }) + return +} diff --git a/repository_test.go b/repository_test.go index d1af7b6..7d4ddce 100644 --- a/repository_test.go +++ b/repository_test.go @@ -569,6 +569,11 @@ func (s *RepositorySuite) TestPlainOpenDetectDotGit(c *C) { err = os.MkdirAll(subdir, 0755) c.Assert(err, IsNil) + file := filepath.Join(subdir, "file.txt") + f, err := os.Create(file) + c.Assert(err, IsNil) + f.Close() + r, err := PlainInit(dir, false) c.Assert(err, IsNil) c.Assert(r, NotNil) @@ -577,6 +582,15 @@ func (s *RepositorySuite) TestPlainOpenDetectDotGit(c *C) { r, err = PlainOpenWithOptions(subdir, opt) c.Assert(err, IsNil) c.Assert(r, NotNil) + + r, err = PlainOpenWithOptions(file, opt) + c.Assert(err, IsNil) + c.Assert(r, NotNil) + + optnodetect := &PlainOpenOptions{DetectDotGit: false} + r, err = PlainOpenWithOptions(file, optnodetect) + c.Assert(err, NotNil) + c.Assert(r, IsNil) } func (s *RepositorySuite) TestPlainOpenNotExistsDetectDotGit(c *C) { @@ -713,7 +727,7 @@ func (s *RepositorySuite) TestPlainCloneContextNonExistentWithNotEmptyDir(c *C) c.Assert(err, IsNil) dummyFile := filepath.Join(repoDirPath, "dummyFile") - err = ioutil.WriteFile(dummyFile, []byte(fmt.Sprint("dummyContent")), 0644) + err = ioutil.WriteFile(dummyFile, []byte("dummyContent"), 0644) c.Assert(err, IsNil) r, err := PlainCloneContext(ctx, repoDirPath, false, &CloneOptions{ @@ -1875,6 +1889,7 @@ func (s *RepositorySuite) TestConfigScoped(c *C) { err := r.clone(context.Background(), &CloneOptions{ URL: s.GetBasicLocalRepositoryURL(), }) + c.Assert(err, IsNil) cfg, err := r.ConfigScoped(config.LocalScope) c.Assert(err, IsNil) @@ -2641,6 +2656,7 @@ func (s *RepositorySuite) TestResolveRevision(c *C) { "v1.0.0~1": "918c48b83bd081e863dbe1b80f8998f058cd8294", "master~1": "918c48b83bd081e863dbe1b80f8998f058cd8294", "918c48b83bd081e863dbe1b80f8998f058cd8294": "918c48b83bd081e863dbe1b80f8998f058cd8294", + "918c48b": "918c48b83bd081e863dbe1b80f8998f058cd8294", // odd number of hex digits } for rev, hash := range datas { diff --git a/storage/filesystem/config_test.go b/storage/filesystem/config_test.go index fe84698..c092d14 100644 --- a/storage/filesystem/config_test.go +++ b/storage/filesystem/config_test.go @@ -4,12 +4,12 @@ import ( "io/ioutil" "os" + "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/storage/filesystem/dotgit" - "github.com/go-git/go-billy/v5/osfs" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type ConfigSuite struct { diff --git a/storage/filesystem/dotgit/dotgit.go b/storage/filesystem/dotgit/dotgit.go index 3840ea7..6c386f7 100644 --- a/storage/filesystem/dotgit/dotgit.go +++ b/storage/filesystem/dotgit/dotgit.go @@ -3,12 +3,14 @@ package dotgit import ( "bufio" + "bytes" "errors" "fmt" "io" stdioutil "io/ioutil" "os" "path/filepath" + "sort" "strings" "time" @@ -88,7 +90,7 @@ type DotGit struct { incomingChecked bool incomingDirName string - objectList []plumbing.Hash + objectList []plumbing.Hash // sorted objectMap map[plumbing.Hash]struct{} packList []plumbing.Hash packMap map[plumbing.Hash]struct{} @@ -336,6 +338,53 @@ func (d *DotGit) NewObject() (*ObjectWriter, error) { return newObjectWriter(d.fs) } +// ObjectsWithPrefix returns the hashes of objects that have the given prefix. +func (d *DotGit) ObjectsWithPrefix(prefix []byte) ([]plumbing.Hash, error) { + // Handle edge cases. + if len(prefix) < 1 { + return d.Objects() + } else if len(prefix) > len(plumbing.ZeroHash) { + return nil, nil + } + + if d.options.ExclusiveAccess { + err := d.genObjectList() + if err != nil { + return nil, err + } + + // Rely on d.objectList being sorted. + // Figure out the half-open interval defined by the prefix. + first := sort.Search(len(d.objectList), func(i int) bool { + // Same as plumbing.HashSlice.Less. + return bytes.Compare(d.objectList[i][:], prefix) >= 0 + }) + lim := len(d.objectList) + if limPrefix, overflow := incBytes(prefix); !overflow { + lim = sort.Search(len(d.objectList), func(i int) bool { + // Same as plumbing.HashSlice.Less. + return bytes.Compare(d.objectList[i][:], limPrefix) >= 0 + }) + } + return d.objectList[first:lim], nil + } + + // This is the slow path. + var objects []plumbing.Hash + var n int + err := d.ForEachObjectHash(func(hash plumbing.Hash) error { + n++ + if bytes.HasPrefix(hash[:], prefix) { + objects = append(objects, hash) + } + return nil + }) + if err != nil { + return nil, err + } + return objects, nil +} + // Objects returns a slice with the hashes of objects found under the // .git/objects/ directory. func (d *DotGit) Objects() ([]plumbing.Hash, error) { @@ -427,12 +476,17 @@ func (d *DotGit) genObjectList() error { } d.objectMap = make(map[plumbing.Hash]struct{}) - return d.forEachObjectHash(func(h plumbing.Hash) error { + populate := func(h plumbing.Hash) error { d.objectList = append(d.objectList, h) d.objectMap[h] = struct{}{} return nil - }) + } + if err := d.forEachObjectHash(populate); err != nil { + return err + } + plumbing.HashesSort(d.objectList) + return nil } func (d *DotGit) hasObject(h plumbing.Hash) error { @@ -1115,3 +1169,20 @@ func isNum(b byte) bool { func isHexAlpha(b byte) bool { return b >= 'a' && b <= 'f' || b >= 'A' && b <= 'F' } + +// incBytes increments a byte slice, which involves incrementing the +// right-most byte, and following carry leftward. +// It makes a copy so that the provided slice's underlying array is not modified. +// If the overall operation overflows (e.g. incBytes(0xff, 0xff)), the second return parameter indicates that. +func incBytes(in []byte) (out []byte, overflow bool) { + out = make([]byte, len(in)) + copy(out, in) + for i := len(out) - 1; i >= 0; i-- { + out[i]++ + if out[i] != 0 { + return // Didn't overflow. + } + } + overflow = true + return +} diff --git a/storage/filesystem/dotgit/dotgit_test.go b/storage/filesystem/dotgit/dotgit_test.go index 0a72aa6..237605f 100644 --- a/storage/filesystem/dotgit/dotgit_test.go +++ b/storage/filesystem/dotgit/dotgit_test.go @@ -2,6 +2,7 @@ package dotgit import ( "bufio" + "encoding/hex" "io/ioutil" "os" "path/filepath" @@ -591,6 +592,7 @@ func (s *SuiteDotGit) TestObjects(c *C) { dir := New(fs) testObjects(c, fs, dir) + testObjectsWithPrefix(c, fs, dir) } func (s *SuiteDotGit) TestObjectsExclusive(c *C) { @@ -598,6 +600,7 @@ func (s *SuiteDotGit) TestObjectsExclusive(c *C) { dir := NewWithOptions(fs, Options{ExclusiveAccess: true}) testObjects(c, fs, dir) + testObjectsWithPrefix(c, fs, dir) } func testObjects(c *C, fs billy.Filesystem, dir *DotGit) { @@ -609,6 +612,20 @@ func testObjects(c *C, fs billy.Filesystem, dir *DotGit) { c.Assert(hashes[2].String(), Equals, "03db8e1fbe133a480f2867aac478fd866686d69e") } +func testObjectsWithPrefix(c *C, fs billy.Filesystem, dir *DotGit) { + prefix, _ := hex.DecodeString("01d5") + hashes, err := dir.ObjectsWithPrefix(prefix) + c.Assert(err, IsNil) + c.Assert(hashes, HasLen, 1) + c.Assert(hashes[0].String(), Equals, "01d5fa556c33743006de7e76e67a2dfcd994ca04") + + // Empty prefix should yield all objects. + // (subset of testObjects) + hashes, err = dir.ObjectsWithPrefix(nil) + c.Assert(err, IsNil) + c.Assert(hashes, HasLen, 187) +} + func (s *SuiteDotGit) TestObjectsNoFolder(c *C) { tmp, err := ioutil.TempDir("", "dot-git") c.Assert(err, IsNil) @@ -835,3 +852,21 @@ type norwfs struct { func (f *norwfs) Capabilities() billy.Capability { return billy.Capabilities(f.Filesystem) &^ billy.ReadAndWriteCapability } + +func (s *SuiteDotGit) TestIncBytes(c *C) { + tests := []struct { + in []byte + out []byte + overflow bool + }{ + {[]byte{0}, []byte{1}, false}, + {[]byte{0xff}, []byte{0}, true}, + {[]byte{7, 0xff}, []byte{8, 0}, false}, + {[]byte{0xff, 0xff}, []byte{0, 0}, true}, + } + for _, test := range tests { + out, overflow := incBytes(test.in) + c.Assert(out, DeepEquals, test.out) + c.Assert(overflow, Equals, test.overflow) + } +} diff --git a/storage/filesystem/dotgit/writers_test.go b/storage/filesystem/dotgit/writers_test.go index 246d310..7147aec 100644 --- a/storage/filesystem/dotgit/writers_test.go +++ b/storage/filesystem/dotgit/writers_test.go @@ -13,8 +13,8 @@ import ( "github.com/go-git/go-git/v5/plumbing/format/packfile" "github.com/go-git/go-billy/v5/osfs" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) func (s *SuiteDotGit) TestNewObjectPack(c *C) { diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index 7437174..0c25dad 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -1,6 +1,7 @@ package filesystem import ( + "bytes" "io" "os" "time" @@ -518,6 +519,36 @@ func (s *ObjectStorage) findObjectInPackfile(h plumbing.Hash) (plumbing.Hash, pl return plumbing.ZeroHash, plumbing.ZeroHash, -1 } +func (s *ObjectStorage) HashesWithPrefix(prefix []byte) ([]plumbing.Hash, error) { + hashes, err := s.dir.ObjectsWithPrefix(prefix) + if err != nil { + return nil, err + } + + // TODO: This could be faster with some idxfile changes, + // or diving into the packfile. + for _, index := range s.index { + ei, err := index.Entries() + if err != nil { + return nil, err + } + for { + e, err := ei.Next() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + if bytes.HasPrefix(e.Hash[:], prefix) { + hashes = append(hashes, e.Hash) + } + } + ei.Close() + } + + return hashes, nil +} + // IterEncodedObjects returns an iterator for all the objects in the packfile // with the given type. func (s *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.EncodedObjectIter, error) { diff --git a/storage/filesystem/object_test.go b/storage/filesystem/object_test.go index 2d6f568..036420f 100644 --- a/storage/filesystem/object_test.go +++ b/storage/filesystem/object_test.go @@ -1,6 +1,7 @@ package filesystem import ( + "encoding/hex" "fmt" "io" "io/ioutil" @@ -332,6 +333,22 @@ func (s *FsSuite) TestGetFromObjectFileSharedCache(c *C) { c.Assert(err, Equals, plumbing.ErrObjectNotFound) } +func (s *FsSuite) TestHashesWithPrefix(c *C) { + // Same setup as TestGetFromObjectFile. + fs := fixtures.ByTag(".git").ByTag("unpacked").One().DotGit() + o := NewObjectStorage(dotgit.New(fs), cache.NewObjectLRUDefault()) + expected := plumbing.NewHash("f3dfe29d268303fc6e1bbce268605fc99573406e") + obj, err := o.EncodedObject(plumbing.AnyObject, expected) + c.Assert(err, IsNil) + c.Assert(obj.Hash(), Equals, expected) + + prefix, _ := hex.DecodeString("f3dfe2") + hashes, err := o.HashesWithPrefix(prefix) + c.Assert(err, IsNil) + c.Assert(hashes, HasLen, 1) + c.Assert(hashes[0].String(), Equals, "f3dfe29d268303fc6e1bbce268605fc99573406e") +} + func BenchmarkPackfileIter(b *testing.B) { defer fixtures.Clean() diff --git a/storage/memory/storage.go b/storage/memory/storage.go index fdf8fcf..a8e5669 100644 --- a/storage/memory/storage.go +++ b/storage/memory/storage.go @@ -195,10 +195,10 @@ func (o *ObjectStorage) DeleteOldObjectPackAndIndex(plumbing.Hash, time.Time) er var errNotSupported = fmt.Errorf("Not supported") -func (s *ObjectStorage) LooseObjectTime(hash plumbing.Hash) (time.Time, error) { +func (o *ObjectStorage) LooseObjectTime(hash plumbing.Hash) (time.Time, error) { return time.Time{}, errNotSupported } -func (s *ObjectStorage) DeleteLooseObject(plumbing.Hash) error { +func (o *ObjectStorage) DeleteLooseObject(plumbing.Hash) error { return errNotSupported } diff --git a/storage/transactional/config_test.go b/storage/transactional/config_test.go index ec7ae89..1f3a572 100644 --- a/storage/transactional/config_test.go +++ b/storage/transactional/config_test.go @@ -1,9 +1,10 @@ package transactional import ( - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/storage/memory" + + . "gopkg.in/check.v1" ) var _ = Suite(&ConfigSuite{}) diff --git a/storage/transactional/index_test.go b/storage/transactional/index_test.go index 88fa1f5..0028c0e 100644 --- a/storage/transactional/index_test.go +++ b/storage/transactional/index_test.go @@ -1,9 +1,10 @@ package transactional import ( - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing/format/index" "github.com/go-git/go-git/v5/storage/memory" + + . "gopkg.in/check.v1" ) var _ = Suite(&IndexSuite{}) diff --git a/storage/transactional/object_test.go b/storage/transactional/object_test.go index e634409..df277c4 100644 --- a/storage/transactional/object_test.go +++ b/storage/transactional/object_test.go @@ -1,9 +1,10 @@ package transactional import ( - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/storage/memory" + + . "gopkg.in/check.v1" ) var _ = Suite(&ObjectSuite{}) diff --git a/storage/transactional/reference.go b/storage/transactional/reference.go index c3a727c..3b009e2 100644 --- a/storage/transactional/reference.go +++ b/storage/transactional/reference.go @@ -27,7 +27,7 @@ func NewReferenceStorage(base, temporal storer.ReferenceStorer) *ReferenceStorag ReferenceStorer: base, temporal: temporal, - deleted: make(map[plumbing.ReferenceName]struct{}, 0), + deleted: make(map[plumbing.ReferenceName]struct{}), } } diff --git a/storage/transactional/reference_test.go b/storage/transactional/reference_test.go index a6bd1ce..05a4fcf 100644 --- a/storage/transactional/reference_test.go +++ b/storage/transactional/reference_test.go @@ -1,9 +1,10 @@ package transactional import ( - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/storage/memory" + + . "gopkg.in/check.v1" ) var _ = Suite(&ReferenceSuite{}) diff --git a/storage/transactional/shallow_test.go b/storage/transactional/shallow_test.go index 1209fe6..15d423c 100644 --- a/storage/transactional/shallow_test.go +++ b/storage/transactional/shallow_test.go @@ -1,9 +1,10 @@ package transactional import ( - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/storage/memory" + + . "gopkg.in/check.v1" ) var _ = Suite(&ShallowSuite{}) diff --git a/submodule_test.go b/submodule_test.go index 3d81965..418b3ee 100644 --- a/submodule_test.go +++ b/submodule_test.go @@ -9,8 +9,8 @@ import ( "github.com/go-git/go-git/v5/plumbing" + fixtures "github.com/go-git/go-git-fixtures/v4" . "gopkg.in/check.v1" - "github.com/go-git/go-git-fixtures/v4" ) type SubmoduleSuite struct { diff --git a/utils/binary/read_test.go b/utils/binary/read_test.go index 3749258..bcd9dee 100644 --- a/utils/binary/read_test.go +++ b/utils/binary/read_test.go @@ -6,8 +6,9 @@ import ( "encoding/binary" "testing" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" + + . "gopkg.in/check.v1" ) func Test(t *testing.T) { TestingT(t) } diff --git a/utils/diff/diff.go b/utils/diff/diff.go index 6142ed0..7005494 100644 --- a/utils/diff/diff.go +++ b/utils/diff/diff.go @@ -29,7 +29,7 @@ func Do(src, dst string) (diffs []diffmatchpatch.Diff) { // a bulk delete+insert and the half-baked suboptimal result is returned at once. // The underlying algorithm is Meyers, its complexity is O(N*d) where N is // min(lines(src), lines(dst)) and d is the size of the diff. -func DoWithTimeout (src, dst string, timeout time.Duration) (diffs []diffmatchpatch.Diff) { +func DoWithTimeout(src, dst string, timeout time.Duration) (diffs []diffmatchpatch.Diff) { dmp := diffmatchpatch.New() dmp.DiffTimeout = timeout wSrc, wDst, warray := dmp.DiffLinesToRunes(src, dst) diff --git a/utils/merkletrie/filesystem/node.go b/utils/merkletrie/filesystem/node.go index 165bd42..2fc3d7a 100644 --- a/utils/merkletrie/filesystem/node.go +++ b/utils/merkletrie/filesystem/node.go @@ -91,8 +91,7 @@ func (n *node) calculateChildren() error { if os.IsNotExist(err) { return nil } - - return nil + return err } for _, file := range files { diff --git a/utils/merkletrie/filesystem/node_test.go b/utils/merkletrie/filesystem/node_test.go index 0f6ebe0..159e63d 100644 --- a/utils/merkletrie/filesystem/node_test.go +++ b/utils/merkletrie/filesystem/node_test.go @@ -7,12 +7,13 @@ import ( "path" "testing" - "github.com/go-git/go-billy/v5" - "github.com/go-git/go-billy/v5/memfs" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/utils/merkletrie" "github.com/go-git/go-git/v5/utils/merkletrie/noder" + + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/memfs" + . "gopkg.in/check.v1" ) func Test(t *testing.T) { TestingT(t) } diff --git a/utils/merkletrie/index/node_test.go b/utils/merkletrie/index/node_test.go index 4fa6c63..cc5600d 100644 --- a/utils/merkletrie/index/node_test.go +++ b/utils/merkletrie/index/node_test.go @@ -5,11 +5,12 @@ import ( "path/filepath" "testing" - . "gopkg.in/check.v1" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/format/index" "github.com/go-git/go-git/v5/utils/merkletrie" "github.com/go-git/go-git/v5/utils/merkletrie/noder" + + . "gopkg.in/check.v1" ) func Test(t *testing.T) { TestingT(t) } diff --git a/worktree.go b/worktree.go index d272373..62ad03b 100644 --- a/worktree.go +++ b/worktree.go @@ -93,7 +93,7 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { head, err := w.r.Head() if err == nil { - headAheadOfRef,err := isFastForward(w.r.Storer, ref.Hash(), head.Hash()) + headAheadOfRef, err := isFastForward(w.r.Storer, ref.Hash(), head.Hash()) if err != nil { return err } @@ -102,7 +102,6 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { return NoErrAlreadyUpToDate } - ff, err := isFastForward(w.r.Storer, head.Hash(), ref.Hash()) if err != nil { return err diff --git a/worktree_commit.go b/worktree_commit.go index 63eb2e8..a9d0e04 100644 --- a/worktree_commit.go +++ b/worktree_commit.go @@ -6,7 +6,6 @@ import ( "sort" "strings" - "golang.org/x/crypto/openpgp" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/filemode" "github.com/go-git/go-git/v5/plumbing/format/index" @@ -14,6 +13,7 @@ import ( "github.com/go-git/go-git/v5/storage" "github.com/go-git/go-billy/v5" + "golang.org/x/crypto/openpgp" ) // Commit stores the current contents of the index in a new commit along with @@ -58,17 +58,23 @@ func (w *Worktree) autoAddModifiedAndDeleted() error { return err } + idx, err := w.r.Storer.Index() + if err != nil { + return err + } + for path, fs := range s { if fs.Worktree != Modified && fs.Worktree != Deleted { continue } - if _, err := w.Add(path); err != nil { + if _, _, err := w.doAddFile(idx, s, path, nil); err != nil { return err } + } - return nil + return w.r.Storer.SetIndex(idx) } func (w *Worktree) updateHEAD(commit plumbing.Hash) error { |