diff --git a/go.mod b/go.mod index c0088ab63..7ff18e323 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,12 @@ require ( github.com/fatih/color v1.9.0 github.com/fsnotify/fsnotify v1.4.7 github.com/go-errors/errors v1.1.1 - github.com/go-git/go-git/v5 v5.0.0 github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 github.com/golang/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.3.1 // indirect github.com/integrii/flaggy v1.4.0 + github.com/jesseduffield/go-git/v5 v5.1.1 github.com/jesseduffield/gocui v0.3.1-0.20200930205305-1b445b9bd5da github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 @@ -40,3 +40,5 @@ require ( golang.org/x/text v0.3.2 gopkg.in/yaml.v2 v2.2.7 ) + +replace github.com/go-git/go-git/v5 => github.com/jesseduffield/go-git/v5 v5.1.1 diff --git a/go.sum b/go.sum index 0f1cbe1f0..528fadcbd 100644 --- a/go.sum +++ b/go.sum @@ -55,10 +55,8 @@ github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc= -github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.0.0 h1:k5RWPm4iJwYtfWoxIJy4wJX9ON7ihPeZZYC1fLYDnpg= -github.com/go-git/go-git/v5 v5.0.0/go.mod h1:oYD8y9kWsGINPFJoLdaScGCN6dlKg23blmClfZwtUVA= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= @@ -92,14 +90,14 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/integrii/flaggy v1.4.0 h1:A1x7SYx4jqu5NSrY14z8Z+0UyX2S5ygfJJrfolWR3zM= github.com/integrii/flaggy v1.4.0/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jesseduffield/gocui v0.3.1-0.20200824100831-1b6ec5d7d449 h1:G5Cm2QuFil8fnrMqUHYFiUkVSS/SXnn3ATtU7MbMFI0= -github.com/jesseduffield/gocui v0.3.1-0.20200824100831-1b6ec5d7d449/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw= -github.com/jesseduffield/gocui v0.3.1-0.20200927010622-b998f1723844 h1:D2/gUHscz5LmHojvNUmEVtvNBlX8OF6Ez82oW7GitfI= -github.com/jesseduffield/gocui v0.3.1-0.20200927010622-b998f1723844/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw= +github.com/jesseduffield/go-git/v5 v5.1.1 h1:ihQ0E8QQnKrSQvbXhhErmUSB7G6tkURD6Kx/jm6RzO0= +github.com/jesseduffield/go-git/v5 v5.1.1/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o= github.com/jesseduffield/gocui v0.3.1-0.20200930205305-1b445b9bd5da h1:I3GD+Set99tj57PgmjZJLoW6lkv0NTHadKNosJ1OKj4= github.com/jesseduffield/gocui v0.3.1-0.20200930205305-1b445b9bd5da/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw= github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe h1:qsVhCf2RFyyKIUe/+gJblbCpXMUki9rZrHuEctg6M/E= diff --git a/pkg/commands/git.go b/pkg/commands/git.go index ab2819f75..af1533886 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -8,7 +8,7 @@ import ( "github.com/go-errors/errors" - gogit "github.com/go-git/go-git/v5" + gogit "github.com/jesseduffield/go-git/v5" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/commands/patch" "github.com/jesseduffield/lazygit/pkg/config" diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index cab1ba39f..87384930f 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/go-errors/errors" - gogit "github.com/go-git/go-git/v5" + gogit "github.com/jesseduffield/go-git/v5" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/config" diff --git a/pkg/commands/status.go b/pkg/commands/status.go index 83d16759c..c5a6c2526 100644 --- a/pkg/commands/status.go +++ b/pkg/commands/status.go @@ -3,7 +3,7 @@ package commands import ( "path/filepath" - gogit "github.com/go-git/go-git/v5" + gogit "github.com/jesseduffield/go-git/v5" ) // RebaseMode returns "" for non-rebase mode, "normal" for normal rebase diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/unified_encoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/unified_encoder.go deleted file mode 100644 index f2bc910a2..000000000 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/unified_encoder.go +++ /dev/null @@ -1,367 +0,0 @@ -package diff - -import ( - "bytes" - "fmt" - "io" - "regexp" - "strings" - - "github.com/go-git/go-git/v5/plumbing" -) - -const ( - diffInit = "diff --git a/%s b/%s\n" - - chunkStart = "@@ -" - chunkMiddle = " +" - chunkEnd = " @@%s\n" - chunkCount = "%d,%d" - - noFilePath = "/dev/null" - aDir = "a/" - bDir = "b/" - - fPath = "--- %s\n" - tPath = "+++ %s\n" - binary = "Binary files %s and %s differ\n" - - addLine = "+%s%s" - deleteLine = "-%s%s" - equalLine = " %s%s" - noNewLine = "\n\\ No newline at end of file\n" - - oldMode = "old mode %o\n" - newMode = "new mode %o\n" - deletedFileMode = "deleted file mode %o\n" - newFileMode = "new file mode %o\n" - - renameFrom = "from" - renameTo = "to" - renameFileMode = "rename %s %s\n" - - indexAndMode = "index %s..%s %o\n" - indexNoMode = "index %s..%s\n" - - DefaultContextLines = 3 -) - -// UnifiedEncoder encodes an unified diff into the provided Writer. -// There are some unsupported features: -// - Similarity index for renames -// - Sort hash representation -type UnifiedEncoder struct { - io.Writer - - // ctxLines is the count of unchanged lines that will appear - // surrounding a change. - ctxLines int - - buf bytes.Buffer -} - -func NewUnifiedEncoder(w io.Writer, ctxLines int) *UnifiedEncoder { - return &UnifiedEncoder{ctxLines: ctxLines, Writer: w} -} - -func (e *UnifiedEncoder) Encode(patch Patch) error { - e.printMessage(patch.Message()) - - if err := e.encodeFilePatch(patch.FilePatches()); err != nil { - return err - } - - _, err := e.buf.WriteTo(e) - - return err -} - -func (e *UnifiedEncoder) encodeFilePatch(filePatches []FilePatch) error { - for _, p := range filePatches { - f, t := p.Files() - if err := e.header(f, t, p.IsBinary()); err != nil { - return err - } - - g := newHunksGenerator(p.Chunks(), e.ctxLines) - for _, c := range g.Generate() { - c.WriteTo(&e.buf) - } - } - - return nil -} - -func (e *UnifiedEncoder) printMessage(message string) { - isEmpty := message == "" - hasSuffix := strings.HasSuffix(message, "\n") - if !isEmpty && !hasSuffix { - message += "\n" - } - - e.buf.WriteString(message) -} - -func (e *UnifiedEncoder) header(from, to File, isBinary bool) error { - switch { - case from == nil && to == nil: - return nil - case from != nil && to != nil: - hashEquals := from.Hash() == to.Hash() - - fmt.Fprintf(&e.buf, diffInit, from.Path(), to.Path()) - - if from.Mode() != to.Mode() { - fmt.Fprintf(&e.buf, oldMode+newMode, from.Mode(), to.Mode()) - } - - if from.Path() != to.Path() { - fmt.Fprintf(&e.buf, - renameFileMode+renameFileMode, - renameFrom, from.Path(), renameTo, to.Path()) - } - - if from.Mode() != to.Mode() && !hashEquals { - fmt.Fprintf(&e.buf, indexNoMode, from.Hash(), to.Hash()) - } else if !hashEquals { - fmt.Fprintf(&e.buf, indexAndMode, from.Hash(), to.Hash(), from.Mode()) - } - - if !hashEquals { - e.pathLines(isBinary, aDir+from.Path(), bDir+to.Path()) - } - case from == nil: - fmt.Fprintf(&e.buf, diffInit, to.Path(), to.Path()) - fmt.Fprintf(&e.buf, newFileMode, to.Mode()) - fmt.Fprintf(&e.buf, indexNoMode, plumbing.ZeroHash, to.Hash()) - e.pathLines(isBinary, noFilePath, bDir+to.Path()) - case to == nil: - fmt.Fprintf(&e.buf, diffInit, from.Path(), from.Path()) - fmt.Fprintf(&e.buf, deletedFileMode, from.Mode()) - fmt.Fprintf(&e.buf, indexNoMode, from.Hash(), plumbing.ZeroHash) - e.pathLines(isBinary, aDir+from.Path(), noFilePath) - } - - return nil -} - -func (e *UnifiedEncoder) pathLines(isBinary bool, fromPath, toPath string) { - format := fPath + tPath - if isBinary { - format = binary - } - - fmt.Fprintf(&e.buf, format, fromPath, toPath) -} - -type hunksGenerator struct { - fromLine, toLine int - ctxLines int - chunks []Chunk - current *hunk - hunks []*hunk - beforeContext, afterContext []string -} - -func newHunksGenerator(chunks []Chunk, ctxLines int) *hunksGenerator { - return &hunksGenerator{ - chunks: chunks, - ctxLines: ctxLines, - } -} - -func (c *hunksGenerator) Generate() []*hunk { - for i, chunk := range c.chunks { - ls := splitLines(chunk.Content()) - lsLen := len(ls) - - switch chunk.Type() { - case Equal: - c.fromLine += lsLen - c.toLine += lsLen - c.processEqualsLines(ls, i) - case Delete: - if lsLen != 0 { - c.fromLine++ - } - - c.processHunk(i, chunk.Type()) - c.fromLine += lsLen - 1 - c.current.AddOp(chunk.Type(), ls...) - case Add: - if lsLen != 0 { - c.toLine++ - } - c.processHunk(i, chunk.Type()) - c.toLine += lsLen - 1 - c.current.AddOp(chunk.Type(), ls...) - } - - if i == len(c.chunks)-1 && c.current != nil { - c.hunks = append(c.hunks, c.current) - } - } - - return c.hunks -} - -func (c *hunksGenerator) processHunk(i int, op Operation) { - if c.current != nil { - return - } - - var ctxPrefix string - linesBefore := len(c.beforeContext) - if linesBefore > c.ctxLines { - ctxPrefix = " " + c.beforeContext[linesBefore-c.ctxLines-1] - c.beforeContext = c.beforeContext[linesBefore-c.ctxLines:] - linesBefore = c.ctxLines - } - - c.current = &hunk{ctxPrefix: strings.TrimSuffix(ctxPrefix, "\n")} - c.current.AddOp(Equal, c.beforeContext...) - - switch op { - case Delete: - c.current.fromLine, c.current.toLine = - c.addLineNumbers(c.fromLine, c.toLine, linesBefore, i, Add) - case Add: - c.current.toLine, c.current.fromLine = - c.addLineNumbers(c.toLine, c.fromLine, linesBefore, i, Delete) - } - - c.beforeContext = nil -} - -// addLineNumbers obtains the line numbers in a new chunk -func (c *hunksGenerator) addLineNumbers(la, lb int, linesBefore int, i int, op Operation) (cla, clb int) { - cla = la - linesBefore - // we need to search for a reference for the next diff - switch { - case linesBefore != 0 && c.ctxLines != 0: - if lb > c.ctxLines { - clb = lb - c.ctxLines + 1 - } else { - clb = 1 - } - case c.ctxLines == 0: - clb = lb - case i != len(c.chunks)-1: - next := c.chunks[i+1] - if next.Type() == op || next.Type() == Equal { - // this diff will be into this chunk - clb = lb + 1 - } - } - - return -} - -func (c *hunksGenerator) processEqualsLines(ls []string, i int) { - if c.current == nil { - c.beforeContext = append(c.beforeContext, ls...) - return - } - - c.afterContext = append(c.afterContext, ls...) - if len(c.afterContext) <= c.ctxLines*2 && i != len(c.chunks)-1 { - c.current.AddOp(Equal, c.afterContext...) - c.afterContext = nil - } else { - ctxLines := c.ctxLines - if ctxLines > len(c.afterContext) { - ctxLines = len(c.afterContext) - } - c.current.AddOp(Equal, c.afterContext[:ctxLines]...) - c.hunks = append(c.hunks, c.current) - - c.current = nil - c.beforeContext = c.afterContext[ctxLines:] - c.afterContext = nil - } -} - -var splitLinesRE = regexp.MustCompile(`[^\n]*(\n|$)`) - -func splitLines(s string) []string { - out := splitLinesRE.FindAllString(s, -1) - if out[len(out)-1] == "" { - out = out[:len(out)-1] - } - return out -} - -type hunk struct { - fromLine int - toLine int - - fromCount int - toCount int - - ctxPrefix string - ops []*op -} - -func (c *hunk) WriteTo(buf *bytes.Buffer) { - buf.WriteString(chunkStart) - - if c.fromCount == 1 { - fmt.Fprintf(buf, "%d", c.fromLine) - } else { - fmt.Fprintf(buf, chunkCount, c.fromLine, c.fromCount) - } - - buf.WriteString(chunkMiddle) - - if c.toCount == 1 { - fmt.Fprintf(buf, "%d", c.toLine) - } else { - fmt.Fprintf(buf, chunkCount, c.toLine, c.toCount) - } - - fmt.Fprintf(buf, chunkEnd, c.ctxPrefix) - - for _, d := range c.ops { - buf.WriteString(d.String()) - } -} - -func (c *hunk) AddOp(t Operation, s ...string) { - ls := len(s) - switch t { - case Add: - c.toCount += ls - case Delete: - c.fromCount += ls - case Equal: - c.toCount += ls - c.fromCount += ls - } - - for _, l := range s { - c.ops = append(c.ops, &op{l, t}) - } -} - -type op struct { - text string - t Operation -} - -func (o *op) String() string { - var prefix, suffix string - switch o.t { - case Add: - prefix = addLine - case Delete: - prefix = deleteLine - case Equal: - prefix = equalLine - } - n := len(o.text) - if n > 0 && o.text[n-1] != '\n' { - suffix = noNewLine - } - - return fmt.Sprintf(prefix, o.text, suffix) -} diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/difftree.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/difftree.go deleted file mode 100644 index 72411a590..000000000 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/difftree.go +++ /dev/null @@ -1,37 +0,0 @@ -package object - -import ( - "bytes" - "context" - - "github.com/go-git/go-git/v5/utils/merkletrie" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" -) - -// DiffTree compares the content and mode of the blobs found via two -// tree objects. -func DiffTree(a, b *Tree) (Changes, error) { - return DiffTreeContext(context.Background(), a, b) -} - -// DiffTree compares the content and mode of the blobs found via two -// tree objects. Provided context must be non-nil. -// An error will be return if context expires -func DiffTreeContext(ctx context.Context, a, b *Tree) (Changes, error) { - from := NewTreeRootNode(a) - to := NewTreeRootNode(b) - - hashEqual := func(a, b noder.Hasher) bool { - return bytes.Equal(a.Hash(), b.Hash()) - } - - merkletrieChanges, err := merkletrie.DiffTreeContext(ctx, from, to, hashEqual) - if err != nil { - if err == merkletrie.ErrCanceled { - return nil, ErrCanceled - } - return nil, err - } - - return newChanges(merkletrieChanges) -} diff --git a/vendor/github.com/imdario/mergo/.gitignore b/vendor/github.com/imdario/mergo/.gitignore new file mode 100644 index 000000000..529c3412b --- /dev/null +++ b/vendor/github.com/imdario/mergo/.gitignore @@ -0,0 +1,33 @@ +#### joe made this: http://goel.io/joe + +#### go #### +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +#### vim #### +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] + +# Session +Session.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags diff --git a/vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md b/vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..469b44907 --- /dev/null +++ b/vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at i@dario.im. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/imdario/mergo/LICENSE b/vendor/github.com/imdario/mergo/LICENSE new file mode 100644 index 000000000..686680298 --- /dev/null +++ b/vendor/github.com/imdario/mergo/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2013 Dario Castañé. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md new file mode 100644 index 000000000..02fc81e06 --- /dev/null +++ b/vendor/github.com/imdario/mergo/README.md @@ -0,0 +1,238 @@ +# Mergo + +A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements. + +Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche. + +## Status + +It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc](https://github.com/imdario/mergo#mergo-in-the-wild). + +[![GoDoc][3]][4] +[![GoCard][5]][6] +[![Build Status][1]][2] +[![Coverage Status][7]][8] +[![Sourcegraph][9]][10] +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield) + +[1]: https://travis-ci.org/imdario/mergo.png +[2]: https://travis-ci.org/imdario/mergo +[3]: https://godoc.org/github.com/imdario/mergo?status.svg +[4]: https://godoc.org/github.com/imdario/mergo +[5]: https://goreportcard.com/badge/imdario/mergo +[6]: https://goreportcard.com/report/github.com/imdario/mergo +[7]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master +[8]: https://coveralls.io/github/imdario/mergo?branch=master +[9]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg +[10]: https://sourcegraph.com/github.com/imdario/mergo?badge + +### Latest release + +[Release v0.3.7](https://github.com/imdario/mergo/releases/tag/v0.3.7). + +### Important note + +Please keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2) Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). An optional/variadic argument has been added, so it won't break existing code. + +If you were using Mergo **before** April 6th 2015, please check your project works as intended after updating your local copy with ```go get -u github.com/imdario/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause (I hope it won't!) in existing projects after the change (release 0.2.0). + +### Donations + +If Mergo is useful to you, consider buying me a coffee, a beer or making a monthly donation so I can keep building great free software. :heart_eyes: + +Buy Me a Coffee at ko-fi.com +[![Beerpay](https://beerpay.io/imdario/mergo/badge.svg)](https://beerpay.io/imdario/mergo) +[![Beerpay](https://beerpay.io/imdario/mergo/make-wish.svg)](https://beerpay.io/imdario/mergo) +Donate using Liberapay + +### Mergo in the wild + +- [moby/moby](https://github.com/moby/moby) +- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) +- [vmware/dispatch](https://github.com/vmware/dispatch) +- [Shopify/themekit](https://github.com/Shopify/themekit) +- [imdario/zas](https://github.com/imdario/zas) +- [matcornic/hermes](https://github.com/matcornic/hermes) +- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go) +- [kataras/iris](https://github.com/kataras/iris) +- [michaelsauter/crane](https://github.com/michaelsauter/crane) +- [go-task/task](https://github.com/go-task/task) +- [sensu/uchiwa](https://github.com/sensu/uchiwa) +- [ory/hydra](https://github.com/ory/hydra) +- [sisatech/vcli](https://github.com/sisatech/vcli) +- [dairycart/dairycart](https://github.com/dairycart/dairycart) +- [projectcalico/felix](https://github.com/projectcalico/felix) +- [resin-os/balena](https://github.com/resin-os/balena) +- [go-kivik/kivik](https://github.com/go-kivik/kivik) +- [Telefonica/govice](https://github.com/Telefonica/govice) +- [supergiant/supergiant](supergiant/supergiant) +- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce) +- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy) +- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel) +- [EagerIO/Stout](https://github.com/EagerIO/Stout) +- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api) +- [russross/canvasassignments](https://github.com/russross/canvasassignments) +- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api) +- [casualjim/exeggutor](https://github.com/casualjim/exeggutor) +- [divshot/gitling](https://github.com/divshot/gitling) +- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl) +- [andrerocker/deploy42](https://github.com/andrerocker/deploy42) +- [elwinar/rambler](https://github.com/elwinar/rambler) +- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman) +- [jfbus/impressionist](https://github.com/jfbus/impressionist) +- [Jmeyering/zealot](https://github.com/Jmeyering/zealot) +- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host) +- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go) +- [thoas/picfit](https://github.com/thoas/picfit) +- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server) +- [jnuthong/item_search](https://github.com/jnuthong/item_search) +- [bukalapak/snowboard](https://github.com/bukalapak/snowboard) + +## Installation + + go get github.com/imdario/mergo + + // use in your .go code + import ( + "github.com/imdario/mergo" + ) + +## Usage + +You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are not considered zero values](https://golang.org/ref/spec#The_zero_value) either. Also maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection). + +```go +if err := mergo.Merge(&dst, src); err != nil { + // ... +} +``` + +Also, you can merge overwriting values using the transformer `WithOverride`. + +```go +if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil { + // ... +} +``` + +Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field. + +```go +if err := mergo.Map(&dst, srcMap); err != nil { + // ... +} +``` + +Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values. + +More information and examples in [godoc documentation](http://godoc.org/github.com/imdario/mergo). + +### Nice example + +```go +package main + +import ( + "fmt" + "github.com/imdario/mergo" +) + +type Foo struct { + A string + B int64 +} + +func main() { + src := Foo{ + A: "one", + B: 2, + } + dest := Foo{ + A: "two", + } + mergo.Merge(&dest, src) + fmt.Println(dest) + // Will print + // {two 2} +} +``` + +Note: if test are failing due missing package, please execute: + + go get gopkg.in/yaml.v2 + +### Transformers + +Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`? + +```go +package main + +import ( + "fmt" + "github.com/imdario/mergo" + "reflect" + "time" +) + +type timeTransfomer struct { +} + +func (t timeTransfomer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error { + if typ == reflect.TypeOf(time.Time{}) { + return func(dst, src reflect.Value) error { + if dst.CanSet() { + isZero := dst.MethodByName("IsZero") + result := isZero.Call([]reflect.Value{}) + if result[0].Bool() { + dst.Set(src) + } + } + return nil + } + } + return nil +} + +type Snapshot struct { + Time time.Time + // ... +} + +func main() { + src := Snapshot{time.Now()} + dest := Snapshot{} + mergo.Merge(&dest, src, mergo.WithTransformers(timeTransfomer{})) + fmt.Println(dest) + // Will print + // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 } +} +``` + + +## Contact me + +If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario) + +## About + +Written by [Dario Castañé](http://dario.im). + +## Top Contributors + +[![0](https://sourcerer.io/fame/imdario/imdario/mergo/images/0)](https://sourcerer.io/fame/imdario/imdario/mergo/links/0) +[![1](https://sourcerer.io/fame/imdario/imdario/mergo/images/1)](https://sourcerer.io/fame/imdario/imdario/mergo/links/1) +[![2](https://sourcerer.io/fame/imdario/imdario/mergo/images/2)](https://sourcerer.io/fame/imdario/imdario/mergo/links/2) +[![3](https://sourcerer.io/fame/imdario/imdario/mergo/images/3)](https://sourcerer.io/fame/imdario/imdario/mergo/links/3) +[![4](https://sourcerer.io/fame/imdario/imdario/mergo/images/4)](https://sourcerer.io/fame/imdario/imdario/mergo/links/4) +[![5](https://sourcerer.io/fame/imdario/imdario/mergo/images/5)](https://sourcerer.io/fame/imdario/imdario/mergo/links/5) +[![6](https://sourcerer.io/fame/imdario/imdario/mergo/images/6)](https://sourcerer.io/fame/imdario/imdario/mergo/links/6) +[![7](https://sourcerer.io/fame/imdario/imdario/mergo/images/7)](https://sourcerer.io/fame/imdario/imdario/mergo/links/7) + + +## License + +[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE). + + +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large) diff --git a/vendor/github.com/imdario/mergo/doc.go b/vendor/github.com/imdario/mergo/doc.go new file mode 100644 index 000000000..6e9aa7baf --- /dev/null +++ b/vendor/github.com/imdario/mergo/doc.go @@ -0,0 +1,44 @@ +// Copyright 2013 Dario Castañé. All rights reserved. +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package mergo merges same-type structs and maps by setting default values in zero-value fields. + +Mergo won't merge unexported (private) fields but will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection). + +Usage + +From my own work-in-progress project: + + type networkConfig struct { + Protocol string + Address string + ServerType string `json: "server_type"` + Port uint16 + } + + type FssnConfig struct { + Network networkConfig + } + + var fssnDefault = FssnConfig { + networkConfig { + "tcp", + "127.0.0.1", + "http", + 31560, + }, + } + + // Inside a function [...] + + if err := mergo.Merge(&config, fssnDefault); err != nil { + log.Fatal(err) + } + + // More code [...] + +*/ +package mergo diff --git a/vendor/github.com/imdario/mergo/map.go b/vendor/github.com/imdario/mergo/map.go new file mode 100644 index 000000000..d83258b4d --- /dev/null +++ b/vendor/github.com/imdario/mergo/map.go @@ -0,0 +1,176 @@ +// Copyright 2014 Dario Castañé. All rights reserved. +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Based on src/pkg/reflect/deepequal.go from official +// golang's stdlib. + +package mergo + +import ( + "fmt" + "reflect" + "unicode" + "unicode/utf8" +) + +func changeInitialCase(s string, mapper func(rune) rune) string { + if s == "" { + return s + } + r, n := utf8.DecodeRuneInString(s) + return string(mapper(r)) + s[n:] +} + +func isExported(field reflect.StructField) bool { + r, _ := utf8.DecodeRuneInString(field.Name) + return r >= 'A' && r <= 'Z' +} + +// Traverses recursively both values, assigning src's fields values to dst. +// The map argument tracks comparisons that have already been seen, which allows +// short circuiting on recursive types. +func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) { + overwrite := config.Overwrite + if dst.CanAddr() { + addr := dst.UnsafeAddr() + h := 17 * addr + seen := visited[h] + typ := dst.Type() + for p := seen; p != nil; p = p.next { + if p.ptr == addr && p.typ == typ { + return nil + } + } + // Remember, remember... + visited[h] = &visit{addr, typ, seen} + } + zeroValue := reflect.Value{} + switch dst.Kind() { + case reflect.Map: + dstMap := dst.Interface().(map[string]interface{}) + for i, n := 0, src.NumField(); i < n; i++ { + srcType := src.Type() + field := srcType.Field(i) + if !isExported(field) { + continue + } + fieldName := field.Name + fieldName = changeInitialCase(fieldName, unicode.ToLower) + if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v)) || overwrite) { + dstMap[fieldName] = src.Field(i).Interface() + } + } + case reflect.Ptr: + if dst.IsNil() { + v := reflect.New(dst.Type().Elem()) + dst.Set(v) + } + dst = dst.Elem() + fallthrough + case reflect.Struct: + srcMap := src.Interface().(map[string]interface{}) + for key := range srcMap { + config.overwriteWithEmptyValue = true + srcValue := srcMap[key] + fieldName := changeInitialCase(key, unicode.ToUpper) + dstElement := dst.FieldByName(fieldName) + if dstElement == zeroValue { + // We discard it because the field doesn't exist. + continue + } + srcElement := reflect.ValueOf(srcValue) + dstKind := dstElement.Kind() + srcKind := srcElement.Kind() + if srcKind == reflect.Ptr && dstKind != reflect.Ptr { + srcElement = srcElement.Elem() + srcKind = reflect.TypeOf(srcElement.Interface()).Kind() + } else if dstKind == reflect.Ptr { + // Can this work? I guess it can't. + if srcKind != reflect.Ptr && srcElement.CanAddr() { + srcPtr := srcElement.Addr() + srcElement = reflect.ValueOf(srcPtr) + srcKind = reflect.Ptr + } + } + + if !srcElement.IsValid() { + continue + } + if srcKind == dstKind { + if _, err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil { + return + } + } else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface { + if _, err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil { + return + } + } else if srcKind == reflect.Map { + if err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil { + return + } + } else { + return fmt.Errorf("type mismatch on %s field: found %v, expected %v", fieldName, srcKind, dstKind) + } + } + } + return +} + +// Map sets fields' values in dst from src. +// src can be a map with string keys or a struct. dst must be the opposite: +// if src is a map, dst must be a valid pointer to struct. If src is a struct, +// dst must be map[string]interface{}. +// It won't merge unexported (private) fields and will do recursively +// any exported field. +// If dst is a map, keys will be src fields' names in lower camel case. +// Missing key in src that doesn't match a field in dst will be skipped. This +// doesn't apply if dst is a map. +// This is separated method from Merge because it is cleaner and it keeps sane +// semantics: merging equal types, mapping different (restricted) types. +func Map(dst, src interface{}, opts ...func(*Config)) error { + return _map(dst, src, opts...) +} + +// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overridden by +// non-empty src attribute values. +// Deprecated: Use Map(…) with WithOverride +func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error { + return _map(dst, src, append(opts, WithOverride)...) +} + +func _map(dst, src interface{}, opts ...func(*Config)) error { + var ( + vDst, vSrc reflect.Value + err error + ) + config := &Config{} + + for _, opt := range opts { + opt(config) + } + + if vDst, vSrc, err = resolveValues(dst, src); err != nil { + return err + } + // To be friction-less, we redirect equal-type arguments + // to deepMerge. Only because arguments can be anything. + if vSrc.Kind() == vDst.Kind() { + _, err := deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config) + return err + } + switch vSrc.Kind() { + case reflect.Struct: + if vDst.Kind() != reflect.Map { + return ErrExpectedMapAsDestination + } + case reflect.Map: + if vDst.Kind() != reflect.Struct { + return ErrExpectedStructAsDestination + } + default: + return ErrNotSupported + } + return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config) +} diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go new file mode 100644 index 000000000..3332c9c2a --- /dev/null +++ b/vendor/github.com/imdario/mergo/merge.go @@ -0,0 +1,338 @@ +// Copyright 2013 Dario Castañé. All rights reserved. +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Based on src/pkg/reflect/deepequal.go from official +// golang's stdlib. + +package mergo + +import ( + "fmt" + "reflect" + "unsafe" +) + +func hasExportedField(dst reflect.Value) (exported bool) { + for i, n := 0, dst.NumField(); i < n; i++ { + field := dst.Type().Field(i) + if isExportedComponent(&field) { + return true + } + } + return +} + +func isExportedComponent(field *reflect.StructField) bool { + name := field.Name + pkgPath := field.PkgPath + if len(pkgPath) > 0 { + return false + } + c := name[0] + if 'a' <= c && c <= 'z' || c == '_' { + return false + } + return true +} + +type Config struct { + Overwrite bool + AppendSlice bool + TypeCheck bool + Transformers Transformers + overwriteWithEmptyValue bool + overwriteSliceWithEmptyValue bool +} + +type Transformers interface { + Transformer(reflect.Type) func(dst, src reflect.Value) error +} + +// Traverses recursively both values, assigning src's fields values to dst. +// The map argument tracks comparisons that have already been seen, which allows +// short circuiting on recursive types. +func deepMerge(dstIn, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (dst reflect.Value, err error) { + dst = dstIn + overwrite := config.Overwrite + typeCheck := config.TypeCheck + overwriteWithEmptySrc := config.overwriteWithEmptyValue + overwriteSliceWithEmptySrc := config.overwriteSliceWithEmptyValue + + if !src.IsValid() { + return + } + + if dst.CanAddr() { + addr := dst.UnsafeAddr() + h := 17 * addr + seen := visited[h] + typ := dst.Type() + for p := seen; p != nil; p = p.next { + if p.ptr == addr && p.typ == typ { + return dst, nil + } + } + // Remember, remember... + visited[h] = &visit{addr, typ, seen} + } + + if config.Transformers != nil && !isEmptyValue(dst) { + if fn := config.Transformers.Transformer(dst.Type()); fn != nil { + err = fn(dst, src) + return + } + } + + if dst.IsValid() && src.IsValid() && src.Type() != dst.Type() { + err = fmt.Errorf("cannot append two different types (%s, %s)", src.Kind(), dst.Kind()) + return + } + + switch dst.Kind() { + case reflect.Struct: + if hasExportedField(dst) { + dstCp := reflect.New(dst.Type()).Elem() + for i, n := 0, dst.NumField(); i < n; i++ { + dstField := dst.Field(i) + structField := dst.Type().Field(i) + // copy un-exported struct fields + if !isExportedComponent(&structField) { + rf := dstCp.Field(i) + rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem() //nolint:gosec + dstRF := dst.Field(i) + if !dst.Field(i).CanAddr() { + continue + } + + dstRF = reflect.NewAt(dstRF.Type(), unsafe.Pointer(dstRF.UnsafeAddr())).Elem() //nolint:gosec + rf.Set(dstRF) + continue + } + dstField, err = deepMerge(dstField, src.Field(i), visited, depth+1, config) + if err != nil { + return + } + dstCp.Field(i).Set(dstField) + } + + if dst.CanSet() { + dst.Set(dstCp) + } else { + dst = dstCp + } + return + } else { + if (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) { + dst = src + } + } + + case reflect.Map: + if dst.IsNil() && !src.IsNil() { + if dst.CanSet() { + dst.Set(reflect.MakeMap(dst.Type())) + } else { + dst = src + return + } + } + for _, key := range src.MapKeys() { + srcElement := src.MapIndex(key) + dstElement := dst.MapIndex(key) + if !srcElement.IsValid() { + continue + } + if dst.MapIndex(key).IsValid() { + k := dstElement.Interface() + dstElement = reflect.ValueOf(k) + } + if isReflectNil(srcElement) { + if overwrite || isReflectNil(dstElement) { + dst.SetMapIndex(key, srcElement) + } + continue + } + if !srcElement.CanInterface() { + continue + } + + if srcElement.CanInterface() { + srcElement = reflect.ValueOf(srcElement.Interface()) + if dstElement.IsValid() { + dstElement = reflect.ValueOf(dstElement.Interface()) + } + } + dstElement, err = deepMerge(dstElement, srcElement, visited, depth+1, config) + if err != nil { + return + } + dst.SetMapIndex(key, dstElement) + + } + case reflect.Slice: + newSlice := dst + if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { + if typeCheck && src.Type() != dst.Type() { + return dst, fmt.Errorf("cannot override two slices with different type (%s, %s)", src.Type(), dst.Type()) + } + newSlice = src + } else if config.AppendSlice { + if typeCheck && src.Type() != dst.Type() { + err = fmt.Errorf("cannot append two slice with different type (%s, %s)", src.Type(), dst.Type()) + return + } + newSlice = reflect.AppendSlice(dst, src) + } + if dst.CanSet() { + dst.Set(newSlice) + } else { + dst = newSlice + } + case reflect.Ptr, reflect.Interface: + if isReflectNil(src) { + break + } + + if dst.Kind() != reflect.Ptr && src.Type().AssignableTo(dst.Type()) { + if dst.IsNil() || overwrite { + if overwrite || isEmptyValue(dst) { + if dst.CanSet() { + dst.Set(src) + } else { + dst = src + } + } + } + break + } + + if src.Kind() != reflect.Interface { + if dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) { + if dst.CanSet() && (overwrite || isEmptyValue(dst)) { + dst.Set(src) + } + } else if src.Kind() == reflect.Ptr { + if dst, err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { + return + } + dst = dst.Addr() + } else if dst.Elem().Type() == src.Type() { + if dst, err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil { + return + } + } else { + return dst, ErrDifferentArgumentsTypes + } + break + } + if dst.IsNil() || overwrite { + if (overwrite || isEmptyValue(dst)) && (overwriteWithEmptySrc || !isEmptyValue(src)) { + if dst.CanSet() { + dst.Set(src) + } else { + dst = src + } + } + } else if _, err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { + return + } + default: + overwriteFull := (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) + if overwriteFull { + if dst.CanSet() { + dst.Set(src) + } else { + dst = src + } + } + } + + return +} + +// Merge will fill any empty for value type attributes on the dst struct using corresponding +// src attributes if they themselves are not empty. dst and src must be valid same-type structs +// and dst must be a pointer to struct. +// It won't merge unexported (private) fields and will do recursively any exported field. +func Merge(dst, src interface{}, opts ...func(*Config)) error { + return merge(dst, src, opts...) +} + +// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overridden by +// non-empty src attribute values. +// Deprecated: use Merge(…) with WithOverride +func MergeWithOverwrite(dst, src interface{}, opts ...func(*Config)) error { + return merge(dst, src, append(opts, WithOverride)...) +} + +// WithTransformers adds transformers to merge, allowing to customize the merging of some types. +func WithTransformers(transformers Transformers) func(*Config) { + return func(config *Config) { + config.Transformers = transformers + } +} + +// WithOverride will make merge override non-empty dst attributes with non-empty src attributes values. +func WithOverride(config *Config) { + config.Overwrite = true +} + +// WithOverwriteWithEmptyValue will make merge override non empty dst attributes with empty src attributes values. +func WithOverwriteWithEmptyValue(config *Config) { + config.overwriteWithEmptyValue = true +} + +// WithOverrideEmptySlice will make merge override empty dst slice with empty src slice. +func WithOverrideEmptySlice(config *Config) { + config.overwriteSliceWithEmptyValue = true +} + +// WithAppendSlice will make merge append slices instead of overwriting it. +func WithAppendSlice(config *Config) { + config.AppendSlice = true +} + +// WithTypeCheck will make merge check types while overwriting it (must be used with WithOverride). +func WithTypeCheck(config *Config) { + config.TypeCheck = true +} + +func merge(dst, src interface{}, opts ...func(*Config)) error { + var ( + vDst, vSrc reflect.Value + err error + ) + + config := &Config{} + + for _, opt := range opts { + opt(config) + } + + if vDst, vSrc, err = resolveValues(dst, src); err != nil { + return err + } + if !vDst.CanSet() { + return fmt.Errorf("cannot set dst, needs reference") + } + if vDst.Type() != vSrc.Type() { + return ErrDifferentArgumentsTypes + } + _, err = deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config) + return err +} + +// IsReflectNil is the reflect value provided nil +func isReflectNil(v reflect.Value) bool { + k := v.Kind() + switch k { + case reflect.Interface, reflect.Slice, reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr: + // Both interface and slice are nil if first word is 0. + // Both are always bigger than a word; assume flagIndir. + return v.IsNil() + default: + return false + } +} diff --git a/vendor/github.com/imdario/mergo/mergo.go b/vendor/github.com/imdario/mergo/mergo.go new file mode 100644 index 000000000..a82fea2fd --- /dev/null +++ b/vendor/github.com/imdario/mergo/mergo.go @@ -0,0 +1,97 @@ +// Copyright 2013 Dario Castañé. All rights reserved. +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Based on src/pkg/reflect/deepequal.go from official +// golang's stdlib. + +package mergo + +import ( + "errors" + "reflect" +) + +// Errors reported by Mergo when it finds invalid arguments. +var ( + ErrNilArguments = errors.New("src and dst must not be nil") + ErrDifferentArgumentsTypes = errors.New("src and dst must be of same type") + ErrNotSupported = errors.New("only structs and maps are supported") + ErrExpectedMapAsDestination = errors.New("dst was expected to be a map") + ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct") +) + +// During deepMerge, must keep track of checks that are +// in progress. The comparison algorithm assumes that all +// checks in progress are true when it reencounters them. +// Visited are stored in a map indexed by 17 * a1 + a2; +type visit struct { + ptr uintptr + typ reflect.Type + next *visit +} + +// From src/pkg/encoding/json/encode.go. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + if v.IsNil() { + return true + } + return isEmptyValue(v.Elem()) + case reflect.Func: + return v.IsNil() + case reflect.Invalid: + return true + } + return false +} + +func resolveValues(dst, src interface{}) (vDst, vSrc reflect.Value, err error) { + if dst == nil || src == nil { + err = ErrNilArguments + return + } + vDst = reflect.ValueOf(dst).Elem() + if vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map { + err = ErrNotSupported + return + } + vSrc = reflect.ValueOf(src) + // We check if vSrc is a pointer to dereference it. + if vSrc.Kind() == reflect.Ptr { + vSrc = vSrc.Elem() + } + return +} + +// Traverses recursively both values, assigning src's fields values to dst. +// The map argument tracks comparisons that have already been seen, which allows +// short circuiting on recursive types. +func deeper(dst, src reflect.Value, visited map[uintptr]*visit, depth int) (err error) { + if dst.CanAddr() { + addr := dst.UnsafeAddr() + h := 17 * addr + seen := visited[h] + typ := dst.Type() + for p := seen; p != nil; p = p.next { + if p.ptr == addr && p.typ == typ { + return nil + } + } + // Remember, remember... + visited[h] = &visit{addr, typ, seen} + } + return // TODO refactor +} diff --git a/vendor/github.com/go-git/go-git/v5/.gitignore b/vendor/github.com/jesseduffield/go-git/v5/.gitignore similarity index 100% rename from vendor/github.com/go-git/go-git/v5/.gitignore rename to vendor/github.com/jesseduffield/go-git/v5/.gitignore diff --git a/vendor/github.com/go-git/go-git/v5/CODE_OF_CONDUCT.md b/vendor/github.com/jesseduffield/go-git/v5/CODE_OF_CONDUCT.md similarity index 100% rename from vendor/github.com/go-git/go-git/v5/CODE_OF_CONDUCT.md rename to vendor/github.com/jesseduffield/go-git/v5/CODE_OF_CONDUCT.md diff --git a/vendor/github.com/go-git/go-git/v5/COMPATIBILITY.md b/vendor/github.com/jesseduffield/go-git/v5/COMPATIBILITY.md similarity index 97% rename from vendor/github.com/go-git/go-git/v5/COMPATIBILITY.md rename to vendor/github.com/jesseduffield/go-git/v5/COMPATIBILITY.md index 395088b7b..2a72b501e 100644 --- a/vendor/github.com/go-git/go-git/v5/COMPATIBILITY.md +++ b/vendor/github.com/jesseduffield/go-git/v5/COMPATIBILITY.md @@ -101,7 +101,7 @@ is supported by go-git. | http(s):// (smart) | ✔ | | git:// | ✔ | | ssh:// | ✔ | -| file:// | ✔ | +| file:// | partial | Warning: this is not pure Golang. This shells out to the `git` binary. | | custom | ✔ | | **other features** | | gitignore | ✔ | diff --git a/vendor/github.com/go-git/go-git/v5/CONTRIBUTING.md b/vendor/github.com/jesseduffield/go-git/v5/CONTRIBUTING.md similarity index 100% rename from vendor/github.com/go-git/go-git/v5/CONTRIBUTING.md rename to vendor/github.com/jesseduffield/go-git/v5/CONTRIBUTING.md diff --git a/vendor/github.com/go-git/go-git/v5/LICENSE b/vendor/github.com/jesseduffield/go-git/v5/LICENSE similarity index 100% rename from vendor/github.com/go-git/go-git/v5/LICENSE rename to vendor/github.com/jesseduffield/go-git/v5/LICENSE diff --git a/vendor/github.com/go-git/go-git/v5/Makefile b/vendor/github.com/jesseduffield/go-git/v5/Makefile similarity index 100% rename from vendor/github.com/go-git/go-git/v5/Makefile rename to vendor/github.com/jesseduffield/go-git/v5/Makefile diff --git a/vendor/github.com/go-git/go-git/v5/README.md b/vendor/github.com/jesseduffield/go-git/v5/README.md similarity index 84% rename from vendor/github.com/go-git/go-git/v5/README.md rename to vendor/github.com/jesseduffield/go-git/v5/README.md index bca3277a0..020400bf4 100644 --- a/vendor/github.com/go-git/go-git/v5/README.md +++ b/vendor/github.com/jesseduffield/go-git/v5/README.md @@ -1,9 +1,9 @@ ![go-git logo](https://cdn.rawgit.com/src-d/artwork/02036484/go-git/files/go-git-github-readme-header.png) -[![GoDoc](https://godoc.org/github.com/go-git/go-git/v5?status.svg)](https://godoc.org/github.com/src-d/go-git) [![Build Status](https://github.com/go-git/go-git/workflows/Test%20&%20Coverage/badge.svg)](https://github.com/go-git/go-git/actions) [![Go Report Card](https://goreportcard.com/badge/github.com/src-d/go-git)](https://goreportcard.com/report/github.com/src-d/go-git) +[![GoDoc](https://godoc.org/github.com/jesseduffield/go-git/v5?status.svg)](https://pkg.go.dev/github.com/jesseduffield/go-git/v5) [![Build Status](https://github.com/go-git/go-git/workflows/Test/badge.svg)](https://github.com/go-git/go-git/actions) [![Go Report Card](https://goreportcard.com/badge/github.com/go-git/go-git)](https://goreportcard.com/report/github.com/go-git/go-git) *go-git* is a highly extensible git implementation library written in **pure Go**. -It can be used to manipulate git repositories at low level *(plumbing)* or high level *(porcelain)*, through an idiomatic Go API. It also supports several types of storage, such as in-memory filesystems, or custom implementations, thanks to the [`Storer`](https://godoc.org/github.com/go-git/go-git/v5/plumbing/storer) interface. +It can be used to manipulate git repositories at low level *(plumbing)* or high level *(porcelain)*, through an idiomatic Go API. It also supports several types of storage, such as in-memory filesystems, or custom implementations, thanks to the [`Storer`](https://pkg.go.dev/github.com/jesseduffield/go-git/v5/plumbing/storer) interface. It's being actively developed since 2015 and is being used extensively by [Keybase](https://keybase.io/blog/encrypted-git-for-everyone), [Gitea](https://gitea.io/en-us/) or [Pulumi](https://github.com/search?q=org%3Apulumi+go-git&type=Code), and by many other libraries and tools. @@ -12,7 +12,7 @@ Project Status After the legal issues with the [`src-d`](https://github.com/src-d) organization, the lack of update for four months and the requirement to make a hard fork, the project is **now back to normality**. -The project is currently actively maintained by individual contributors, including several of the original authors, but also backed by a new company `gitsigth` where `go-git` is a critical component used at scale. +The project is currently actively maintained by individual contributors, including several of the original authors, but also backed by a new company, [gitsight](https://github.com/gitsight), where `go-git` is a critical component used at scale. Comparison with git @@ -29,7 +29,7 @@ Installation The recommended way to install *go-git* is: ```go -import "github.com/go-git/go-git/v5" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/jesseduffield/go-git/v5" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/go-git/go-git" // with go modules disabled ``` @@ -37,7 +37,7 @@ import "github.com/go-git/go-git" // with go modules disabled Examples -------- -> Please note that the `CheckIfError` and `Info` functions used in the examples are from the [examples package](https://github.com/src-d/go-git/blob/master/_examples/common.go#L17) just to be used in the examples. +> Please note that the `CheckIfError` and `Info` functions used in the examples are from the [examples package](https://github.com/go-git/go-git/blob/master/_examples/common.go#L19) just to be used in the examples. ### Basic example diff --git a/vendor/github.com/go-git/go-git/v5/blame.go b/vendor/github.com/jesseduffield/go-git/v5/blame.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/blame.go rename to vendor/github.com/jesseduffield/go-git/v5/blame.go index 43634b32c..47fd59700 100644 --- a/vendor/github.com/go-git/go-git/v5/blame.go +++ b/vendor/github.com/jesseduffield/go-git/v5/blame.go @@ -9,9 +9,9 @@ import ( "time" "unicode/utf8" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/utils/diff" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/utils/diff" ) // BlameResult represents the result of a Blame operation. diff --git a/vendor/github.com/go-git/go-git/v5/common.go b/vendor/github.com/jesseduffield/go-git/v5/common.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/common.go rename to vendor/github.com/jesseduffield/go-git/v5/common.go diff --git a/vendor/github.com/go-git/go-git/v5/config/branch.go b/vendor/github.com/jesseduffield/go-git/v5/config/branch.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/config/branch.go rename to vendor/github.com/jesseduffield/go-git/v5/config/branch.go index fe86cf542..69e0a9889 100644 --- a/vendor/github.com/go-git/go-git/v5/config/branch.go +++ b/vendor/github.com/jesseduffield/go-git/v5/config/branch.go @@ -3,8 +3,8 @@ package config import ( "errors" - "github.com/go-git/go-git/v5/plumbing" - format "github.com/go-git/go-git/v5/plumbing/format/config" + "github.com/jesseduffield/go-git/v5/plumbing" + format "github.com/jesseduffield/go-git/v5/plumbing/format/config" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/config/config.go b/vendor/github.com/jesseduffield/go-git/v5/config/config.go similarity index 72% rename from vendor/github.com/go-git/go-git/v5/config/config.go rename to vendor/github.com/jesseduffield/go-git/v5/config/config.go index bec35b0c2..da891c181 100644 --- a/vendor/github.com/go-git/go-git/v5/config/config.go +++ b/vendor/github.com/jesseduffield/go-git/v5/config/config.go @@ -5,11 +5,16 @@ import ( "bytes" "errors" "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" "sort" "strconv" - "github.com/go-git/go-git/v5/internal/url" - format "github.com/go-git/go-git/v5/plumbing/format/config" + "github.com/jesseduffield/go-git/v5/internal/url" + format "github.com/jesseduffield/go-git/v5/plumbing/format/config" + "github.com/mitchellh/go-homedir" ) const ( @@ -32,6 +37,16 @@ var ( ErrRemoteConfigEmptyName = errors.New("remote config: empty name") ) +// Scope defines the scope of a config file, such as local, global or system. +type Scope int + +// Available ConfigScope's +const ( + LocalScope Scope = iota + GlobalScope + SystemScope +) + // Config contains the repository configuration // https://www.kernel.org/pub/software/scm/git/docs/git-config.html#FILES type Config struct { @@ -46,6 +61,27 @@ type Config struct { CommentChar string } + User struct { + // Name is the personal name of the author and the commiter of a commit. + Name string + // Email is the email of the author and the commiter of a commit. + Email string + } + + Author struct { + // Name is the personal name of the author of a commit. + Name string + // Email is the email of the author of a commit. + Email string + } + + Committer struct { + // Name is the personal name of the commiter of a commit. + Name string + // Email is the email of the the commiter of a commit. + Email string + } + Pack struct { // Window controls the size of the sliding window for delta // compression. The default is 10. A value of 0 turns off @@ -82,6 +118,77 @@ func NewConfig() *Config { return config } +// ReadConfig reads a config file from a io.Reader. +func ReadConfig(r io.Reader) (*Config, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + cfg := NewConfig() + if err = cfg.Unmarshal(b); err != nil { + return nil, err + } + + return cfg, nil +} + +// LoadConfig loads a config file from a given scope. The returned Config, +// contains exclusively information fom the given scope. If couldn't find a +// config file to the given scope, a empty one is returned. +func LoadConfig(scope Scope) (*Config, error) { + if scope == LocalScope { + return nil, fmt.Errorf("LocalScope should be read from the a ConfigStorer.") + } + + files, err := Paths(scope) + if err != nil { + return nil, err + } + + for _, file := range files { + f, err := os.Open(file) + if err != nil { + if os.IsNotExist(err) { + continue + } + + return nil, err + } + + defer f.Close() + return ReadConfig(f) + } + + return NewConfig(), nil +} + +// Paths returns the config file location for a given scope. +func Paths(scope Scope) ([]string, error) { + var files []string + switch scope { + case GlobalScope: + xdg := os.Getenv("XDG_CONFIG_HOME") + if xdg != "" { + files = append(files, filepath.Join(xdg, "git/config")) + } + + home, err := homedir.Dir() + if err != nil { + return nil, err + } + + files = append(files, + filepath.Join(home, ".gitconfig"), + filepath.Join(home, ".config/git/config"), + ) + case SystemScope: + files = append(files, "/etc/gitconfig") + } + + return files, nil +} + // Validate validates the fields and sets the default values. func (c *Config) Validate() error { for name, r := range c.Remotes { @@ -113,6 +220,9 @@ const ( branchSection = "branch" coreSection = "core" packSection = "pack" + userSection = "user" + authorSection = "author" + committerSection = "committer" fetchKey = "fetch" urlKey = "url" bareKey = "bare" @@ -121,6 +231,8 @@ const ( windowKey = "window" mergeKey = "merge" rebaseKey = "rebase" + nameKey = "name" + emailKey = "email" // DefaultPackWindow holds the number of previous objects used to // generate deltas. The value 10 is the same used by git command. @@ -138,14 +250,15 @@ func (c *Config) Unmarshal(b []byte) error { } c.unmarshalCore() + c.unmarshalUser() if err := c.unmarshalPack(); err != nil { return err } unmarshalSubmodules(c.Raw, c.Submodules) - if err := c.unmarshalBranches(); err != nil { - return err - } + // ignore error + // Why ignore the error? It seems overly strict and for my use case none of the errors matter to me + c.unmarshalBranches() return c.unmarshalRemotes() } @@ -160,6 +273,20 @@ func (c *Config) unmarshalCore() { c.Core.CommentChar = s.Options.Get(commentCharKey) } +func (c *Config) unmarshalUser() { + s := c.Raw.Section(userSection) + c.User.Name = s.Options.Get(nameKey) + c.User.Email = s.Options.Get(emailKey) + + s = c.Raw.Section(authorSection) + c.Author.Name = s.Options.Get(nameKey) + c.Author.Email = s.Options.Get(emailKey) + + s = c.Raw.Section(committerSection) + c.Committer.Name = s.Options.Get(nameKey) + c.Committer.Email = s.Options.Get(emailKey) +} + func (c *Config) unmarshalPack() error { s := c.Raw.Section(packSection) window := s.Options.Get(windowKey) @@ -209,7 +336,7 @@ func (c *Config) unmarshalBranches() error { b := &Branch{} if err := b.unmarshal(sub); err != nil { - return err + // ignore error } c.Branches[b.Name] = b @@ -220,6 +347,7 @@ func (c *Config) unmarshalBranches() error { // Marshal returns Config encoded as a git-config file. func (c *Config) Marshal() ([]byte, error) { c.marshalCore() + c.marshalUser() c.marshalPack() c.marshalRemotes() c.marshalSubmodules() @@ -242,6 +370,35 @@ func (c *Config) marshalCore() { } } +func (c *Config) marshalUser() { + s := c.Raw.Section(userSection) + if c.User.Name != "" { + s.SetOption(nameKey, c.User.Name) + } + + if c.User.Email != "" { + s.SetOption(emailKey, c.User.Email) + } + + s = c.Raw.Section(authorSection) + if c.Author.Name != "" { + s.SetOption(nameKey, c.Author.Name) + } + + if c.Author.Email != "" { + s.SetOption(emailKey, c.Author.Email) + } + + s = c.Raw.Section(committerSection) + if c.Committer.Name != "" { + s.SetOption(nameKey, c.Committer.Name) + } + + if c.Committer.Email != "" { + s.SetOption(emailKey, c.Committer.Email) + } +} + func (c *Config) marshalPack() { s := c.Raw.Section(packSection) if c.Pack.Window != DefaultPackWindow { diff --git a/vendor/github.com/go-git/go-git/v5/config/modules.go b/vendor/github.com/jesseduffield/go-git/v5/config/modules.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/config/modules.go rename to vendor/github.com/jesseduffield/go-git/v5/config/modules.go index 1c10aa354..898e2d9ec 100644 --- a/vendor/github.com/go-git/go-git/v5/config/modules.go +++ b/vendor/github.com/jesseduffield/go-git/v5/config/modules.go @@ -5,7 +5,7 @@ import ( "errors" "regexp" - format "github.com/go-git/go-git/v5/plumbing/format/config" + format "github.com/jesseduffield/go-git/v5/plumbing/format/config" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/config/refspec.go b/vendor/github.com/jesseduffield/go-git/v5/config/refspec.go similarity index 93% rename from vendor/github.com/go-git/go-git/v5/config/refspec.go rename to vendor/github.com/jesseduffield/go-git/v5/config/refspec.go index 87cf2a601..3b0cb77e6 100644 --- a/vendor/github.com/go-git/go-git/v5/config/refspec.go +++ b/vendor/github.com/jesseduffield/go-git/v5/config/refspec.go @@ -4,7 +4,7 @@ import ( "errors" "strings" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) const ( @@ -25,7 +25,7 @@ var ( // reference even if it isn’t a fast-forward. // eg.: "+refs/heads/*:refs/remotes/origin/*" // -// https://git-scm.com/book/es/v2/Git-Internals-The-Refspec +// https://git-scm.com/book/en/v2/Git-Internals-The-Refspec type RefSpec string // Validate validates the RefSpec @@ -59,6 +59,11 @@ func (s RefSpec) IsDelete() bool { return s[0] == refSpecSeparator[0] } +// IsExactSHA1 returns true if the source is a SHA1 hash. +func (s RefSpec) IsExactSHA1() bool { + return plumbing.IsHash(s.Src()) +} + // Src return the src side. func (s RefSpec) Src() string { spec := string(s) @@ -69,8 +74,8 @@ func (s RefSpec) Src() string { } else { start = 0 } - end := strings.Index(spec, refSpecSeparator) + end := strings.Index(spec, refSpecSeparator) return spec[start:end] } diff --git a/vendor/github.com/go-git/go-git/v5/doc.go b/vendor/github.com/jesseduffield/go-git/v5/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/go.mod b/vendor/github.com/jesseduffield/go-git/v5/go.mod similarity index 86% rename from vendor/github.com/go-git/go-git/v5/go.mod rename to vendor/github.com/jesseduffield/go-git/v5/go.mod index 6d8da35c3..c6a9be01f 100644 --- a/vendor/github.com/go-git/go-git/v5/go.mod +++ b/vendor/github.com/jesseduffield/go-git/v5/go.mod @@ -1,4 +1,4 @@ -module github.com/go-git/go-git/v5 +module github.com/jesseduffield/go-git/v5 require ( github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect @@ -8,8 +8,9 @@ require ( github.com/gliderlabs/ssh v0.2.2 github.com/go-git/gcfg v1.5.0 github.com/go-git/go-billy/v5 v5.0.0 - github.com/go-git/go-git-fixtures/v4 v4.0.1 + github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 github.com/google/go-cmp v0.3.0 + github.com/imdario/mergo v0.3.9 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 github.com/jessevdk/go-flags v1.4.0 github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd diff --git a/vendor/github.com/go-git/go-git/v5/go.sum b/vendor/github.com/jesseduffield/go-git/v5/go.sum similarity index 94% rename from vendor/github.com/go-git/go-git/v5/go.sum rename to vendor/github.com/jesseduffield/go-git/v5/go.sum index a73585e90..9af1b0611 100644 --- a/vendor/github.com/go-git/go-git/v5/go.sum +++ b/vendor/github.com/jesseduffield/go-git/v5/go.sum @@ -20,8 +20,12 @@ github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agR github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc= github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= diff --git a/vendor/github.com/go-git/go-git/v5/internal/revision/parser.go b/vendor/github.com/jesseduffield/go-git/v5/internal/revision/parser.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/internal/revision/parser.go rename to vendor/github.com/jesseduffield/go-git/v5/internal/revision/parser.go index 61de386b2..8facf17ff 100644 --- a/vendor/github.com/go-git/go-git/v5/internal/revision/parser.go +++ b/vendor/github.com/jesseduffield/go-git/v5/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, 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/vendor/github.com/go-git/go-git/v5/internal/revision/scanner.go b/vendor/github.com/jesseduffield/go-git/v5/internal/revision/scanner.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/internal/revision/scanner.go rename to vendor/github.com/jesseduffield/go-git/v5/internal/revision/scanner.go diff --git a/vendor/github.com/go-git/go-git/v5/internal/revision/token.go b/vendor/github.com/jesseduffield/go-git/v5/internal/revision/token.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/internal/revision/token.go rename to vendor/github.com/jesseduffield/go-git/v5/internal/revision/token.go diff --git a/vendor/github.com/go-git/go-git/v5/internal/url/url.go b/vendor/github.com/jesseduffield/go-git/v5/internal/url/url.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/internal/url/url.go rename to vendor/github.com/jesseduffield/go-git/v5/internal/url/url.go diff --git a/vendor/github.com/go-git/go-git/v5/object_walker.go b/vendor/github.com/jesseduffield/go-git/v5/object_walker.go similarity index 92% rename from vendor/github.com/go-git/go-git/v5/object_walker.go rename to vendor/github.com/jesseduffield/go-git/v5/object_walker.go index 3fcdd2999..c9d84b058 100644 --- a/vendor/github.com/go-git/go-git/v5/object_walker.go +++ b/vendor/github.com/jesseduffield/go-git/v5/object_walker.go @@ -3,10 +3,10 @@ package git import ( "fmt" - "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/object" - "github.com/go-git/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/storage" ) type objectWalker struct { diff --git a/vendor/github.com/go-git/go-git/v5/options.go b/vendor/github.com/jesseduffield/go-git/v5/options.go similarity index 82% rename from vendor/github.com/go-git/go-git/v5/options.go rename to vendor/github.com/jesseduffield/go-git/v5/options.go index a147f58b9..8423d14b6 100644 --- a/vendor/github.com/go-git/go-git/v5/options.go +++ b/vendor/github.com/jesseduffield/go-git/v5/options.go @@ -2,16 +2,17 @@ package git import ( "errors" + "fmt" "regexp" "strings" "time" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband" + "github.com/jesseduffield/go-git/v5/plumbing/transport" "golang.org/x/crypto/openpgp" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband" - "github.com/go-git/go-git/v5/plumbing/transport" ) // SubmoduleRescursivity defines how depth will affect any submodule recursive @@ -190,6 +191,9 @@ type PushOptions struct { // Prune specify that remote refs that match given RefSpecs and that do // not exist locally will be removed. Prune bool + // Force allows the push to update a remote branch even when the local + // branch does not descend from it. + Force bool } // Validate validates the fields and sets the default values. @@ -370,12 +374,37 @@ var ( ErrMissingAuthor = errors.New("author field is required") ) +// AddOptions describes how a add operation should be performed +type AddOptions struct { + // All equivalent to `git add -A`, update the index not only where the + // working tree has a file matching `Path` but also where the index already + // has an entry. This adds, modifies, and removes index entries to match the + // working tree. If no `Path` nor `Glob` is given when `All` option is + // used, all files in the entire working tree are updated. + All bool + // Path is the exact filepath to a the file or directory to be added. + Path string + // Glob adds all paths, matching pattern, to the index. If pattern matches a + // directory path, all directory contents are added to the index recursively. + Glob string +} + +// Validate validates the fields and sets the default values. +func (o *AddOptions) Validate(r *Repository) error { + if o.Path != "" && o.Glob != "" { + return fmt.Errorf("fields Path and Glob are mutual exclusive") + } + + return nil +} + // CommitOptions describes how a commit operation should be performed. type CommitOptions struct { // All automatically stage files that have been modified and deleted, but // new files you have not told Git about are not affected. All bool - // Author is the author's signature of the commit. + // Author is the author's signature of the commit. If Author is empty the + // Name and Email is read from the config, and time.Now it's used as When. Author *object.Signature // Committer is the committer's signature of the commit. If Committer is // nil the Author signature is used. @@ -392,7 +421,9 @@ type CommitOptions struct { // Validate validates the fields and sets the default values. func (o *CommitOptions) Validate(r *Repository) error { if o.Author == nil { - return ErrMissingAuthor + if err := o.loadConfigAuthorAndCommitter(r); err != nil { + return err + } } if o.Committer == nil { @@ -413,6 +444,43 @@ func (o *CommitOptions) Validate(r *Repository) error { return nil } +func (o *CommitOptions) loadConfigAuthorAndCommitter(r *Repository) error { + cfg, err := r.ConfigScoped(config.SystemScope) + if err != nil { + return err + } + + if o.Author == nil && cfg.Author.Email != "" && cfg.Author.Name != "" { + o.Author = &object.Signature{ + Name: cfg.Author.Name, + Email: cfg.Author.Email, + When: time.Now(), + } + } + + if o.Committer == nil && cfg.Committer.Email != "" && cfg.Committer.Name != "" { + o.Committer = &object.Signature{ + Name: cfg.Committer.Name, + Email: cfg.Committer.Email, + When: time.Now(), + } + } + + if o.Author == nil && cfg.User.Email != "" && cfg.User.Name != "" { + o.Author = &object.Signature{ + Name: cfg.User.Name, + Email: cfg.User.Email, + When: time.Now(), + } + } + + if o.Author == nil { + return ErrMissingAuthor + } + + return nil +} + var ( ErrMissingName = errors.New("name field is required") ErrMissingTagger = errors.New("tagger field is required") @@ -421,7 +489,8 @@ var ( // CreateTagOptions describes how a tag object should be created. type CreateTagOptions struct { - // Tagger defines the signature of the tag creator. + // Tagger defines the signature of the tag creator. If Tagger is empty the + // Name and Email is read from the config, and time.Now it's used as When. Tagger *object.Signature // Message defines the annotation of the tag. It is canonicalized during // validation into the format expected by git - no leading whitespace and @@ -435,7 +504,9 @@ type CreateTagOptions struct { // Validate validates the fields and sets the default values. func (o *CreateTagOptions) Validate(r *Repository, hash plumbing.Hash) error { if o.Tagger == nil { - return ErrMissingTagger + if err := o.loadConfigTagger(r); err != nil { + return err + } } if o.Message == "" { @@ -448,6 +519,35 @@ func (o *CreateTagOptions) Validate(r *Repository, hash plumbing.Hash) error { return nil } +func (o *CreateTagOptions) loadConfigTagger(r *Repository) error { + cfg, err := r.ConfigScoped(config.SystemScope) + if err != nil { + return err + } + + if o.Tagger == nil && cfg.Author.Email != "" && cfg.Author.Name != "" { + o.Tagger = &object.Signature{ + Name: cfg.Author.Name, + Email: cfg.Author.Email, + When: time.Now(), + } + } + + if o.Tagger == nil && cfg.User.Email != "" && cfg.User.Name != "" { + o.Tagger = &object.Signature{ + Name: cfg.User.Name, + Email: cfg.User.Email, + When: time.Now(), + } + } + + if o.Tagger == nil { + return ErrMissingTagger + } + + return nil +} + // ListOptions describes how a remote list should be performed. type ListOptions struct { // Auth credentials, if required, to use with the remote repository. @@ -502,6 +602,9 @@ type PlainOpenOptions struct { // DetectDotGit defines whether parent directories should be // walked until a .git directory or file is found. DetectDotGit bool + // Enable .git/commondir support (see https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt). + // NOTE: This option will only work with the filesystem storage. + EnableDotGitCommonDir bool } // Validate validates the fields and sets the default values. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/cache/buffer_lru.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/buffer_lru.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/cache/buffer_lru.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/buffer_lru.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/cache/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/common.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/cache/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/common.go index 7b0d0c76b..7856df3d3 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/cache/common.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/common.go @@ -1,6 +1,6 @@ package cache -import "github.com/go-git/go-git/v5/plumbing" +import "github.com/jesseduffield/go-git/v5/plumbing" const ( Byte FileSize = 1 << (iota * 10) diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/cache/object_lru.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/object_lru.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/cache/object_lru.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/object_lru.go index c50d0d1e6..75b2b72b0 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/cache/object_lru.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/cache/object_lru.go @@ -4,7 +4,7 @@ import ( "container/list" "sync" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) // ObjectLRU implements an object cache with an LRU eviction policy and a diff --git a/vendor/github.com/jesseduffield/go-git/v5/plumbing/color/color.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/color/color.go new file mode 100644 index 000000000..2cd74bdc1 --- /dev/null +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/color/color.go @@ -0,0 +1,38 @@ +package color + +// TODO read colors from a github.com/go-git/go-git/plumbing/format/config.Config struct +// TODO implement color parsing, see https://github.com/git/git/blob/v2.26.2/color.c + +// Colors. See https://github.com/git/git/blob/v2.26.2/color.h#L24-L53. +const ( + Normal = "" + Reset = "\033[m" + Bold = "\033[1m" + Red = "\033[31m" + Green = "\033[32m" + Yellow = "\033[33m" + Blue = "\033[34m" + Magenta = "\033[35m" + Cyan = "\033[36m" + BoldRed = "\033[1;31m" + BoldGreen = "\033[1;32m" + BoldYellow = "\033[1;33m" + BoldBlue = "\033[1;34m" + BoldMagenta = "\033[1;35m" + BoldCyan = "\033[1;36m" + FaintRed = "\033[2;31m" + FaintGreen = "\033[2;32m" + FaintYellow = "\033[2;33m" + FaintBlue = "\033[2;34m" + FaintMagenta = "\033[2;35m" + FaintCyan = "\033[2;36m" + BgRed = "\033[41m" + BgGreen = "\033[42m" + BgYellow = "\033[43m" + BgBlue = "\033[44m" + BgMagenta = "\033[45m" + BgCyan = "\033[46m" + Faint = "\033[2m" + FaintItalic = "\033[2;3m" + Reverse = "\033[7m" +) diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/error.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/error.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/error.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/error.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/filemode/filemode.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/filemode/filemode.go similarity index 99% rename from vendor/github.com/go-git/go-git/v5/plumbing/filemode/filemode.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/filemode/filemode.go index 594984f9e..b848a9796 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/filemode/filemode.go +++ b/vendor/github.com/jesseduffield/go-git/v5/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/vendor/github.com/go-git/go-git/v5/plumbing/format/config/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/common.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/config/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/common.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/decoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/decoder.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/config/decoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/decoder.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/config/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/encoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/encoder.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/config/encoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/encoder.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/option.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/option.go index d4775e4f0..218f992fd 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go +++ b/vendor/github.com/jesseduffield/go-git/v5/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/vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/section.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/config/section.go index 4a17e3b21..f743da6af 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go +++ b/vendor/github.com/jesseduffield/go-git/v5/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) } // Option return the value for the specified key. Empty string is returned if diff --git a/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/colorconfig.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/colorconfig.go new file mode 100644 index 000000000..212401be7 --- /dev/null +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/colorconfig.go @@ -0,0 +1,97 @@ +package diff + +import "github.com/jesseduffield/go-git/v5/plumbing/color" + +// A ColorKey is a key into a ColorConfig map and also equal to the key in the +// diff.color subsection of the config. See +// https://github.com/git/git/blob/v2.26.2/diff.c#L83-L106. +type ColorKey string + +// ColorKeys. +const ( + Context ColorKey = "context" + Meta ColorKey = "meta" + Frag ColorKey = "frag" + Old ColorKey = "old" + New ColorKey = "new" + Commit ColorKey = "commit" + Whitespace ColorKey = "whitespace" + Func ColorKey = "func" + OldMoved ColorKey = "oldMoved" + OldMovedAlternative ColorKey = "oldMovedAlternative" + OldMovedDimmed ColorKey = "oldMovedDimmed" + OldMovedAlternativeDimmed ColorKey = "oldMovedAlternativeDimmed" + NewMoved ColorKey = "newMoved" + NewMovedAlternative ColorKey = "newMovedAlternative" + NewMovedDimmed ColorKey = "newMovedDimmed" + NewMovedAlternativeDimmed ColorKey = "newMovedAlternativeDimmed" + ContextDimmed ColorKey = "contextDimmed" + OldDimmed ColorKey = "oldDimmed" + NewDimmed ColorKey = "newDimmed" + ContextBold ColorKey = "contextBold" + OldBold ColorKey = "oldBold" + NewBold ColorKey = "newBold" +) + +// A ColorConfig is a color configuration. A nil or empty ColorConfig +// corresponds to no color. +type ColorConfig map[ColorKey]string + +// A ColorConfigOption sets an option on a ColorConfig. +type ColorConfigOption func(ColorConfig) + +// WithColor sets the color for key. +func WithColor(key ColorKey, color string) ColorConfigOption { + return func(cc ColorConfig) { + cc[key] = color + } +} + +// defaultColorConfig is the default color configuration. See +// https://github.com/git/git/blob/v2.26.2/diff.c#L57-L81. +var defaultColorConfig = ColorConfig{ + Context: color.Normal, + Meta: color.Bold, + Frag: color.Cyan, + Old: color.Red, + New: color.Green, + Commit: color.Yellow, + Whitespace: color.BgRed, + Func: color.Normal, + OldMoved: color.BoldMagenta, + OldMovedAlternative: color.BoldBlue, + OldMovedDimmed: color.Faint, + OldMovedAlternativeDimmed: color.FaintItalic, + NewMoved: color.BoldCyan, + NewMovedAlternative: color.BoldYellow, + NewMovedDimmed: color.Faint, + NewMovedAlternativeDimmed: color.FaintItalic, + ContextDimmed: color.Faint, + OldDimmed: color.FaintRed, + NewDimmed: color.FaintGreen, + ContextBold: color.Bold, + OldBold: color.BoldRed, + NewBold: color.BoldGreen, +} + +// NewColorConfig returns a new ColorConfig. +func NewColorConfig(options ...ColorConfigOption) ColorConfig { + cc := make(ColorConfig) + for key, value := range defaultColorConfig { + cc[key] = value + } + for _, option := range options { + option(cc) + } + return cc +} + +// Reset returns the ANSI escape sequence to reset the color with key set from +// cc. If no color was set then no reset is needed so it returns the empty +// string. +func (cc ColorConfig) Reset(key ColorKey) string { + if cc[key] == "" { + return "" + } + return color.Reset +} diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/patch.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/patch.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/diff/patch.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/patch.go index 39a66a1a8..7d6601feb 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/patch.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/patch.go @@ -1,8 +1,8 @@ package diff import ( - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" ) // Operation defines the operation of a diff item. diff --git a/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/unified_encoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/unified_encoder.go new file mode 100644 index 000000000..2c0fdf919 --- /dev/null +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/diff/unified_encoder.go @@ -0,0 +1,376 @@ +package diff + +import ( + "fmt" + "io" + "regexp" + "strconv" + "strings" + + "github.com/jesseduffield/go-git/v5/plumbing" +) + +// DefaultContextLines is the default number of context lines. +const DefaultContextLines = 3 + +var ( + splitLinesRegexp = regexp.MustCompile(`[^\n]*(\n|$)`) + + operationChar = map[Operation]byte{ + Add: '+', + Delete: '-', + Equal: ' ', + } + + operationColorKey = map[Operation]ColorKey{ + Add: New, + Delete: Old, + Equal: Context, + } +) + +// UnifiedEncoder encodes an unified diff into the provided Writer. It does not +// support similarity index for renames or sorting hash representations. +type UnifiedEncoder struct { + io.Writer + + // contextLines is the count of unchanged lines that will appear surrounding + // a change. + contextLines int + + // colorConfig is the color configuration. The default is no color. + color ColorConfig +} + +// NewUnifiedEncoder returns a new UnifiedEncoder that writes to w. +func NewUnifiedEncoder(w io.Writer, contextLines int) *UnifiedEncoder { + return &UnifiedEncoder{ + Writer: w, + contextLines: contextLines, + } +} + +// SetColor sets e's color configuration and returns e. +func (e *UnifiedEncoder) SetColor(colorConfig ColorConfig) *UnifiedEncoder { + e.color = colorConfig + return e +} + +// Encode encodes patch. +func (e *UnifiedEncoder) Encode(patch Patch) error { + sb := &strings.Builder{} + + if message := patch.Message(); message != "" { + sb.WriteString(message) + if !strings.HasSuffix(message, "\n") { + sb.WriteByte('\n') + } + } + + for _, filePatch := range patch.FilePatches() { + e.writeFilePatchHeader(sb, filePatch) + g := newHunksGenerator(filePatch.Chunks(), e.contextLines) + for _, hunk := range g.Generate() { + hunk.writeTo(sb, e.color) + } + } + + _, err := e.Write([]byte(sb.String())) + return err +} + +func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch FilePatch) { + from, to := filePatch.Files() + if from == nil && to == nil { + return + } + isBinary := filePatch.IsBinary() + + var lines []string + switch { + case from != nil && to != nil: + hashEquals := from.Hash() == to.Hash() + lines = append(lines, + fmt.Sprintf("diff --git a/%s b/%s", from.Path(), to.Path()), + ) + if from.Mode() != to.Mode() { + lines = append(lines, + fmt.Sprintf("old mode %o", from.Mode()), + fmt.Sprintf("new mode %o", to.Mode()), + ) + } + if from.Path() != to.Path() { + lines = append(lines, + fmt.Sprintf("rename from %s", from.Path()), + fmt.Sprintf("rename to %s", to.Path()), + ) + } + if from.Mode() != to.Mode() && !hashEquals { + lines = append(lines, + fmt.Sprintf("index %s..%s", from.Hash(), to.Hash()), + ) + } else if !hashEquals { + lines = append(lines, + fmt.Sprintf("index %s..%s %o", from.Hash(), to.Hash(), from.Mode()), + ) + } + if !hashEquals { + lines = e.appendPathLines(lines, "a/"+from.Path(), "b/"+to.Path(), isBinary) + } + case from == nil: + lines = append(lines, + fmt.Sprintf("diff --git a/%s b/%s", to.Path(), to.Path()), + fmt.Sprintf("new file mode %o", to.Mode()), + fmt.Sprintf("index %s..%s", plumbing.ZeroHash, to.Hash()), + ) + lines = e.appendPathLines(lines, "/dev/null", "b/"+to.Path(), isBinary) + case to == nil: + lines = append(lines, + fmt.Sprintf("diff --git a/%s b/%s", from.Path(), from.Path()), + fmt.Sprintf("deleted file mode %o", from.Mode()), + fmt.Sprintf("index %s..%s", from.Hash(), plumbing.ZeroHash), + ) + lines = e.appendPathLines(lines, "a/"+from.Path(), "/dev/null", isBinary) + } + + sb.WriteString(e.color[Meta]) + sb.WriteString(lines[0]) + for _, line := range lines[1:] { + sb.WriteByte('\n') + sb.WriteString(line) + } + sb.WriteString(e.color.Reset(Meta)) + sb.WriteByte('\n') +} + +func (e *UnifiedEncoder) appendPathLines(lines []string, fromPath, toPath string, isBinary bool) []string { + if isBinary { + return append(lines, + fmt.Sprintf("Binary files %s and %s differ", fromPath, toPath), + ) + } + return append(lines, + fmt.Sprintf("--- %s", fromPath), + fmt.Sprintf("+++ %s", toPath), + ) +} + +type hunksGenerator struct { + fromLine, toLine int + ctxLines int + chunks []Chunk + current *hunk + hunks []*hunk + beforeContext, afterContext []string +} + +func newHunksGenerator(chunks []Chunk, ctxLines int) *hunksGenerator { + return &hunksGenerator{ + chunks: chunks, + ctxLines: ctxLines, + } +} + +func (g *hunksGenerator) Generate() []*hunk { + for i, chunk := range g.chunks { + lines := splitLines(chunk.Content()) + nLines := len(lines) + + switch chunk.Type() { + case Equal: + g.fromLine += nLines + g.toLine += nLines + g.processEqualsLines(lines, i) + case Delete: + if nLines != 0 { + g.fromLine++ + } + + g.processHunk(i, chunk.Type()) + g.fromLine += nLines - 1 + g.current.AddOp(chunk.Type(), lines...) + case Add: + if nLines != 0 { + g.toLine++ + } + g.processHunk(i, chunk.Type()) + g.toLine += nLines - 1 + g.current.AddOp(chunk.Type(), lines...) + } + + if i == len(g.chunks)-1 && g.current != nil { + g.hunks = append(g.hunks, g.current) + } + } + + return g.hunks +} + +func (g *hunksGenerator) processHunk(i int, op Operation) { + if g.current != nil { + return + } + + var ctxPrefix string + linesBefore := len(g.beforeContext) + if linesBefore > g.ctxLines { + ctxPrefix = g.beforeContext[linesBefore-g.ctxLines-1] + g.beforeContext = g.beforeContext[linesBefore-g.ctxLines:] + linesBefore = g.ctxLines + } + + g.current = &hunk{ctxPrefix: strings.TrimSuffix(ctxPrefix, "\n")} + g.current.AddOp(Equal, g.beforeContext...) + + switch op { + case Delete: + g.current.fromLine, g.current.toLine = + g.addLineNumbers(g.fromLine, g.toLine, linesBefore, i, Add) + case Add: + g.current.toLine, g.current.fromLine = + g.addLineNumbers(g.toLine, g.fromLine, linesBefore, i, Delete) + } + + g.beforeContext = nil +} + +// addLineNumbers obtains the line numbers in a new chunk. +func (g *hunksGenerator) addLineNumbers(la, lb int, linesBefore int, i int, op Operation) (cla, clb int) { + cla = la - linesBefore + // we need to search for a reference for the next diff + switch { + case linesBefore != 0 && g.ctxLines != 0: + if lb > g.ctxLines { + clb = lb - g.ctxLines + 1 + } else { + clb = 1 + } + case g.ctxLines == 0: + clb = lb + case i != len(g.chunks)-1: + next := g.chunks[i+1] + if next.Type() == op || next.Type() == Equal { + // this diff will be into this chunk + clb = lb + 1 + } + } + + return +} + +func (g *hunksGenerator) processEqualsLines(ls []string, i int) { + if g.current == nil { + g.beforeContext = append(g.beforeContext, ls...) + return + } + + g.afterContext = append(g.afterContext, ls...) + if len(g.afterContext) <= g.ctxLines*2 && i != len(g.chunks)-1 { + g.current.AddOp(Equal, g.afterContext...) + g.afterContext = nil + } else { + ctxLines := g.ctxLines + if ctxLines > len(g.afterContext) { + ctxLines = len(g.afterContext) + } + g.current.AddOp(Equal, g.afterContext[:ctxLines]...) + g.hunks = append(g.hunks, g.current) + + g.current = nil + g.beforeContext = g.afterContext[ctxLines:] + g.afterContext = nil + } +} + +func splitLines(s string) []string { + out := splitLinesRegexp.FindAllString(s, -1) + if out[len(out)-1] == "" { + out = out[:len(out)-1] + } + return out +} + +type hunk struct { + fromLine int + toLine int + + fromCount int + toCount int + + ctxPrefix string + ops []*op +} + +func (h *hunk) writeTo(sb *strings.Builder, color ColorConfig) { + sb.WriteString(color[Frag]) + sb.WriteString("@@ -") + + if h.fromCount == 1 { + sb.WriteString(strconv.Itoa(h.fromLine)) + } else { + sb.WriteString(strconv.Itoa(h.fromLine)) + sb.WriteByte(',') + sb.WriteString(strconv.Itoa(h.fromCount)) + } + + sb.WriteString(" +") + + if h.toCount == 1 { + sb.WriteString(strconv.Itoa(h.toLine)) + } else { + sb.WriteString(strconv.Itoa(h.toLine)) + sb.WriteByte(',') + sb.WriteString(strconv.Itoa(h.toCount)) + } + + sb.WriteString(" @@") + sb.WriteString(color.Reset(Frag)) + + if h.ctxPrefix != "" { + sb.WriteByte(' ') + sb.WriteString(color[Func]) + sb.WriteString(h.ctxPrefix) + sb.WriteString(color.Reset(Func)) + } + + sb.WriteByte('\n') + + for _, op := range h.ops { + op.writeTo(sb, color) + } +} + +func (h *hunk) AddOp(t Operation, ss ...string) { + n := len(ss) + switch t { + case Add: + h.toCount += n + case Delete: + h.fromCount += n + case Equal: + h.toCount += n + h.fromCount += n + } + + for _, s := range ss { + h.ops = append(h.ops, &op{s, t}) + } +} + +type op struct { + text string + t Operation +} + +func (o *op) writeTo(sb *strings.Builder, color ColorConfig) { + colorKey := operationColorKey[o.t] + sb.WriteString(color[colorKey]) + sb.WriteByte(operationChar[o.t]) + if strings.HasSuffix(o.text, "\n") { + sb.WriteString(strings.TrimSuffix(o.text, "\n")) + } else { + sb.WriteString(o.text + "\n\\ No newline at end of file") + } + sb.WriteString(color.Reset(colorKey)) + sb.WriteByte('\n') +} diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/dir.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/dir.go similarity index 89% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/dir.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/dir.go index f4444bfb3..437a0896c 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/dir.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/dir.go @@ -1,6 +1,7 @@ package gitignore import ( + "bufio" "bytes" "io/ioutil" "os" @@ -8,14 +9,13 @@ import ( "strings" "github.com/go-git/go-billy/v5" - "github.com/go-git/go-git/v5/plumbing/format/config" - gioutil "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/format/config" + gioutil "github.com/jesseduffield/go-git/v5/utils/ioutil" ) 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/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/matcher.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/matcher.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/matcher.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/matcher.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/pattern.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/pattern.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/pattern.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/gitignore/pattern.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/decoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/decoder.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/decoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/decoder.go index 7768bd650..65401996d 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/decoder.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/decoder.go @@ -6,7 +6,7 @@ import ( "errors" "io" - "github.com/go-git/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/utils/binary" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/encoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/encoder.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/encoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/encoder.go index 26b2e4d6b..235853465 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/encoder.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/encoder.go @@ -5,7 +5,7 @@ import ( "hash" "io" - "github.com/go-git/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/utils/binary" ) // Encoder writes MemoryIndex structs to an output stream. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/idxfile.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/idxfile.go similarity index 99% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/idxfile.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/idxfile.go index 64dd8dcef..e5ac0ed36 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/idxfile.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/idxfile.go @@ -7,7 +7,7 @@ import ( encbin "encoding/binary" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) const ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/writer.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/writer.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/writer.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/writer.go index daa160502..a7dd47c71 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/writer.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/idxfile/writer.go @@ -7,8 +7,8 @@ import ( "sort" "sync" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/utils/binary" ) // objects implements sort.Interface and uses hash as sorting key. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/decoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/decoder.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/index/decoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/decoder.go index 79d0b9e11..3fb1ef84a 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/decoder.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/decoder.go @@ -11,8 +11,8 @@ import ( "strconv" "time" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/utils/binary" ) var ( @@ -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/vendor/github.com/go-git/go-git/v5/plumbing/format/index/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/index/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/encoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/encoder.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/index/encoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/encoder.go index 00d4e7a31..e21c451a6 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/encoder.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/encoder.go @@ -9,7 +9,7 @@ import ( "sort" "time" - "github.com/go-git/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/utils/binary" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/index.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/index.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/index/index.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/index.go index 649416a2b..175396e62 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/index.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/index.go @@ -7,8 +7,8 @@ import ( "path/filepath" "time" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/match.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/match.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/index/match.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/index/match.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/reader.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/reader.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/reader.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/reader.go index b6b2ca06d..7a70fc0c7 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/reader.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/reader.go @@ -6,8 +6,8 @@ import ( "io" "strconv" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/packfile" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/packfile" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/writer.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/writer.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/writer.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/writer.go index 2a96a4370..3414d5646 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/writer.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/objfile/writer.go @@ -6,7 +6,7 @@ import ( "io" "strconv" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/common.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/common.go index df423ad50..3f60c3eb0 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/common.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/common.go @@ -6,8 +6,8 @@ import ( "io" "sync" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) var signature = []byte{'P', 'A', 'C', 'K'} diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_index.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/delta_index.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_index.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/delta_index.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_selector.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/delta_selector.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_selector.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/delta_selector.go index 4b60ff394..1741fbd22 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_selector.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/delta_selector.go @@ -4,8 +4,8 @@ import ( "sort" "sync" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) const ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/diff_delta.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/diff_delta.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/diff_delta.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/diff_delta.go index 1d4b384a7..1282e3f68 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/diff_delta.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/diff_delta.go @@ -3,7 +3,8 @@ package packfile import ( "bytes" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // See https://github.com/jelmer/dulwich/blob/master/dulwich/pack.py and @@ -27,17 +28,20 @@ func GetDelta(base, target plumbing.EncodedObject) (plumbing.EncodedObject, erro return getDelta(new(deltaIndex), base, target) } -func getDelta(index *deltaIndex, base, target plumbing.EncodedObject) (plumbing.EncodedObject, error) { +func getDelta(index *deltaIndex, base, target plumbing.EncodedObject) (o plumbing.EncodedObject, err error) { br, err := base.Reader() if err != nil { return nil, err } - defer br.Close() + + defer ioutil.CheckClose(br, &err) + tr, err := target.Reader() if err != nil { return nil, err } - defer tr.Close() + + defer ioutil.CheckClose(tr, &err) bb := bufPool.Get().(*bytes.Buffer) defer bufPool.Put(bb) diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/encoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/encoder.go similarity index 93% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/encoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/encoder.go index 65fae523a..f5c25a3d2 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/encoder.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/encoder.go @@ -6,9 +6,10 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // Encoder gets the data from the storage and write it into the writer in PACK @@ -80,7 +81,7 @@ func (e *Encoder) head(numEntries int) error { ) } -func (e *Encoder) entry(o *ObjectToPack) error { +func (e *Encoder) entry(o *ObjectToPack) (err error) { if o.WantWrite() { // A cycle exists in this delta chain. This should only occur if a // selected object representation disappeared during writing @@ -119,17 +120,22 @@ func (e *Encoder) entry(o *ObjectToPack) error { } e.zw.Reset(e.w) + + defer ioutil.CheckClose(e.zw, &err) + or, err := o.Object.Reader() if err != nil { return err } + defer ioutil.CheckClose(or, &err) + _, err = io.Copy(e.zw, or) if err != nil { return err } - return e.zw.Close() + return nil } func (e *Encoder) writeBaseIfDelta(o *ObjectToPack) error { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/error.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/error.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/error.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/error.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/fsobject.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/fsobject.go similarity index 93% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/fsobject.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/fsobject.go index c5edaf52e..b571554df 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/fsobject.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/fsobject.go @@ -4,9 +4,9 @@ import ( "io" billy "github.com/go-git/go-billy/v5" - "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" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/plumbing/format/idxfile" ) // FSObject is an object from the packfile on the filesystem. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/object_pack.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/object_pack.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/object_pack.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/object_pack.go index 8ce29ef8b..484946dc3 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/object_pack.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/object_pack.go @@ -1,7 +1,7 @@ package packfile import ( - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) // ObjectToPack is a representation of an object that is going to be into a diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/packfile.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/packfile.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/packfile.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/packfile.go index d06004197..f93ab1c67 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/packfile.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/packfile.go @@ -6,10 +6,11 @@ import ( "os" billy "github.com/go-git/go-billy/v5" - "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" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/plumbing/format/idxfile" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) var ( @@ -307,12 +308,14 @@ func (p *Packfile) getNextMemoryObject(h *ObjectHeader) (plumbing.EncodedObject, return obj, nil } -func (p *Packfile) fillRegularObjectContent(obj plumbing.EncodedObject) error { +func (p *Packfile) fillRegularObjectContent(obj plumbing.EncodedObject) (err error) { w, err := obj.Writer() if err != nil { return err } + defer ioutil.CheckClose(w, &err) + _, _, err = p.s.NextObject(w) p.cachePut(obj) diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/parser.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/parser.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/parser.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/parser.go index d411c5b57..726606538 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/parser.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/parser.go @@ -4,11 +4,12 @@ import ( "bytes" "errors" "io" - "io/ioutil" + stdioutil "io/ioutil" - "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/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) var ( @@ -283,7 +284,7 @@ func (p *Parser) resolveDeltas() error { if !obj.IsDelta() && len(obj.Children) > 0 { for _, child := range obj.Children { - if err := p.resolveObject(ioutil.Discard, child, content); err != nil { + if err := p.resolveObject(stdioutil.Discard, child, content); err != nil { return err } } @@ -298,7 +299,7 @@ func (p *Parser) resolveDeltas() error { return nil } -func (p *Parser) get(o *objectInfo, buf *bytes.Buffer) error { +func (p *Parser) get(o *objectInfo, buf *bytes.Buffer) (err error) { if !o.ExternalRef { // skip cache check for placeholder parents b, ok := p.cache.Get(o.Offset) if ok { @@ -310,17 +311,21 @@ func (p *Parser) get(o *objectInfo, buf *bytes.Buffer) error { // If it's not on the cache and is not a delta we can try to find it in the // storage, if there's one. External refs must enter here. if p.storage != nil && !o.Type.IsDelta() { - e, err := p.storage.EncodedObject(plumbing.AnyObject, o.SHA1) + var e plumbing.EncodedObject + e, err = p.storage.EncodedObject(plumbing.AnyObject, o.SHA1) if err != nil { return err } o.Type = e.Type() - r, err := e.Reader() + var r io.ReadCloser + r, err = e.Reader() if err != nil { return err } + defer ioutil.CheckClose(r, &err) + _, err = buf.ReadFrom(io.LimitReader(r, e.Size())) return err } diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/patch_delta.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/patch_delta.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/patch_delta.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/patch_delta.go index 57c9da7ce..ed71857fe 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/patch_delta.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/patch_delta.go @@ -5,7 +5,8 @@ import ( "errors" "io" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // See https://github.com/git/git/blob/49fa3dc76179e04b0833542fa52d0f287a4955ac/delta.h @@ -16,17 +17,21 @@ import ( const deltaSizeMin = 4 // ApplyDelta writes to target the result of applying the modification deltas in delta to base. -func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) error { +func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) (err error) { r, err := base.Reader() if err != nil { return err } + defer ioutil.CheckClose(r, &err) + w, err := target.Writer() if err != nil { return err } + defer ioutil.CheckClose(w, &err) + buf := bufPool.Get().(*bytes.Buffer) defer bufPool.Put(buf) buf.Reset() @@ -44,7 +49,6 @@ func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) error { return err } - target.SetSize(int64(dst.Len())) b := byteSlicePool.Get().([]byte) @@ -108,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/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/scanner.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/scanner.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/scanner.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/scanner.go index 6e6a68788..d6efeaf6e 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/scanner.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/packfile/scanner.go @@ -11,9 +11,9 @@ import ( stdioutil "io/ioutil" "sync" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/utils/binary" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/encoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/pktline/encoder.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/encoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/pktline/encoder.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/scanner.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/format/pktline/scanner.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/scanner.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/format/pktline/scanner.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/hash.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/hash.go similarity index 88% rename from vendor/github.com/go-git/go-git/v5/plumbing/hash.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/hash.go index 637a4252a..afc602a9e 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/hash.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/hash.go @@ -71,3 +71,13 @@ type HashSlice []Hash func (p HashSlice) Len() int { return len(p) } func (p HashSlice) Less(i, j int) bool { return bytes.Compare(p[i][:], p[j][:]) < 0 } func (p HashSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// IsHash returns true if the given string is a valid hash. +func IsHash(s string) bool { + if len(s) != 40 { + return false + } + + _, err := hex.DecodeString(s) + return err == nil +} diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/memory.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/memory.go similarity index 77% rename from vendor/github.com/go-git/go-git/v5/plumbing/memory.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/memory.go index b8e1e1b81..21337cc0d 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/memory.go +++ b/vendor/github.com/jesseduffield/go-git/v5/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/vendor/github.com/go-git/go-git/v5/plumbing/object.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/object.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/blob.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/blob.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/blob.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/blob.go index 8fb7576fa..7bce28e80 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/blob.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/blob.go @@ -3,9 +3,9 @@ package object import ( "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // Blob is used to store arbitrary data - it is generally a file. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/change.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/change.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/change.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/change.go index 4474905e0..ff5d38e00 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/change.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/change.go @@ -6,7 +6,7 @@ import ( "fmt" "strings" - "github.com/go-git/go-git/v5/utils/merkletrie" + "github.com/jesseduffield/go-git/v5/utils/merkletrie" ) // Change values represent a detected change between two git trees. For @@ -18,7 +18,7 @@ type Change struct { To ChangeEntry } -var empty = ChangeEntry{} +var empty ChangeEntry // Action returns the kind of action represented by the change, an // insertion, a deletion or a modification. @@ -27,9 +27,11 @@ func (c *Change) Action() (merkletrie.Action, error) { return merkletrie.Action(0), fmt.Errorf("malformed change: empty from and to") } + if c.From == empty { return merkletrie.Insert, nil } + if c.To == empty { return merkletrie.Delete, nil } @@ -73,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, c.name()) diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/change_adaptor.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/change_adaptor.go similarity index 90% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/change_adaptor.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/change_adaptor.go index f70118828..53ef06c1b 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/change_adaptor.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/change_adaptor.go @@ -4,8 +4,8 @@ import ( "errors" "fmt" - "github.com/go-git/go-git/v5/utils/merkletrie" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/utils/merkletrie" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) // The following functions transform changes types form the merkletrie diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit.go similarity index 90% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/commit.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit.go index b37ff61d3..3f172d1ad 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit.go @@ -11,9 +11,9 @@ import ( "golang.org/x/crypto/openpgp" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) const ( @@ -78,21 +78,30 @@ func (c *Commit) Tree() (*Tree, error) { // PatchContext returns the Patch between the actual commit and the provided one. // Error will be return if context expires. Provided context must be non-nil. +// +// NOTE: Since version 5.1.0 the renames are correctly handled, the settings +// used are the recommended options DefaultDiffTreeOptions. func (c *Commit) PatchContext(ctx context.Context, to *Commit) (*Patch, error) { fromTree, err := c.Tree() if err != nil { return nil, err } - toTree, err := to.Tree() - if err != nil { - return nil, err + var toTree *Tree + if to != nil { + toTree, err = to.Tree() + if err != nil { + return nil, err + } } return fromTree.PatchContext(ctx, toTree) } // Patch returns the Patch between the actual commit and the provided one. +// +// NOTE: Since version 5.1.0 the renames are correctly handled, the settings +// used are the recommended options DefaultDiffTreeOptions. func (c *Commit) Patch(to *Commit) (*Patch, error) { return c.PatchContext(context.Background(), to) } @@ -234,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 { @@ -252,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 } @@ -266,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 } @@ -274,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 } @@ -287,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/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker.go index a96b6a4cf..60da75cad 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker.go @@ -4,9 +4,9 @@ import ( "container/list" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/storage" ) type commitPreIterator struct { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_bfs.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_bfs.go index 8047fa9bc..c9c744d6c 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_bfs.go @@ -3,8 +3,8 @@ package object import ( "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) type bfsCommitIterator struct { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go index e87c3dbbb..72343a64b 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go @@ -3,8 +3,8 @@ package object import ( "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) // NewFilterCommitIter returns a CommitIter that walks the commit history, @@ -173,4 +173,3 @@ func (w *filterCommitIter) addToQueue( return nil } - diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_ctime.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_ctime.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_ctime.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_ctime.go index fbddf1d23..69ac2aa35 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_ctime.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_ctime.go @@ -5,8 +5,8 @@ import ( "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/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) type commitIteratorByCTime struct { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_limit.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_limit.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_limit.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_limit.go index ac56a71c4..24677a872 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_limit.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_limit.go @@ -4,7 +4,7 @@ import ( "io" "time" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) type commitLimitIter struct { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_path.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_path.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_path.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_path.go index af6f745d2..ae3afe4cd 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_path.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/commit_walker_path.go @@ -3,9 +3,8 @@ package object import ( "io" - "github.com/go-git/go-git/v5/plumbing" - - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) type commitPathIter struct { @@ -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/vendor/github.com/go-git/go-git/v5/plumbing/object/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/common.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/common.go diff --git a/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/difftree.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/difftree.go new file mode 100644 index 000000000..a2dd582be --- /dev/null +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/difftree.go @@ -0,0 +1,98 @@ +package object + +import ( + "bytes" + "context" + + "github.com/jesseduffield/go-git/v5/utils/merkletrie" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" +) + +// DiffTree compares the content and mode of the blobs found via two +// tree objects. +// DiffTree does not perform rename detection, use DiffTreeWithOptions +// instead to detect renames. +func DiffTree(a, b *Tree) (Changes, error) { + return DiffTreeContext(context.Background(), a, b) +} + +// DiffTreeContext compares the content and mode of the blobs found via two +// tree objects. Provided context must be non-nil. +// An error will be returned if context expires. +func DiffTreeContext(ctx context.Context, a, b *Tree) (Changes, error) { + return DiffTreeWithOptions(ctx, a, b, nil) +} + +// DiffTreeOptions are the configurable options when performing a diff tree. +type DiffTreeOptions struct { + // DetectRenames is whether the diff tree will use rename detection. + DetectRenames bool + // RenameScore is the threshold to of similarity between files to consider + // that a pair of delete and insert are a rename. The number must be + // exactly between 0 and 100. + RenameScore uint + // RenameLimit is the maximum amount of files that can be compared when + // detecting renames. The number of comparisons that have to be performed + // is equal to the number of deleted files * the number of added files. + // That means, that if 100 files were deleted and 50 files were added, 5000 + // file comparisons may be needed. So, if the rename limit is 50, the number + // of both deleted and added needs to be equal or less than 50. + // A value of 0 means no limit. + RenameLimit uint + // OnlyExactRenames performs only detection of exact renames and will not perform + // any detection of renames based on file similarity. + OnlyExactRenames bool +} + +// DefaultDiffTreeOptions are the default and recommended options for the +// diff tree. +var DefaultDiffTreeOptions = &DiffTreeOptions{ + DetectRenames: true, + RenameScore: 60, + RenameLimit: 0, + OnlyExactRenames: false, +} + +// DiffTreeWithOptions compares the content and mode of the blobs found +// via two tree objects with the given options. The provided context +// must be non-nil. +// If no options are passed, no rename detection will be performed. The +// recommended options are DefaultDiffTreeOptions. +// An error will be returned if the context expires. +// This function will be deprecated and removed in v6 so the default +// behaviour of DiffTree is to detect renames. +func DiffTreeWithOptions( + ctx context.Context, + a, b *Tree, + opts *DiffTreeOptions, +) (Changes, error) { + from := NewTreeRootNode(a) + to := NewTreeRootNode(b) + + hashEqual := func(a, b noder.Hasher) bool { + return bytes.Equal(a.Hash(), b.Hash()) + } + + merkletrieChanges, err := merkletrie.DiffTreeContext(ctx, from, to, hashEqual) + if err != nil { + if err == merkletrie.ErrCanceled { + return nil, ErrCanceled + } + return nil, err + } + + changes, err := newChanges(merkletrieChanges) + if err != nil { + return nil, err + } + + if opts == nil { + opts = new(DiffTreeOptions) + } + + if opts.DetectRenames { + return DetectRenames(changes, opts) + } + + return changes, nil +} diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/file.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/file.go similarity index 93% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/file.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/file.go index 6cc5367d8..755f87859 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/file.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/file.go @@ -5,10 +5,10 @@ import ( "io" "strings" - "github.com/go-git/go-git/v5/plumbing/filemode" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/utils/binary" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/binary" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // File represents git file objects. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/merge_base.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/merge_base.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/merge_base.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/merge_base.go index b412361d0..33eb5d8b0 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/merge_base.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/merge_base.go @@ -4,8 +4,8 @@ import ( "fmt" "sort" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) // errIsReachable is thrown when first commit is an ancestor of the second diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/object.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/object.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/object.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/object.go index 13b1e91c9..d77b358e3 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/object.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/object.go @@ -10,8 +10,8 @@ import ( "strconv" "time" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) // ErrUnsupportedObject trigger when a non-supported object is being decoded. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/patch.go similarity index 92% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/patch.go index be1e60927..d4770ad8c 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/patch.go @@ -9,10 +9,10 @@ import ( "math" "strings" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/filemode" - fdiff "github.com/go-git/go-git/v5/plumbing/format/diff" - "github.com/go-git/go-git/v5/utils/diff" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + fdiff "github.com/jesseduffield/go-git/v5/plumbing/format/diff" + "github.com/jesseduffield/go-git/v5/utils/diff" dmp "github.com/sergi/go-diff/diffmatchpatch" ) @@ -115,18 +115,18 @@ func fileContent(f *File) (content string, isBinary bool, err error) { return } -// textPatch is an implementation of fdiff.Patch interface +// Patch is an implementation of fdiff.Patch interface type Patch struct { message string 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/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/rename.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/rename.go new file mode 100644 index 000000000..956c5cf89 --- /dev/null +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/rename.go @@ -0,0 +1,813 @@ +package object + +import ( + "errors" + "io" + "sort" + "strings" + + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/utils/merkletrie" +) + +// DetectRenames detects the renames in the given changes on two trees with +// the given options. It will return the given changes grouping additions and +// deletions into modifications when possible. +// If options is nil, the default diff tree options will be used. +func DetectRenames( + changes Changes, + opts *DiffTreeOptions, +) (Changes, error) { + if opts == nil { + opts = DefaultDiffTreeOptions + } + + detector := &renameDetector{ + renameScore: int(opts.RenameScore), + renameLimit: int(opts.RenameLimit), + onlyExact: opts.OnlyExactRenames, + } + + for _, c := range changes { + action, err := c.Action() + if err != nil { + return nil, err + } + + switch action { + case merkletrie.Insert: + detector.added = append(detector.added, c) + case merkletrie.Delete: + detector.deleted = append(detector.deleted, c) + default: + detector.modified = append(detector.modified, c) + } + } + + return detector.detect() +} + +// renameDetector will detect and resolve renames in a set of changes. +// see: https://github.com/eclipse/jgit/blob/master/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java +type renameDetector struct { + added []*Change + deleted []*Change + modified []*Change + + renameScore int + renameLimit int + onlyExact bool +} + +// detectExactRenames detects matches files that were deleted with files that +// were added where the hash is the same on both. If there are multiple targets +// the one with the most similar path will be chosen as the rename and the +// rest as either deletions or additions. +func (d *renameDetector) detectExactRenames() { + added := groupChangesByHash(d.added) + deletes := groupChangesByHash(d.deleted) + var uniqueAdds []*Change + var nonUniqueAdds [][]*Change + var addedLeft []*Change + + for _, cs := range added { + if len(cs) == 1 { + uniqueAdds = append(uniqueAdds, cs[0]) + } else { + nonUniqueAdds = append(nonUniqueAdds, cs) + } + } + + for _, c := range uniqueAdds { + hash := changeHash(c) + deleted := deletes[hash] + + if len(deleted) == 1 { + if sameMode(c, deleted[0]) { + d.modified = append(d.modified, &Change{From: deleted[0].From, To: c.To}) + delete(deletes, hash) + } else { + addedLeft = append(addedLeft, c) + } + } else if len(deleted) > 1 { + bestMatch := bestNameMatch(c, deleted) + if bestMatch != nil && sameMode(c, bestMatch) { + d.modified = append(d.modified, &Change{From: bestMatch.From, To: c.To}) + delete(deletes, hash) + + var newDeletes = make([]*Change, 0, len(deleted)-1) + for _, d := range deleted { + if d != bestMatch { + newDeletes = append(newDeletes, d) + } + } + deletes[hash] = newDeletes + } + } else { + addedLeft = append(addedLeft, c) + } + } + + for _, added := range nonUniqueAdds { + hash := changeHash(added[0]) + deleted := deletes[hash] + + if len(deleted) == 1 { + deleted := deleted[0] + bestMatch := bestNameMatch(deleted, added) + if bestMatch != nil && sameMode(deleted, bestMatch) { + d.modified = append(d.modified, &Change{From: deleted.From, To: bestMatch.To}) + delete(deletes, hash) + + for _, c := range added { + if c != bestMatch { + addedLeft = append(addedLeft, c) + } + } + } else { + addedLeft = append(addedLeft, added...) + } + } else if len(deleted) > 1 { + maxSize := len(deleted) * len(added) + if d.renameLimit > 0 && d.renameLimit < maxSize { + maxSize = d.renameLimit + } + + matrix := make(similarityMatrix, 0, maxSize) + + for delIdx, del := range deleted { + deletedName := changeName(del) + + for addIdx, add := range added { + addedName := changeName(add) + + score := nameSimilarityScore(addedName, deletedName) + matrix = append(matrix, similarityPair{added: addIdx, deleted: delIdx, score: score}) + + if len(matrix) >= maxSize { + break + } + } + + if len(matrix) >= maxSize { + break + } + } + + sort.Stable(matrix) + + usedAdds := make(map[*Change]struct{}) + usedDeletes := make(map[*Change]struct{}) + for i := len(matrix) - 1; i >= 0; i-- { + del := deleted[matrix[i].deleted] + add := added[matrix[i].added] + + if add == nil || del == nil { + // it was already matched + continue + } + + usedAdds[add] = struct{}{} + usedDeletes[del] = struct{}{} + d.modified = append(d.modified, &Change{From: del.From, To: add.To}) + added[matrix[i].added] = nil + deleted[matrix[i].deleted] = nil + } + + for _, c := range added { + if _, ok := usedAdds[c]; !ok && c != nil { + addedLeft = append(addedLeft, c) + } + } + + var newDeletes = make([]*Change, 0, len(deleted)-len(usedDeletes)) + for _, c := range deleted { + if _, ok := usedDeletes[c]; !ok && c != nil { + newDeletes = append(newDeletes, c) + } + } + deletes[hash] = newDeletes + } else { + addedLeft = append(addedLeft, added...) + } + } + + d.added = addedLeft + d.deleted = nil + for _, dels := range deletes { + d.deleted = append(d.deleted, dels...) + } +} + +// detectContentRenames detects renames based on the similarity of the content +// in the files by building a matrix of pairs between sources and destinations +// and matching by the highest score. +// see: https://github.com/eclipse/jgit/blob/master/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java +func (d *renameDetector) detectContentRenames() error { + cnt := max(len(d.added), len(d.deleted)) + if d.renameLimit > 0 && cnt > d.renameLimit { + return nil + } + + srcs, dsts := d.deleted, d.added + matrix, err := buildSimilarityMatrix(srcs, dsts, d.renameScore) + if err != nil { + return err + } + renames := make([]*Change, 0, min(len(matrix), len(dsts))) + + // Match rename pairs on a first come, first serve basis until + // we have looked at everything that is above the minimum score. + for i := len(matrix) - 1; i >= 0; i-- { + pair := matrix[i] + src := srcs[pair.deleted] + dst := dsts[pair.added] + + if dst == nil || src == nil { + // It was already matched before + continue + } + + renames = append(renames, &Change{From: src.From, To: dst.To}) + + // Claim destination and source as matched + dsts[pair.added] = nil + srcs[pair.deleted] = nil + } + + d.modified = append(d.modified, renames...) + d.added = compactChanges(dsts) + d.deleted = compactChanges(srcs) + + return nil +} + +func (d *renameDetector) detect() (Changes, error) { + if len(d.added) > 0 && len(d.deleted) > 0 { + d.detectExactRenames() + + if !d.onlyExact { + if err := d.detectContentRenames(); err != nil { + return nil, err + } + } + } + + result := make(Changes, 0, len(d.added)+len(d.deleted)+len(d.modified)) + result = append(result, d.added...) + result = append(result, d.deleted...) + result = append(result, d.modified...) + + sort.Stable(result) + + return result, nil +} + +func bestNameMatch(change *Change, changes []*Change) *Change { + var best *Change + var bestScore int + + cname := changeName(change) + + for _, c := range changes { + score := nameSimilarityScore(cname, changeName(c)) + if score > bestScore { + bestScore = score + best = c + } + } + + return best +} + +func nameSimilarityScore(a, b string) int { + aDirLen := strings.LastIndexByte(a, '/') + 1 + bDirLen := strings.LastIndexByte(b, '/') + 1 + + dirMin := min(aDirLen, bDirLen) + dirMax := max(aDirLen, bDirLen) + + var dirScoreLtr, dirScoreRtl int + if dirMax == 0 { + dirScoreLtr = 100 + dirScoreRtl = 100 + } else { + var dirSim int + + for ; dirSim < dirMin; dirSim++ { + if a[dirSim] != b[dirSim] { + break + } + } + + dirScoreLtr = dirSim * 100 / dirMax + + if dirScoreLtr == 100 { + dirScoreRtl = 100 + } else { + for dirSim = 0; dirSim < dirMin; dirSim++ { + if a[aDirLen-1-dirSim] != b[bDirLen-1-dirSim] { + break + } + } + dirScoreRtl = dirSim * 100 / dirMax + } + } + + fileMin := min(len(a)-aDirLen, len(b)-bDirLen) + fileMax := max(len(a)-aDirLen, len(b)-bDirLen) + + fileSim := 0 + for ; fileSim < fileMin; fileSim++ { + if a[len(a)-1-fileSim] != b[len(b)-1-fileSim] { + break + } + } + fileScore := fileSim * 100 / fileMax + + return (((dirScoreLtr + dirScoreRtl) * 25) + (fileScore * 50)) / 100 +} + +func changeName(c *Change) string { + if c.To != empty { + return c.To.Name + } + return c.From.Name +} + +func changeHash(c *Change) plumbing.Hash { + if c.To != empty { + return c.To.TreeEntry.Hash + } + + return c.From.TreeEntry.Hash +} + +func changeMode(c *Change) filemode.FileMode { + if c.To != empty { + return c.To.TreeEntry.Mode + } + + return c.From.TreeEntry.Mode +} + +func sameMode(a, b *Change) bool { + return changeMode(a) == changeMode(b) +} + +func groupChangesByHash(changes []*Change) map[plumbing.Hash][]*Change { + var result = make(map[plumbing.Hash][]*Change) + for _, c := range changes { + hash := changeHash(c) + result[hash] = append(result[hash], c) + } + return result +} + +type similarityMatrix []similarityPair + +func (m similarityMatrix) Len() int { return len(m) } +func (m similarityMatrix) Swap(i, j int) { m[i], m[j] = m[j], m[i] } +func (m similarityMatrix) Less(i, j int) bool { + if m[i].score == m[j].score { + if m[i].added == m[j].added { + return m[i].deleted < m[j].deleted + } + return m[i].added < m[j].added + } + return m[i].score < m[j].score +} + +type similarityPair struct { + // index of the added file + added int + // index of the deleted file + deleted int + // similarity score + score int +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func buildSimilarityMatrix(srcs, dsts []*Change, renameScore int) (similarityMatrix, error) { + // Allocate for the worst-case scenario where every pair has a score + // that we need to consider. We might not need that many. + matrix := make(similarityMatrix, 0, len(srcs)*len(dsts)) + srcSizes := make([]int64, len(srcs)) + dstSizes := make([]int64, len(dsts)) + dstTooLarge := make(map[int]bool) + + // Consider each pair of files, if the score is above the minimum + // threshold we need to record that scoring in the matrix so we can + // later find the best matches. +outerLoop: + for srcIdx, src := range srcs { + if changeMode(src) != filemode.Regular { + continue + } + + // Declare the from file and the similarity index here to be able to + // reuse it inside the inner loop. The reason to not initialize them + // here is so we can skip the initialization in case they happen to + // not be needed later. They will be initialized inside the inner + // loop if and only if they're needed and reused in subsequent passes. + var from *File + var s *similarityIndex + var err error + for dstIdx, dst := range dsts { + if changeMode(dst) != filemode.Regular { + continue + } + + if dstTooLarge[dstIdx] { + continue + } + + var to *File + srcSize := srcSizes[srcIdx] + if srcSize == 0 { + from, _, err = src.Files() + if err != nil { + return nil, err + } + srcSize = from.Size + 1 + srcSizes[srcIdx] = srcSize + } + + dstSize := dstSizes[dstIdx] + if dstSize == 0 { + _, to, err = dst.Files() + if err != nil { + return nil, err + } + dstSize = to.Size + 1 + dstSizes[dstIdx] = dstSize + } + + min, max := srcSize, dstSize + if dstSize < srcSize { + min = dstSize + max = srcSize + } + + if int(min*100/max) < renameScore { + // File sizes are too different to be a match + continue + } + + if s == nil { + s, err = fileSimilarityIndex(from) + if err != nil { + if err == errIndexFull { + continue outerLoop + } + return nil, err + } + } + + if to == nil { + _, to, err = dst.Files() + if err != nil { + return nil, err + } + } + + di, err := fileSimilarityIndex(to) + if err != nil { + if err == errIndexFull { + dstTooLarge[dstIdx] = true + } + + return nil, err + } + + contentScore := s.score(di, 10000) + // The name score returns a value between 0 and 100, so we need to + // convert it to the same range as the content score. + nameScore := nameSimilarityScore(src.From.Name, dst.To.Name) * 100 + score := (contentScore*99 + nameScore*1) / 10000 + + if score < renameScore { + continue + } + + matrix = append(matrix, similarityPair{added: dstIdx, deleted: srcIdx, score: score}) + } + } + + sort.Stable(matrix) + + return matrix, nil +} + +func compactChanges(changes []*Change) []*Change { + var result []*Change + for _, c := range changes { + if c != nil { + result = append(result, c) + } + } + return result +} + +const ( + keyShift = 32 + maxCountValue = (1 << keyShift) - 1 +) + +var errIndexFull = errors.New("index is full") + +// similarityIndex is an index structure of lines/blocks in one file. +// This structure can be used to compute an approximation of the similarity +// 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 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 { + hashed uint64 + // number of non-zero entries in hashes + numHashes int + growAt int + hashes []keyCountPair + hashBits int +} + +func fileSimilarityIndex(f *File) (*similarityIndex, error) { + idx := newSimilarityIndex() + if err := idx.hash(f); err != nil { + return nil, err + } + + sort.Stable(keyCountPairs(idx.hashes)) + + return idx, nil +} + +func newSimilarityIndex() *similarityIndex { + return &similarityIndex{ + hashBits: 8, + hashes: make([]keyCountPair, 1<<8), + growAt: shouldGrowAt(8), + } +} + +func (i *similarityIndex) hash(f *File) error { + isBin, err := f.IsBinary() + if err != nil { + return err + } + + r, err := f.Reader() + if err != nil { + return err + } + + defer ioutil.CheckClose(r, &err) + + return i.hashContent(r, f.Size, isBin) +} + +func (i *similarityIndex) hashContent(r io.Reader, size int64, isBin bool) error { + var buf = make([]byte, 4096) + var ptr, cnt int + remaining := size + + for 0 < remaining { + hash := 5381 + var blockHashedCnt uint64 + + // Hash one line or block, whatever happens first + n := int64(0) + for { + if ptr == cnt { + ptr = 0 + var err error + cnt, err = io.ReadFull(r, buf) + if err != nil && err != io.ErrUnexpectedEOF { + return err + } + + if cnt == 0 { + return io.EOF + } + } + n++ + c := buf[ptr] & 0xff + ptr++ + + // Ignore CR in CRLF sequence if it's text + if !isBin && c == '\r' && ptr < cnt && buf[ptr] == '\n' { + continue + } + blockHashedCnt++ + + if c == '\n' { + break + } + + hash = (hash << 5) + hash + int(c) + + if n >= 64 || n >= remaining { + break + } + } + i.hashed += blockHashedCnt + if err := i.add(hash, blockHashedCnt); err != nil { + return err + } + remaining -= n + } + + return nil +} + +// score computes the similarity score between this index and another one. +// A region of a file is defined as a line in a text file or a fixed-size +// block in a binary file. To prepare an index, each region in the file is +// hashed; the values and counts of hashes are retained in a sorted table. +// Define the similarity fraction F as the count of matching regions between +// the two files divided between the maximum count of regions in either file. +// The similarity score is F multiplied by the maxScore constant, yielding a +// range [0, maxScore]. It is defined as maxScore for the degenerate case of +// two empty files. +// The similarity score is symmetrical; i.e. a.score(b) == b.score(a). +func (i *similarityIndex) score(other *similarityIndex, maxScore int) int { + var maxHashed = i.hashed + if maxHashed < other.hashed { + maxHashed = other.hashed + } + if maxHashed == 0 { + return maxScore + } + + return int(i.common(other) * uint64(maxScore) / maxHashed) +} + +func (i *similarityIndex) common(dst *similarityIndex) uint64 { + srcIdx, dstIdx := 0, 0 + if i.numHashes == 0 || dst.numHashes == 0 { + return 0 + } + + var common uint64 + srcKey, dstKey := i.hashes[srcIdx].key(), dst.hashes[dstIdx].key() + + for { + if srcKey == dstKey { + srcCnt, dstCnt := i.hashes[srcIdx].count(), dst.hashes[dstIdx].count() + if srcCnt < dstCnt { + common += srcCnt + } else { + common += dstCnt + } + + srcIdx++ + if srcIdx == len(i.hashes) { + break + } + srcKey = i.hashes[srcIdx].key() + + dstIdx++ + if dstIdx == len(dst.hashes) { + break + } + dstKey = dst.hashes[dstIdx].key() + } else if srcKey < dstKey { + // Region of src that is not in dst + srcIdx++ + if srcIdx == len(i.hashes) { + break + } + srcKey = i.hashes[srcIdx].key() + } else { + // Region of dst that is not in src + dstIdx++ + if dstIdx == len(dst.hashes) { + break + } + dstKey = dst.hashes[dstIdx].key() + } + } + + return common +} + +func (i *similarityIndex) add(key int, cnt uint64) error { + key = int(uint32(key) * 0x9e370001 >> 1) + + j := i.slot(key) + for { + v := i.hashes[j] + if v == 0 { + // It's an empty slot, so we can store it here. + if i.growAt <= i.numHashes { + if err := i.grow(); err != nil { + return err + } + j = i.slot(key) + continue + } + + var err error + i.hashes[j], err = newKeyCountPair(key, cnt) + if err != nil { + return err + } + i.numHashes++ + return nil + } else if v.key() == key { + // It's the same key, so increment the counter. + var err error + i.hashes[j], err = newKeyCountPair(key, v.count()+cnt) + if err != nil { + return err + } + return nil + } else if j+1 >= len(i.hashes) { + j = 0 + } else { + j++ + } + } +} + +type keyCountPair uint64 + +func newKeyCountPair(key int, cnt uint64) (keyCountPair, error) { + if cnt > maxCountValue { + return 0, errIndexFull + } + + return keyCountPair((uint64(key) << keyShift) | cnt), nil +} + +func (p keyCountPair) key() int { + return int(p >> keyShift) +} + +func (p keyCountPair) count() uint64 { + return uint64(p) & maxCountValue +} + +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)) +} + +func shouldGrowAt(hashBits int) int { + return (1 << uint(hashBits)) * (hashBits - 3) / hashBits +} + +func (i *similarityIndex) grow() error { + if i.hashBits == 30 { + return errIndexFull + } + + old := i.hashes + + i.hashBits++ + i.growAt = shouldGrowAt(i.hashBits) + + // TODO(erizocosmico): find a way to check if it will OOM and return + // errIndexFull instead. + i.hashes = make([]keyCountPair, 1<= len(i.hashes) { + j = 0 + } + } + i.hashes[j] = v + } + } + + return nil +} + +type keyCountPairs []keyCountPair + +func (p keyCountPairs) Len() int { return len(p) } +func (p keyCountPairs) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p keyCountPairs) Less(i, j int) bool { return p[i] < p[j] } diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/tag.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/tag.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/tag.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/tag.go index 464165804..838af1325 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/tag.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/tag.go @@ -10,9 +10,9 @@ import ( "golang.org/x/crypto/openpgp" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // Tag represents an annotated tag object. It points to a single git object of diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/tree.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/tree.go similarity index 88% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/tree.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/tree.go index d3c8c77d1..f97c63a2f 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/tree.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/tree.go @@ -10,10 +10,10 @@ import ( "path/filepath" "strings" - "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/storer" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) const ( @@ -304,29 +304,34 @@ func (t *Tree) buildMap() { } // Diff returns a list of changes between this tree and the provided one -func (from *Tree) Diff(to *Tree) (Changes, error) { - return DiffTree(from, to) +func (t *Tree) Diff(to *Tree) (Changes, error) { + return t.DiffContext(context.Background(), to) } -// Diff returns a list of changes between this tree and the provided one -// Error will be returned if context expires -// Provided context must be non nil -func (from *Tree) DiffContext(ctx context.Context, to *Tree) (Changes, error) { - return DiffTreeContext(ctx, from, to) +// DiffContext returns a list of changes between this tree and the provided one +// Error will be returned if context expires. Provided context must be non nil. +// +// NOTE: Since version 5.1.0 the renames are correctly handled, the settings +// used are the recommended options DefaultDiffTreeOptions. +func (t *Tree) DiffContext(ctx context.Context, to *Tree) (Changes, error) { + return DiffTreeWithOptions(ctx, t, to, DefaultDiffTreeOptions) } // Patch returns a slice of Patch objects with all the changes between trees // in chunks. This representation can be used to create several diff outputs. -func (from *Tree) Patch(to *Tree) (*Patch, error) { - return from.PatchContext(context.Background(), to) +func (t *Tree) Patch(to *Tree) (*Patch, error) { + return t.PatchContext(context.Background(), to) } -// Patch returns a slice of Patch objects with all the changes between trees -// in chunks. This representation can be used to create several diff outputs. -// If context expires, an error will be returned -// Provided context must be non-nil -func (from *Tree) PatchContext(ctx context.Context, to *Tree) (*Patch, error) { - changes, err := DiffTreeContext(ctx, from, to) +// PatchContext returns a slice of Patch objects with all the changes between +// trees in chunks. This representation can be used to create several diff +// outputs. If context expires, an error will be returned. Provided context must +// be non-nil. +// +// NOTE: Since version 5.1.0 the renames are correctly handled, the settings +// used are the recommended options DefaultDiffTreeOptions. +func (t *Tree) PatchContext(ctx context.Context, to *Tree) (*Patch, error) { + changes, err := t.DiffContext(ctx, to) if err != nil { return nil, err } diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/treenoder.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/treenoder.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/object/treenoder.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/object/treenoder.go index b4891b957..ef335b461 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/treenoder.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/object/treenoder.go @@ -3,9 +3,9 @@ package object import ( "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/filemode" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) // A treenoder is a helper type that wraps git trees into merkletrie diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs.go similarity index 92% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs.go index ab286c638..fde411051 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs.go @@ -5,10 +5,10 @@ import ( "sort" "strings" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/storage/memory" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/storage/memory" ) // AdvRefs values represent the information transmitted on an @@ -201,3 +201,11 @@ func (a *AdvRefs) addSymbolicRefs(s storer.ReferenceStorer) error { func (a *AdvRefs) supportSymrefs() bool { return a.Capabilities.Supports(capability.SymRef) } + +// IsEmpty returns true if doesn't contain any reference. +func (a *AdvRefs) IsEmpty() bool { + return a.Head == nil && + len(a.References) == 0 && + len(a.Peeled) == 0 && + len(a.Shallows) == 0 +} diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_decode.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs_decode.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_decode.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs_decode.go index 63bbe5ab1..20999a07a 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_decode.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs_decode.go @@ -7,8 +7,8 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) // Decode reads the next advertised-refs message form its input and diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_encode.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs_encode.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_encode.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs_encode.go index fb9bd883f..9de6f8e05 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_encode.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/advrefs_encode.go @@ -6,9 +6,9 @@ import ( "io" "sort" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" ) // Encode writes the AdvRefs encoding to a writer. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability/capability.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability/capability.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/list.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability/list.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/list.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability/list.go index 96092112d..f41ec799c 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/list.go +++ b/vendor/github.com/jesseduffield/go-git/v5/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/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/common.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/common.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/report_status.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/report_status.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/report_status.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/report_status.go index e2a0a108b..a96658ad1 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/report_status.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/report_status.go @@ -6,8 +6,8 @@ import ( "io" "strings" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) const ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/shallowupd.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/shallowupd.go similarity index 93% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/shallowupd.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/shallowupd.go index fe4fe6887..af6ba69c7 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/shallowupd.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/shallowupd.go @@ -5,8 +5,8 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) const ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/common.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/common.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/demux.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/demux.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/demux.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/demux.go index 0116f962e..4fcc4c3e4 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/demux.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/demux.go @@ -5,7 +5,7 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) // ErrMaxPackedExceeded returned by Read, if the maximum packed size is exceeded diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/muxer.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/muxer.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/muxer.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/muxer.go index d51ac8269..5c9f851b0 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/muxer.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband/muxer.go @@ -3,7 +3,7 @@ package sideband import ( "io" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) // Muxer multiplex the packfile along with the progress messages and the error diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/srvresp.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/srvresp.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/srvresp.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/srvresp.go index b3a7ee804..611c32a3d 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/srvresp.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/srvresp.go @@ -7,8 +7,8 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) const ackLineLen = 44 diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq.go similarity index 80% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq.go index 44db8e401..3ede75fef 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq.go @@ -4,8 +4,8 @@ import ( "fmt" "time" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" ) // UploadRequest values represent the information transmitted on a @@ -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/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_decode.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq_decode.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_decode.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq_decode.go index 449b729a5..e87f6e664 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_decode.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq_decode.go @@ -8,15 +8,15 @@ import ( "strconv" "time" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) // 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/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_encode.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq_encode.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_encode.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq_encode.go index 486307688..abbf4f642 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_encode.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/ulreq_encode.go @@ -6,8 +6,8 @@ import ( "io" "time" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) // Encode writes the UlReq encoding of u to the stream. @@ -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/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq.go similarity index 88% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq.go index b63b02340..32fd53e5d 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq.go @@ -4,9 +4,9 @@ import ( "errors" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband" ) var ( @@ -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/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_decode.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq_decode.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_decode.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq_decode.go index 2c9843a56..4d4743f37 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_decode.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq_decode.go @@ -8,8 +8,8 @@ import ( "io" "io/ioutil" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_encode.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq_encode.go similarity index 55% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_encode.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq_encode.go index 6a79653f1..36721b236 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_encode.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/updreq_encode.go @@ -4,9 +4,9 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" ) var ( @@ -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/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackreq.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/uppackreq.go similarity index 92% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackreq.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/uppackreq.go index de2206b3f..d6abe0697 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackreq.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/uppackreq.go @@ -5,9 +5,9 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" ) // UploadPackRequest represents a upload-pack request. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackresp.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/uppackresp.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackresp.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/uppackresp.go index a9a7192ea..9d0b1339e 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackresp.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/uppackresp.go @@ -6,8 +6,8 @@ import ( "bufio" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // ErrUploadPackResponseNotDecoded is returned if Read is called without diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/reference.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/reference.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/reference.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/reference.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/revision.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/revision.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/revision.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/revision.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/revlist/revlist.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/revlist/revlist.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/revlist/revlist.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/revlist/revlist.go index b9109870f..99600f539 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/revlist/revlist.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/revlist/revlist.go @@ -6,10 +6,10 @@ import ( "fmt" "io" - "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/object" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) // Objects applies a complementary set. It gets all the hashes from all diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/doc.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/storer/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/index.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/index.go similarity index 70% rename from vendor/github.com/go-git/go-git/v5/plumbing/storer/index.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/index.go index 33113949b..0cb5287d6 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/storer/index.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/index.go @@ -1,6 +1,6 @@ package storer -import "github.com/go-git/go-git/v5/plumbing/format/index" +import "github.com/jesseduffield/go-git/v5/plumbing/format/index" // IndexStorer generic storage of index.Index type IndexStorer interface { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/object.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/object.go similarity index 99% rename from vendor/github.com/go-git/go-git/v5/plumbing/storer/object.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/object.go index dfe309db1..22b1064fb 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/storer/object.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/object.go @@ -5,7 +5,7 @@ import ( "io" "time" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/reference.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/reference.go similarity index 99% rename from vendor/github.com/go-git/go-git/v5/plumbing/storer/reference.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/reference.go index 1d74ef3c6..3d0699d77 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/storer/reference.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/reference.go @@ -4,7 +4,7 @@ import ( "errors" "io" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) const MaxResolveRecursion = 1024 diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/shallow.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/shallow.go similarity index 83% rename from vendor/github.com/go-git/go-git/v5/plumbing/storer/shallow.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/shallow.go index 39ef5ea5c..409ae4d62 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/storer/shallow.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/shallow.go @@ -1,6 +1,6 @@ package storer -import "github.com/go-git/go-git/v5/plumbing" +import "github.com/jesseduffield/go-git/v5/plumbing" // ShallowStorer is a storage of references to shallow commits by hash, // meaning that these commits have missing parents because of a shallow fetch. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/storer.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/storer.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/plumbing/storer/storer.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/storer/storer.go diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/client/client.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/client/client.go similarity index 78% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/client/client.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/client/client.go index 4f6d210e9..f56d988b5 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/client/client.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/client/client.go @@ -5,11 +5,11 @@ package client import ( "fmt" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/file" - "github.com/go-git/go-git/v5/plumbing/transport/git" - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport/file" + "github.com/jesseduffield/go-git/v5/plumbing/transport/git" + "github.com/jesseduffield/go-git/v5/plumbing/transport/http" + "github.com/jesseduffield/go-git/v5/plumbing/transport/ssh" ) // Protocols are the protocols supported by default. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/common.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/common.go index ead215557..8eed74c98 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/common.go @@ -22,10 +22,10 @@ import ( "strconv" "strings" - giturl "github.com/go-git/go-git/v5/internal/url" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/protocol/packp" - "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" + giturl "github.com/jesseduffield/go-git/v5/internal/url" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" ) var ( diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/client.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/file/client.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/file/client.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/file/client.go index f6e23652a..954a40aca 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/client.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/file/client.go @@ -10,8 +10,8 @@ import ( "path/filepath" "strings" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/internal/common" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common" ) // DefaultClient is the default local client. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/server.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/file/server.go similarity index 83% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/file/server.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/file/server.go index b45d7a71c..79ea016fb 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/server.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/file/server.go @@ -4,10 +4,10 @@ import ( "fmt" "os" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/internal/common" - "github.com/go-git/go-git/v5/plumbing/transport/server" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common" + "github.com/jesseduffield/go-git/v5/plumbing/transport/server" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // ServeUploadPack serves a git-upload-pack request using standard output, input diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/git/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/git/common.go similarity index 90% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/git/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/git/common.go index 306aae261..7e9fc676b 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/git/common.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/git/common.go @@ -6,10 +6,10 @@ import ( "io" "net" - "github.com/go-git/go-git/v5/plumbing/format/pktline" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/internal/common" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // DefaultClient is the default git client. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/common.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/common.go index aeedc5bb5..06833c4e7 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/common.go @@ -9,10 +9,10 @@ import ( "strconv" "strings" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/protocol/packp" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // it requires a bytes.Buffer, because we need to know the length diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/receive_pack.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/receive_pack.go similarity index 85% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/http/receive_pack.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/receive_pack.go index 433dfcfda..72bd13749 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/receive_pack.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/receive_pack.go @@ -7,12 +7,12 @@ import ( "io" "net/http" - "github.com/go-git/go-git/v5/plumbing" - "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/protocol/packp/sideband" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) type rpSession struct { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/upload_pack.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/upload_pack.go similarity index 87% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/http/upload_pack.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/upload_pack.go index db3708940..b47e1d839 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/upload_pack.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/http/upload_pack.go @@ -7,12 +7,12 @@ import ( "io" "net/http" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/pktline" - "github.com/go-git/go-git/v5/plumbing/protocol/packp" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/internal/common" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) type upSession struct { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common/common.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common/common.go index d564d25a6..829e320c1 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common/common.go @@ -15,12 +15,12 @@ import ( "strings" "time" - "github.com/go-git/go-git/v5/plumbing/format/pktline" - "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/protocol/packp/sideband" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/format/pktline" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) const ( @@ -175,6 +175,13 @@ func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) { } } + // Some servers like jGit, announce capabilities instead of returning an + // packp message with a flush. This verifies that we received a empty + // adv-refs, even it contains capabilities. + if !s.isReceivePack && ar.IsEmpty() { + return nil, transport.ErrEmptyRemoteRepository + } + transport.FilterUnsupportedCapabilities(ar.Capabilities) s.advRefs = ar return ar, nil diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/server.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common/server.go similarity index 89% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/server.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common/server.go index e2480848a..1f8dd2404 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/server.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common/server.go @@ -5,9 +5,9 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/plumbing/protocol/packp" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // ServerCommand is used for a single server command execution. diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/loader.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/server/loader.go similarity index 88% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/server/loader.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/server/loader.go index e7e2b075e..0d9afd5ba 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/loader.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/server/loader.go @@ -1,10 +1,10 @@ package server import ( - "github.com/go-git/go-git/v5/plumbing/cache" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/storage/filesystem" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/storage/filesystem" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/server.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/server/server.go similarity index 92% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/server/server.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/server/server.go index 71845e3bb..824d76afd 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/server.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/server/server.go @@ -8,14 +8,14 @@ import ( "fmt" "io" - "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/revlist" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/packfile" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing/revlist" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) var DefaultServer = NewServer(DefaultLoader) @@ -243,11 +243,13 @@ func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateR //TODO: Implement 'atomic' update of references. - r := ioutil.NewContextReadCloser(ctx, req.Packfile) - if err := s.writePackfile(r); err != nil { - s.unpackErr = err - s.firstErr = err - return s.reportStatus(), err + if req.Packfile != nil { + r := ioutil.NewContextReadCloser(ctx, req.Packfile) + if err := s.writePackfile(r); err != nil { + s.unpackErr = err + s.firstErr = err + return s.reportStatus(), err + } } s.updateReferences(req) diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/ssh/auth_method.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/ssh/auth_method.go index b79a74e41..5b7533e69 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/ssh/auth_method.go @@ -10,10 +10,10 @@ import ( "os/user" "path/filepath" - "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport" "github.com/mitchellh/go-homedir" - "github.com/xanzy/ssh-agent" + sshagent "github.com/xanzy/ssh-agent" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/knownhosts" ) diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/ssh/common.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go rename to vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/ssh/common.go index c05ded986..00d41b57c 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go +++ b/vendor/github.com/jesseduffield/go-git/v5/plumbing/transport/ssh/common.go @@ -7,8 +7,8 @@ import ( "reflect" "strconv" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/internal/common" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common" "github.com/kevinburke/ssh_config" "golang.org/x/crypto/ssh" diff --git a/vendor/github.com/go-git/go-git/v5/prune.go b/vendor/github.com/jesseduffield/go-git/v5/prune.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/prune.go rename to vendor/github.com/jesseduffield/go-git/v5/prune.go index cc5907a14..e4434838c 100644 --- a/vendor/github.com/go-git/go-git/v5/prune.go +++ b/vendor/github.com/jesseduffield/go-git/v5/prune.go @@ -4,8 +4,8 @@ import ( "errors" "time" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) type PruneHandler func(unreferencedObjectHash plumbing.Hash) error diff --git a/vendor/github.com/go-git/go-git/v5/references.go b/vendor/github.com/jesseduffield/go-git/v5/references.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/references.go rename to vendor/github.com/jesseduffield/go-git/v5/references.go index 6d96035af..ab44ef7ea 100644 --- a/vendor/github.com/go-git/go-git/v5/references.go +++ b/vendor/github.com/jesseduffield/go-git/v5/references.go @@ -4,9 +4,9 @@ import ( "io" "sort" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/utils/diff" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/utils/diff" "github.com/sergi/go-diff/diffmatchpatch" ) diff --git a/vendor/github.com/go-git/go-git/v5/remote.go b/vendor/github.com/jesseduffield/go-git/v5/remote.go similarity index 91% rename from vendor/github.com/go-git/go-git/v5/remote.go rename to vendor/github.com/jesseduffield/go-git/v5/remote.go index 242df0d44..05aa0e030 100644 --- a/vendor/github.com/go-git/go-git/v5/remote.go +++ b/vendor/github.com/jesseduffield/go-git/v5/remote.go @@ -7,28 +7,29 @@ import ( "io" "github.com/go-git/go-billy/v5/osfs" - "github.com/go-git/go-git/v5/config" - "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/packfile" - "github.com/go-git/go-git/v5/plumbing/object" - "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/protocol/packp/sideband" - "github.com/go-git/go-git/v5/plumbing/revlist" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/client" - "github.com/go-git/go-git/v5/storage" - "github.com/go-git/go-git/v5/storage/filesystem" - "github.com/go-git/go-git/v5/storage/memory" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/plumbing/format/packfile" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability" + "github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband" + "github.com/jesseduffield/go-git/v5/plumbing/revlist" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/plumbing/transport" + "github.com/jesseduffield/go-git/v5/plumbing/transport/client" + "github.com/jesseduffield/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/storage/filesystem" + "github.com/jesseduffield/go-git/v5/storage/memory" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) var ( NoErrAlreadyUpToDate = errors.New("already up-to-date") ErrDeleteRefNotSupported = errors.New("server does not support delete-refs") ErrForceNeeded = errors.New("some refs were not updated") + ErrExactSHA1NotSupported = errors.New("server does not support exact SHA1 refspec") ) const ( @@ -122,6 +123,15 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) { return ErrDeleteRefNotSupported } + if o.Force { + for i := 0; i < len(o.RefSpecs); i++ { + rs := &o.RefSpecs[i] + if !rs.IsForceUpdate() { + o.RefSpecs[i] = config.RefSpec("+" + rs.String()) + } + } + } + localRefs, err := r.references() if err != nil { return err @@ -208,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) } } @@ -303,6 +313,10 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen return nil, err } + if err := r.isSupportedRefSpec(o.RefSpecs, ar); err != nil { + return nil, err + } + remoteRefs, err := ar.AllReferences() if err != nil { return nil, err @@ -484,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{ @@ -546,6 +558,7 @@ func (r *Remote) addReferenceIfRefSpecMatches(rs config.RefSpec, func (r *Remote) references() ([]*plumbing.Reference, error) { var localRefs []*plumbing.Reference + iter, err := r.s.IterReferences() if err != nil { return nil, err @@ -701,6 +714,11 @@ func doCalculateRefs( return err } + if s.IsExactSHA1() { + ref := plumbing.NewHashReference(s.Dst(""), plumbing.NewHash(s.Src())) + return refs.SetReference(ref) + } + var matched bool err = iter.ForEach(func(ref *plumbing.Reference) error { if !s.Match(ref.Name()) { @@ -850,6 +868,26 @@ func (r *Remote) newUploadPackRequest(o *FetchOptions, return req, nil } +func (r *Remote) isSupportedRefSpec(refs []config.RefSpec, ar *packp.AdvRefs) error { + var containsIsExact bool + for _, ref := range refs { + if ref.IsExactSHA1() { + containsIsExact = true + } + } + + if !containsIsExact { + return nil + } + + if ar.Capabilities.Supports(capability.AllowReachableSHA1InWant) || + ar.Capabilities.Supports(capability.AllowTipSHA1InWant) { + return nil + } + + return ErrExactSHA1NotSupported +} + func buildSidebandIfSupported(l *capability.List, reader io.Reader, p sideband.Progress) io.Reader { var t sideband.Type @@ -883,7 +921,7 @@ func (r *Remote) updateLocalReferenceStorage( } for _, ref := range fetchedRefs { - if !spec.Match(ref.Name()) { + if !spec.Match(ref.Name()) && !spec.IsExactSHA1() { continue } @@ -997,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/vendor/github.com/go-git/go-git/v5/repository.go b/vendor/github.com/jesseduffield/go-git/v5/repository.go similarity index 87% rename from vendor/github.com/go-git/go-git/v5/repository.go rename to vendor/github.com/jesseduffield/go-git/v5/repository.go index c83a13603..23b74f0a3 100644 --- a/vendor/github.com/go-git/go-git/v5/repository.go +++ b/vendor/github.com/jesseduffield/go-git/v5/repository.go @@ -3,6 +3,7 @@ package git import ( "bytes" "context" + "encoding/hex" "errors" "fmt" "io" @@ -13,17 +14,20 @@ import ( "strings" "time" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" + + "github.com/imdario/mergo" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/internal/revision" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/plumbing/format/packfile" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/storage/filesystem" + "github.com/jesseduffield/go-git/v5/utils/ioutil" "golang.org/x/crypto/openpgp" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/internal/revision" - "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/packfile" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/storage" - "github.com/go-git/go-git/v5/storage/filesystem" - "github.com/go-git/go-git/v5/utils/ioutil" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" @@ -46,6 +50,7 @@ var ( ErrInvalidReference = errors.New("invalid reference, should be a tag or a branch") ErrRepositoryNotExists = errors.New("repository does not exist") + ErrRepositoryIncomplete = errors.New("repository's commondir path does not exist") ErrRepositoryAlreadyExists = errors.New("repository already exists") ErrRemoteNotFound = errors.New("remote not found") ErrRemoteExists = errors.New("remote already exists") @@ -88,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 } @@ -155,7 +160,7 @@ func setConfigWorktree(r *Repository, worktree, storage billy.Filesystem) error return nil } - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return err } @@ -252,7 +257,19 @@ func PlainOpenWithOptions(path string, o *PlainOpenOptions) (*Repository, error) return nil, err } - s := filesystem.NewStorage(dot, cache.NewObjectLRUDefault()) + var repositoryFs billy.Filesystem + + if o.EnableDotGitCommonDir { + dotGitCommon, err := dotGitCommonDirectory(dot) + if err != nil { + return nil, err + } + repositoryFs = dotgit.NewRepositoryFilesystem(dot, dotGitCommon) + } else { + repositoryFs = dot + } + + s := filesystem.NewStorage(repositoryFs, cache.NewObjectLRUDefault()) return Open(s, wt) } @@ -327,6 +344,38 @@ func dotGitFileToOSFilesystem(path string, fs billy.Filesystem) (bfs billy.Files return osfs.New(fs.Join(path, gitdir)), nil } +func dotGitCommonDirectory(fs billy.Filesystem) (commonDir billy.Filesystem, err error) { + f, err := fs.Open("commondir") + if os.IsNotExist(err) { + return nil, nil + } + if err != nil { + return nil, err + } + + b, err := stdioutil.ReadAll(f) + if err != nil { + return nil, err + } + if len(b) > 0 { + path := strings.TrimSpace(string(b)) + if filepath.IsAbs(path) { + commonDir = osfs.New(path) + } else { + commonDir = osfs.New(filepath.Join(fs.Root(), path)) + } + if _, err := commonDir.Stat(""); err != nil { + if os.IsNotExist(err) { + return nil, ErrRepositoryIncomplete + } + + return nil, err + } + } + + return commonDir, nil +} + // PlainClone a repository into the path with the given options, isBare defines // if the new repository will be bare or normal. If the path is not empty // ErrRepositoryAlreadyExists is returned. @@ -360,7 +409,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) } } @@ -434,14 +483,56 @@ func cleanUpDir(path string, all bool) error { return err } -// Config return the repository config +// Config return the repository config. In a filesystem backed repository this +// means read the `.git/config`. func (r *Repository) Config() (*config.Config, error) { return r.Storer.Config() } +// SetConfig marshall and writes the repository config. In a filesystem backed +// repository this means write the `.git/config`. This function should be called +// with the result of `Repository.Config` and never with the output of +// `Repository.ConfigScoped`. +func (r *Repository) SetConfig(cfg *config.Config) error { + return r.Storer.SetConfig(cfg) +} + +// ConfigScoped returns the repository config, merged with requested scope and +// lower. For example if, config.GlobalScope is given the local and global config +// are returned merged in one config value. +func (r *Repository) ConfigScoped(scope config.Scope) (*config.Config, error) { + // TODO(mcuadros): v6, add this as ConfigOptions.Scoped + + var err error + system := config.NewConfig() + if scope >= config.SystemScope { + system, err = config.LoadConfig(config.SystemScope) + if err != nil { + return nil, err + } + } + + global := config.NewConfig() + if scope >= config.GlobalScope { + global, err = config.LoadConfig(config.GlobalScope) + if err != nil { + return nil, err + } + } + + local, err := r.Storer.Config() + if err != nil { + return nil, err + } + + _ = mergo.Merge(global, system) + _ = mergo.Merge(local, global) + return local, nil +} + // Remote return a remote if exists func (r *Repository) Remote(name string) (*Remote, error) { - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return nil, err } @@ -456,7 +547,7 @@ func (r *Repository) Remote(name string) (*Remote, error) { // Remotes returns a list with all the remotes func (r *Repository) Remotes() ([]*Remote, error) { - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return nil, err } @@ -480,7 +571,7 @@ func (r *Repository) CreateRemote(c *config.RemoteConfig) (*Remote, error) { remote := NewRemote(r.Storer, c) - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return nil, err } @@ -511,7 +602,7 @@ func (r *Repository) CreateRemoteAnonymous(c *config.RemoteConfig) (*Remote, err // DeleteRemote delete a remote from the repository and delete the config func (r *Repository) DeleteRemote(name string) error { - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return err } @@ -526,7 +617,7 @@ func (r *Repository) DeleteRemote(name string) error { // Branch return a Branch if exists func (r *Repository) Branch(name string) (*config.Branch, error) { - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return nil, err } @@ -545,7 +636,7 @@ func (r *Repository) CreateBranch(c *config.Branch) error { return err } - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return err } @@ -560,7 +651,7 @@ func (r *Repository) CreateBranch(c *config.Branch) error { // DeleteBranch delete a Branch from the repository and delete the config func (r *Repository) DeleteBranch(name string) error { - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return err } @@ -835,7 +926,7 @@ func (r *Repository) cloneRefSpec(o *CloneOptions) []config.RefSpec { } func (r *Repository) setIsBare(isBare bool) error { - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return err } @@ -851,7 +942,7 @@ func (r *Repository) updateRemoteConfigIfNeeded(o *CloneOptions, c *config.Remot c.Fetch = r.cloneRefSpec(o) - cfg, err := r.Storer.Config() + cfg, err := r.Config() if err != nil { return err } @@ -1336,7 +1427,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)) @@ -1349,17 +1440,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))) @@ -1404,7 +1491,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 @@ -1432,7 +1519,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 { @@ -1444,8 +1531,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 @@ -1477,6 +1564,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. @@ -1541,7 +1671,7 @@ func (r *Repository) createNewObjectPack(cfg *RepackConfig) (h plumbing.Hash, er return h, err } defer ioutil.CheckClose(wc, &err) - scfg, err := r.Storer.Config() + scfg, err := r.Config() if err != nil { return h, err } @@ -1569,3 +1699,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/vendor/github.com/go-git/go-git/v5/status.go b/vendor/github.com/jesseduffield/go-git/v5/status.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/status.go rename to vendor/github.com/jesseduffield/go-git/v5/status.go diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/config.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/config.go similarity index 62% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/config.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/config.go index 01b35b4e3..fa28d5af8 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/config.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/config.go @@ -1,12 +1,11 @@ package filesystem import ( - stdioutil "io/ioutil" "os" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/storage/filesystem/dotgit" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) type ConfigStorage struct { @@ -14,29 +13,17 @@ type ConfigStorage struct { } func (c *ConfigStorage) Config() (conf *config.Config, err error) { - cfg := config.NewConfig() - f, err := c.dir.Config() if err != nil { if os.IsNotExist(err) { - return cfg, nil + return config.NewConfig(), nil } return nil, err } defer ioutil.CheckClose(f, &err) - - b, err := stdioutil.ReadAll(f) - if err != nil { - return nil, err - } - - if err = cfg.Unmarshal(b); err != nil { - return nil, err - } - - return cfg, err + return config.ReadConfig(f) } func (c *ConfigStorage) SetConfig(cfg *config.Config) (err error) { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/deltaobject.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/deltaobject.go similarity index 92% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/deltaobject.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/deltaobject.go index 6ab2cdf38..65bf0d5e7 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/deltaobject.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/deltaobject.go @@ -1,7 +1,7 @@ package filesystem import ( - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) type deltaObject struct { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit.go similarity index 90% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit.go index 3ce9daeda..c92e5fa6a 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit.go @@ -3,19 +3,21 @@ package dotgit import ( "bufio" + "bytes" "errors" "fmt" "io" stdioutil "io/ioutil" "os" "path/filepath" + "sort" "strings" "time" "github.com/go-git/go-billy/v5/osfs" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/storage" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/utils/ioutil" "github.com/go-git/go-billy/v5" ) @@ -30,6 +32,12 @@ const ( objectsPath = "objects" packPath = "pack" refsPath = "refs" + branchesPath = "branches" + hooksPath = "hooks" + infoPath = "info" + remotesPath = "remotes" + logsPath = "logs" + worktreesPath = "worktrees" tmpPackedRefsPrefix = "._packed-refs" @@ -57,6 +65,9 @@ var ( // targeting a non-existing object. This usually means the repository // is corrupt. ErrSymRefTargetNotFound = errors.New("symbolic reference target not found") + // ErrIsDir is returned when a reference file is attempting to be read, + // but the path specified is a directory. + ErrIsDir = errors.New("reference path is a directory") ) // Options holds configuration for the storage. @@ -79,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{} @@ -327,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) { @@ -418,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 { @@ -926,6 +989,14 @@ func (d *DotGit) addRefFromHEAD(refs *[]*plumbing.Reference) error { func (d *DotGit) readReferenceFile(path, name string) (ref *plumbing.Reference, err error) { path = d.fs.Join(path, d.fs.Join(strings.Split(name, "/")...)) + st, err := d.fs.Stat(path) + if err != nil { + return nil, err + } + if st.IsDir() { + return nil, ErrIsDir + } + f, err := d.fs.Open(path) if err != nil { return nil, err @@ -1098,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/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go index 43263eadf..d0ee2f3d9 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go @@ -6,7 +6,7 @@ import ( "runtime" "github.com/go-git/go-billy/v5" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) func (d *DotGit) openAndLockPackedRefsMode() int { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go index c057f5c48..31a81dddb 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go @@ -4,8 +4,8 @@ import ( "fmt" "os" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/utils/ioutil" "github.com/go-git/go-billy/v5" ) diff --git a/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/repository_filesystem.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/repository_filesystem.go new file mode 100644 index 000000000..8d243efea --- /dev/null +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/repository_filesystem.go @@ -0,0 +1,111 @@ +package dotgit + +import ( + "os" + "path/filepath" + "strings" + + "github.com/go-git/go-billy/v5" +) + +// RepositoryFilesystem is a billy.Filesystem compatible object wrapper +// which handles dot-git filesystem operations and supports commondir according to git scm layout: +// https://github.com/git/git/blob/master/Documentation/gitrepository-layout.txt +type RepositoryFilesystem struct { + dotGitFs billy.Filesystem + commonDotGitFs billy.Filesystem +} + +func NewRepositoryFilesystem(dotGitFs, commonDotGitFs billy.Filesystem) *RepositoryFilesystem { + return &RepositoryFilesystem{ + dotGitFs: dotGitFs, + commonDotGitFs: commonDotGitFs, + } +} + +func (fs *RepositoryFilesystem) mapToRepositoryFsByPath(path string) billy.Filesystem { + // Nothing to decide if commondir not defined + if fs.commonDotGitFs == nil { + return fs.dotGitFs + } + + cleanPath := filepath.Clean(path) + + // Check exceptions for commondir (https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt) + switch cleanPath { + case fs.dotGitFs.Join(logsPath, "HEAD"): + return fs.dotGitFs + case fs.dotGitFs.Join(refsPath, "bisect"), fs.dotGitFs.Join(refsPath, "rewritten"), fs.dotGitFs.Join(refsPath, "worktree"): + return fs.dotGitFs + } + + // Determine dot-git root by first path element. + // There are some elements which should always use commondir when commondir defined. + // Usual dot-git root will be used for the rest of files. + switch strings.Split(cleanPath, string(filepath.Separator))[0] { + case objectsPath, refsPath, packedRefsPath, configPath, branchesPath, hooksPath, infoPath, remotesPath, logsPath, shallowPath, worktreesPath: + return fs.commonDotGitFs + default: + return fs.dotGitFs + } +} + +func (fs *RepositoryFilesystem) Create(filename string) (billy.File, error) { + return fs.mapToRepositoryFsByPath(filename).Create(filename) +} + +func (fs *RepositoryFilesystem) Open(filename string) (billy.File, error) { + return fs.mapToRepositoryFsByPath(filename).Open(filename) +} + +func (fs *RepositoryFilesystem) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) { + return fs.mapToRepositoryFsByPath(filename).OpenFile(filename, flag, perm) +} + +func (fs *RepositoryFilesystem) Stat(filename string) (os.FileInfo, error) { + return fs.mapToRepositoryFsByPath(filename).Stat(filename) +} + +func (fs *RepositoryFilesystem) Rename(oldpath, newpath string) error { + return fs.mapToRepositoryFsByPath(oldpath).Rename(oldpath, newpath) +} + +func (fs *RepositoryFilesystem) Remove(filename string) error { + return fs.mapToRepositoryFsByPath(filename).Remove(filename) +} + +func (fs *RepositoryFilesystem) Join(elem ...string) string { + return fs.dotGitFs.Join(elem...) +} + +func (fs *RepositoryFilesystem) TempFile(dir, prefix string) (billy.File, error) { + return fs.mapToRepositoryFsByPath(dir).TempFile(dir, prefix) +} + +func (fs *RepositoryFilesystem) ReadDir(path string) ([]os.FileInfo, error) { + return fs.mapToRepositoryFsByPath(path).ReadDir(path) +} + +func (fs *RepositoryFilesystem) MkdirAll(filename string, perm os.FileMode) error { + return fs.mapToRepositoryFsByPath(filename).MkdirAll(filename, perm) +} + +func (fs *RepositoryFilesystem) Lstat(filename string) (os.FileInfo, error) { + return fs.mapToRepositoryFsByPath(filename).Lstat(filename) +} + +func (fs *RepositoryFilesystem) Symlink(target, link string) error { + return fs.mapToRepositoryFsByPath(target).Symlink(target, link) +} + +func (fs *RepositoryFilesystem) Readlink(link string) (string, error) { + return fs.mapToRepositoryFsByPath(link).Readlink(link) +} + +func (fs *RepositoryFilesystem) Chroot(path string) (billy.Filesystem, error) { + return fs.mapToRepositoryFsByPath(path).Chroot(path) +} + +func (fs *RepositoryFilesystem) Root() string { + return fs.dotGitFs.Root() +} diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/writers.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/writers.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/writers.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/writers.go index e2ede938c..a90fb5861 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/writers.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit/writers.go @@ -5,10 +5,10 @@ import ( "io" "sync/atomic" - "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/plumbing/format/objfile" - "github.com/go-git/go-git/v5/plumbing/format/packfile" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/idxfile" + "github.com/jesseduffield/go-git/v5/plumbing/format/objfile" + "github.com/jesseduffield/go-git/v5/plumbing/format/packfile" "github.com/go-git/go-billy/v5" ) diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/index.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/index.go similarity index 81% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/index.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/index.go index a19176f83..b20ebb918 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/index.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/index.go @@ -4,9 +4,9 @@ import ( "bufio" "os" - "github.com/go-git/go-git/v5/plumbing/format/index" - "github.com/go-git/go-git/v5/storage/filesystem/dotgit" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) type IndexStorage struct { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/module.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/module.go similarity index 63% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/module.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/module.go index 20336c118..77de7dbab 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/module.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/module.go @@ -1,9 +1,9 @@ package filesystem import ( - "github.com/go-git/go-git/v5/plumbing/cache" - "github.com/go-git/go-git/v5/storage" - "github.com/go-git/go-git/v5/storage/filesystem/dotgit" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" ) type ModuleStorage struct { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/object.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/object.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/object.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/object.go index 862cc1b1a..e0c272b3c 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/object.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/object.go @@ -1,18 +1,19 @@ package filesystem import ( + "bytes" "io" "os" "time" - "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" - "github.com/go-git/go-git/v5/plumbing/format/objfile" - "github.com/go-git/go-git/v5/plumbing/format/packfile" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/storage/filesystem/dotgit" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/plumbing/format/idxfile" + "github.com/jesseduffield/go-git/v5/plumbing/format/objfile" + "github.com/jesseduffield/go-git/v5/plumbing/format/packfile" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" + "github.com/jesseduffield/go-git/v5/utils/ioutil" "github.com/go-git/go-billy/v5" ) @@ -408,6 +409,8 @@ func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedOb return nil, err } + defer ioutil.CheckClose(w, &err) + s.objectCache.Put(obj) _, err = io.Copy(w, r) @@ -516,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/vendor/github.com/go-git/go-git/v5/storage/filesystem/reference.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/reference.go similarity index 84% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/reference.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/reference.go index aabcd7308..d6a79fce5 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/reference.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/reference.go @@ -1,9 +1,9 @@ package filesystem import ( - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/storage/filesystem/dotgit" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" ) type ReferenceStorage struct { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/shallow.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/shallow.go similarity index 86% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/shallow.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/shallow.go index afb600cf2..7c82b2173 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/shallow.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/shallow.go @@ -4,9 +4,9 @@ import ( "bufio" "fmt" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/storage/filesystem/dotgit" - "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" + "github.com/jesseduffield/go-git/v5/utils/ioutil" ) // ShallowStorage where the shallow commits are stored, an internal to diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/storage.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/storage.go index 8b69b27b0..056ca9013 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/filesystem/storage.go @@ -2,8 +2,8 @@ package filesystem import ( - "github.com/go-git/go-git/v5/plumbing/cache" - "github.com/go-git/go-git/v5/storage/filesystem/dotgit" + "github.com/jesseduffield/go-git/v5/plumbing/cache" + "github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit" "github.com/go-git/go-billy/v5" ) diff --git a/vendor/github.com/go-git/go-git/v5/storage/memory/storage.go b/vendor/github.com/jesseduffield/go-git/v5/storage/memory/storage.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/storage/memory/storage.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/memory/storage.go index fdf8fcfc6..1083d65b6 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/memory/storage.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/memory/storage.go @@ -5,11 +5,11 @@ import ( "fmt" "time" - "github.com/go-git/go-git/v5/config" - "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/plumbing/storer" - "github.com/go-git/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/storage" ) var ErrUnsupportedObjectType = fmt.Errorf("unsupported object type") @@ -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/vendor/github.com/go-git/go-git/v5/storage/storer.go b/vendor/github.com/jesseduffield/go-git/v5/storage/storer.go similarity index 78% rename from vendor/github.com/go-git/go-git/v5/storage/storer.go rename to vendor/github.com/jesseduffield/go-git/v5/storage/storer.go index 4800ac7ba..643592e0c 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/storer.go +++ b/vendor/github.com/jesseduffield/go-git/v5/storage/storer.go @@ -3,14 +3,14 @@ package storage import ( "errors" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/plumbing/storer" ) var ErrReferenceHasChanged = errors.New("reference has changed concurrently") // Storer is a generic storage of objects, references and any information -// related to a particular repository. The package github.com/go-git/go-git/v5/storage +// related to a particular repository. The package github.com/jesseduffield/go-git/v5/storage // contains two implementation a filesystem base implementation (such as `.git`) // and a memory implementations being ephemeral type Storer interface { diff --git a/vendor/github.com/go-git/go-git/v5/submodule.go b/vendor/github.com/jesseduffield/go-git/v5/submodule.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/submodule.go rename to vendor/github.com/jesseduffield/go-git/v5/submodule.go index 92ccdb1c8..03f7d1a2b 100644 --- a/vendor/github.com/go-git/go-git/v5/submodule.go +++ b/vendor/github.com/jesseduffield/go-git/v5/submodule.go @@ -7,9 +7,9 @@ import ( "fmt" "github.com/go-git/go-billy/v5" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" ) var ( @@ -35,7 +35,7 @@ func (s *Submodule) Config() *config.Submodule { // Init initialize the submodule reading the recorded Entry in the index for // the given submodule func (s *Submodule) Init() error { - cfg, err := s.w.r.Storer.Config() + cfg, err := s.w.r.Config() if err != nil { return err } diff --git a/vendor/github.com/go-git/go-git/v5/utils/binary/read.go b/vendor/github.com/jesseduffield/go-git/v5/utils/binary/read.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/utils/binary/read.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/binary/read.go index a14d48db9..15452b079 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/binary/read.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/binary/read.go @@ -7,7 +7,7 @@ import ( "encoding/binary" "io" - "github.com/go-git/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing" ) // Read reads structured binary data from r into data. Bytes are read and diff --git a/vendor/github.com/go-git/go-git/v5/utils/binary/write.go b/vendor/github.com/jesseduffield/go-git/v5/utils/binary/write.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/utils/binary/write.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/binary/write.go diff --git a/vendor/github.com/go-git/go-git/v5/utils/diff/diff.go b/vendor/github.com/jesseduffield/go-git/v5/utils/diff/diff.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/utils/diff/diff.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/diff/diff.go index 6142ed051..70054949f 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/diff/diff.go +++ b/vendor/github.com/jesseduffield/go-git/v5/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/vendor/github.com/go-git/go-git/v5/utils/ioutil/common.go b/vendor/github.com/jesseduffield/go-git/v5/utils/ioutil/common.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/utils/ioutil/common.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/ioutil/common.go diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/change.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/change.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/change.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/change.go index cc6dc8907..8d83cd297 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/change.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/change.go @@ -4,7 +4,7 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) // Action values represent the kind of things a Change can represent: diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/difftree.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/difftree.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/difftree.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/difftree.go index 90d9c958d..26c344dde 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/difftree.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/difftree.go @@ -23,7 +23,7 @@ package merkletrie // # Cases // -// When comparing noders in both trees you will found yourself in +// When comparing noders in both trees you will find yourself in // one of 169 possible cases, but if we ignore moves, we can // simplify a lot the search space into the following table: // @@ -252,21 +252,25 @@ import ( "errors" "fmt" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) var ( + // ErrCanceled is returned whenever the operation is canceled. ErrCanceled = errors.New("operation canceled") ) // DiffTree calculates the list of changes between two merkletries. It // uses the provided hashEqual callback to compare noders. -func DiffTree(fromTree, toTree noder.Noder, - hashEqual noder.Equal) (Changes, error) { +func DiffTree( + fromTree, + toTree noder.Noder, + hashEqual noder.Equal, +) (Changes, error) { return DiffTreeContext(context.Background(), fromTree, toTree, hashEqual) } -// DiffTree calculates the list of changes between two merkletries. It +// DiffTreeContext calculates the list of changes between two merkletries. It // uses the provided hashEqual callback to compare noders. // Error will be returned if context expires // Provided context must be non nil diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doc.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/doc.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/doc.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/doc.go diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doubleiter.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/doubleiter.go similarity index 98% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/doubleiter.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/doubleiter.go index 4a4341b38..2a6e6843d 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doubleiter.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/doubleiter.go @@ -4,7 +4,7 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) // A doubleIter is a convenience type to keep track of the current diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/filesystem/node.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem/node.go similarity index 95% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/filesystem/node.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem/node.go index 165bd42fc..96cf4fa53 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/filesystem/node.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem/node.go @@ -5,9 +5,9 @@ import ( "os" "path" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/filemode" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" "github.com/go-git/go-billy/v5" ) @@ -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/vendor/github.com/go-git/go-git/v5/utils/merkletrie/index/node.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/index/node.go similarity index 94% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/index/node.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/index/node.go index d05b0c694..bc8a8ba97 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/index/node.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/index/node.go @@ -4,8 +4,8 @@ import ( "path" "strings" - "github.com/go-git/go-git/v5/plumbing/format/index" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) // The node represents a index.Entry or a directory inferred from the path diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame/frame.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame/frame.go index 131878a1c..b24f97a55 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame/frame.go @@ -6,7 +6,7 @@ import ( "sort" "strings" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) // A Frame is a collection of siblings in a trie, sorted alphabetically diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/iter.go similarity index 97% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/iter.go index d75afec46..d8a4fbf39 100644 --- a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go +++ b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/iter.go @@ -4,8 +4,8 @@ import ( "fmt" "io" - "github.com/go-git/go-git/v5/utils/merkletrie/internal/frame" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) // Iter is an iterator for merkletries (only the trie part of the diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/noder.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/noder/noder.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/noder.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/noder/noder.go diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/path.go b/vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/noder/path.go similarity index 100% rename from vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/path.go rename to vendor/github.com/jesseduffield/go-git/v5/utils/merkletrie/noder/path.go diff --git a/vendor/github.com/go-git/go-git/v5/worktree.go b/vendor/github.com/jesseduffield/go-git/v5/worktree.go similarity index 96% rename from vendor/github.com/go-git/go-git/v5/worktree.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree.go index 7f394d484..a0d58c8e5 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree.go @@ -11,15 +11,15 @@ import ( "strings" "sync" - "github.com/go-git/go-git/v5/config" - "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/gitignore" - "github.com/go-git/go-git/v5/plumbing/format/index" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/go-git/go-git/v5/utils/ioutil" - "github.com/go-git/go-git/v5/utils/merkletrie" + "github.com/jesseduffield/go-git/v5/config" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing/format/gitignore" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/plumbing/storer" + "github.com/jesseduffield/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/utils/merkletrie" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/util" @@ -93,7 +93,12 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { head, err := w.r.Head() if err == nil { - if !updated && head.Hash() == ref.Hash() { + headAheadOfRef, err := isFastForward(w.r.Storer, ref.Hash(), head.Hash()) + if err != nil { + return err + } + + if !updated && headAheadOfRef { return NoErrAlreadyUpToDate } diff --git a/vendor/github.com/go-git/go-git/v5/worktree_bsd.go b/vendor/github.com/jesseduffield/go-git/v5/worktree_bsd.go similarity index 87% rename from vendor/github.com/go-git/go-git/v5/worktree_bsd.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree_bsd.go index d4ea32758..3ed1f2cbb 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree_bsd.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree_bsd.go @@ -6,7 +6,7 @@ import ( "syscall" "time" - "github.com/go-git/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" ) func init() { diff --git a/vendor/github.com/go-git/go-git/v5/worktree_commit.go b/vendor/github.com/jesseduffield/go-git/v5/worktree_commit.go similarity index 92% rename from vendor/github.com/go-git/go-git/v5/worktree_commit.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree_commit.go index 63eb2e867..7f0ba9b5f 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree_commit.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree_commit.go @@ -6,14 +6,14 @@ 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" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/storage" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/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 { diff --git a/vendor/github.com/go-git/go-git/v5/worktree_linux.go b/vendor/github.com/jesseduffield/go-git/v5/worktree_linux.go similarity index 87% rename from vendor/github.com/go-git/go-git/v5/worktree_linux.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree_linux.go index cf0db2524..4bf039cf3 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree_linux.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree_linux.go @@ -6,7 +6,7 @@ import ( "syscall" "time" - "github.com/go-git/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" ) func init() { diff --git a/vendor/github.com/go-git/go-git/v5/worktree_plan9.go b/vendor/github.com/jesseduffield/go-git/v5/worktree_plan9.go similarity index 89% rename from vendor/github.com/go-git/go-git/v5/worktree_plan9.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree_plan9.go index 8cedf71a3..7952a68e5 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree_plan9.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree_plan9.go @@ -4,7 +4,7 @@ import ( "syscall" "time" - "github.com/go-git/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" ) func init() { diff --git a/vendor/github.com/go-git/go-git/v5/worktree_status.go b/vendor/github.com/jesseduffield/go-git/v5/worktree_status.go similarity index 83% rename from vendor/github.com/go-git/go-git/v5/worktree_status.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree_status.go index 1542f5e6a..aa2543204 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree_status.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree_status.go @@ -7,18 +7,19 @@ import ( "os" "path" "path/filepath" + "strings" "github.com/go-git/go-billy/v5/util" - "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/gitignore" - "github.com/go-git/go-git/v5/plumbing/format/index" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/utils/ioutil" - "github.com/go-git/go-git/v5/utils/merkletrie" - "github.com/go-git/go-git/v5/utils/merkletrie/filesystem" - mindex "github.com/go-git/go-git/v5/utils/merkletrie/index" - "github.com/go-git/go-git/v5/utils/merkletrie/noder" + "github.com/jesseduffield/go-git/v5/plumbing" + "github.com/jesseduffield/go-git/v5/plumbing/filemode" + "github.com/jesseduffield/go-git/v5/plumbing/format/gitignore" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/object" + "github.com/jesseduffield/go-git/v5/utils/ioutil" + "github.com/jesseduffield/go-git/v5/utils/merkletrie" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem" + mindex "github.com/jesseduffield/go-git/v5/utils/merkletrie/index" + "github.com/jesseduffield/go-git/v5/utils/merkletrie/noder" ) var ( @@ -264,7 +265,77 @@ func diffTreeIsEquals(a, b noder.Hasher) bool { // the worktree to the index. If any of the files is already staged in the index // no error is returned. When path is a file, the blob.Hash is returned. func (w *Worktree) Add(path string) (plumbing.Hash, error) { - // TODO(mcuadros): remove plumbing.Hash from signature at v5. + // TODO(mcuadros): deprecate in favor of AddWithOption in v6. + return w.doAdd(path, make([]gitignore.Pattern, 0)) +} + +func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, ignorePattern []gitignore.Pattern) (added bool, err error) { + files, err := w.Filesystem.ReadDir(directory) + if err != nil { + return false, err + } + if len(ignorePattern) > 0 { + m := gitignore.NewMatcher(ignorePattern) + matchPath := strings.Split(directory, string(os.PathSeparator)) + if m.Match(matchPath, true) { + // ignore + return false, nil + } + } + + for _, file := range files { + name := path.Join(directory, file.Name()) + + var a bool + if file.IsDir() { + if file.Name() == GitDirName { + // ignore special git directory + continue + } + a, err = w.doAddDirectory(idx, s, name, ignorePattern) + } else { + a, _, err = w.doAddFile(idx, s, name, ignorePattern) + } + + if err != nil { + return + } + + if !added && a { + added = true + } + } + + return +} + +// AddWithOptions file contents to the index, updates the index using the +// current content found in the working tree, to prepare the content staged for +// the next commit. +// +// It typically adds the current content of existing paths as a whole, but with +// some options it can also be used to add content with only part of the changes +// made to the working tree files applied, or remove paths that do not exist in +// the working tree anymore. +func (w *Worktree) AddWithOptions(opts *AddOptions) error { + if err := opts.Validate(w.r); err != nil { + return err + } + + if opts.All { + _, err := w.doAdd(".", w.Excludes) + return err + } + + if opts.Glob != "" { + return w.AddGlob(opts.Glob) + } + + _, err := w.Add(opts.Path) + return err +} + +func (w *Worktree) doAdd(path string, ignorePattern []gitignore.Pattern) (plumbing.Hash, error) { s, err := w.Status() if err != nil { return plumbing.ZeroHash, err @@ -280,9 +351,9 @@ func (w *Worktree) Add(path string) (plumbing.Hash, error) { fi, err := w.Filesystem.Lstat(path) if err != nil || !fi.IsDir() { - added, h, err = w.doAddFile(idx, s, path) + added, h, err = w.doAddFile(idx, s, path, ignorePattern) } else { - added, err = w.doAddDirectory(idx, s, path) + added, err = w.doAddDirectory(idx, s, path, ignorePattern) } if err != nil { @@ -296,42 +367,11 @@ func (w *Worktree) Add(path string) (plumbing.Hash, error) { return h, w.r.Storer.SetIndex(idx) } -func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string) (added bool, err error) { - files, err := w.Filesystem.ReadDir(directory) - if err != nil { - return false, err - } - - for _, file := range files { - name := path.Join(directory, file.Name()) - - var a bool - if file.IsDir() { - if file.Name() == GitDirName { - // ignore special git directory - continue - } - a, err = w.doAddDirectory(idx, s, name) - } else { - a, _, err = w.doAddFile(idx, s, name) - } - - if err != nil { - return - } - - if !added && a { - added = true - } - } - - return -} - // AddGlob adds all paths, matching pattern, to the index. If pattern matches a // directory path, all directory contents are added to the index recursively. No // error is returned if all matching paths are already staged in index. func (w *Worktree) AddGlob(pattern string) error { + // TODO(mcuadros): deprecate in favor of AddWithOption in v6. files, err := util.Glob(w.Filesystem, pattern) if err != nil { return err @@ -360,9 +400,9 @@ func (w *Worktree) AddGlob(pattern string) error { var added bool if fi.IsDir() { - added, err = w.doAddDirectory(idx, s, file) + added, err = w.doAddDirectory(idx, s, file, make([]gitignore.Pattern, 0)) } else { - added, _, err = w.doAddFile(idx, s, file) + added, _, err = w.doAddFile(idx, s, file, make([]gitignore.Pattern, 0)) } if err != nil { @@ -383,10 +423,18 @@ func (w *Worktree) AddGlob(pattern string) error { // doAddFile create a new blob from path and update the index, added is true if // the file added is different from the index. -func (w *Worktree) doAddFile(idx *index.Index, s Status, path string) (added bool, h plumbing.Hash, err error) { +func (w *Worktree) doAddFile(idx *index.Index, s Status, path string, ignorePattern []gitignore.Pattern) (added bool, h plumbing.Hash, err error) { if s.File(path).Worktree == Unmodified { return false, h, nil } + if len(ignorePattern) > 0 { + m := gitignore.NewMatcher(ignorePattern) + matchPath := strings.Split(path, string(os.PathSeparator)) + if m.Match(matchPath, true) { + // ignore + return false, h, nil + } + } h, err = w.copyFileToStorage(path) if err != nil { diff --git a/vendor/github.com/go-git/go-git/v5/worktree_unix_other.go b/vendor/github.com/jesseduffield/go-git/v5/worktree_unix_other.go similarity index 87% rename from vendor/github.com/go-git/go-git/v5/worktree_unix_other.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree_unix_other.go index f45966be9..3d1aabf12 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree_unix_other.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree_unix_other.go @@ -6,7 +6,7 @@ import ( "syscall" "time" - "github.com/go-git/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" ) func init() { diff --git a/vendor/github.com/go-git/go-git/v5/worktree_windows.go b/vendor/github.com/jesseduffield/go-git/v5/worktree_windows.go similarity index 91% rename from vendor/github.com/go-git/go-git/v5/worktree_windows.go rename to vendor/github.com/jesseduffield/go-git/v5/worktree_windows.go index 1928f9712..e98f0773e 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree_windows.go +++ b/vendor/github.com/jesseduffield/go-git/v5/worktree_windows.go @@ -7,7 +7,7 @@ import ( "syscall" "time" - "github.com/go-git/go-git/v5/plumbing/format/index" + "github.com/jesseduffield/go-git/v5/plumbing/format/index" ) func init() { diff --git a/vendor/modules.txt b/vendor/modules.txt index 3379970e3..030a64ab6 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -39,49 +39,6 @@ github.com/go-git/go-billy/v5/helper/chroot github.com/go-git/go-billy/v5/helper/polyfill github.com/go-git/go-billy/v5/osfs github.com/go-git/go-billy/v5/util -# github.com/go-git/go-git/v5 v5.0.0 -## explicit -github.com/go-git/go-git/v5 -github.com/go-git/go-git/v5/config -github.com/go-git/go-git/v5/internal/revision -github.com/go-git/go-git/v5/internal/url -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/filemode -github.com/go-git/go-git/v5/plumbing/format/config -github.com/go-git/go-git/v5/plumbing/format/diff -github.com/go-git/go-git/v5/plumbing/format/gitignore -github.com/go-git/go-git/v5/plumbing/format/idxfile -github.com/go-git/go-git/v5/plumbing/format/index -github.com/go-git/go-git/v5/plumbing/format/objfile -github.com/go-git/go-git/v5/plumbing/format/packfile -github.com/go-git/go-git/v5/plumbing/format/pktline -github.com/go-git/go-git/v5/plumbing/object -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/protocol/packp/sideband -github.com/go-git/go-git/v5/plumbing/revlist -github.com/go-git/go-git/v5/plumbing/storer -github.com/go-git/go-git/v5/plumbing/transport -github.com/go-git/go-git/v5/plumbing/transport/client -github.com/go-git/go-git/v5/plumbing/transport/file -github.com/go-git/go-git/v5/plumbing/transport/git -github.com/go-git/go-git/v5/plumbing/transport/http -github.com/go-git/go-git/v5/plumbing/transport/internal/common -github.com/go-git/go-git/v5/plumbing/transport/server -github.com/go-git/go-git/v5/plumbing/transport/ssh -github.com/go-git/go-git/v5/storage -github.com/go-git/go-git/v5/storage/filesystem -github.com/go-git/go-git/v5/storage/filesystem/dotgit -github.com/go-git/go-git/v5/storage/memory -github.com/go-git/go-git/v5/utils/binary -github.com/go-git/go-git/v5/utils/diff -github.com/go-git/go-git/v5/utils/ioutil -github.com/go-git/go-git/v5/utils/merkletrie -github.com/go-git/go-git/v5/utils/merkletrie/filesystem -github.com/go-git/go-git/v5/utils/merkletrie/index -github.com/go-git/go-git/v5/utils/merkletrie/internal/frame -github.com/go-git/go-git/v5/utils/merkletrie/noder # github.com/go-logfmt/logfmt v0.5.0 ## explicit github.com/go-logfmt/logfmt @@ -103,11 +60,57 @@ github.com/hashicorp/hcl/hcl/token github.com/hashicorp/hcl/json/parser github.com/hashicorp/hcl/json/scanner github.com/hashicorp/hcl/json/token +# github.com/imdario/mergo v0.3.9 +github.com/imdario/mergo # github.com/integrii/flaggy v1.4.0 ## explicit github.com/integrii/flaggy # github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 github.com/jbenet/go-context/io +# github.com/jesseduffield/go-git/v5 v5.1.1 +## explicit +github.com/jesseduffield/go-git/v5 +github.com/jesseduffield/go-git/v5/config +github.com/jesseduffield/go-git/v5/internal/revision +github.com/jesseduffield/go-git/v5/internal/url +github.com/jesseduffield/go-git/v5/plumbing +github.com/jesseduffield/go-git/v5/plumbing/cache +github.com/jesseduffield/go-git/v5/plumbing/color +github.com/jesseduffield/go-git/v5/plumbing/filemode +github.com/jesseduffield/go-git/v5/plumbing/format/config +github.com/jesseduffield/go-git/v5/plumbing/format/diff +github.com/jesseduffield/go-git/v5/plumbing/format/gitignore +github.com/jesseduffield/go-git/v5/plumbing/format/idxfile +github.com/jesseduffield/go-git/v5/plumbing/format/index +github.com/jesseduffield/go-git/v5/plumbing/format/objfile +github.com/jesseduffield/go-git/v5/plumbing/format/packfile +github.com/jesseduffield/go-git/v5/plumbing/format/pktline +github.com/jesseduffield/go-git/v5/plumbing/object +github.com/jesseduffield/go-git/v5/plumbing/protocol/packp +github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/capability +github.com/jesseduffield/go-git/v5/plumbing/protocol/packp/sideband +github.com/jesseduffield/go-git/v5/plumbing/revlist +github.com/jesseduffield/go-git/v5/plumbing/storer +github.com/jesseduffield/go-git/v5/plumbing/transport +github.com/jesseduffield/go-git/v5/plumbing/transport/client +github.com/jesseduffield/go-git/v5/plumbing/transport/file +github.com/jesseduffield/go-git/v5/plumbing/transport/git +github.com/jesseduffield/go-git/v5/plumbing/transport/http +github.com/jesseduffield/go-git/v5/plumbing/transport/internal/common +github.com/jesseduffield/go-git/v5/plumbing/transport/server +github.com/jesseduffield/go-git/v5/plumbing/transport/ssh +github.com/jesseduffield/go-git/v5/storage +github.com/jesseduffield/go-git/v5/storage/filesystem +github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit +github.com/jesseduffield/go-git/v5/storage/memory +github.com/jesseduffield/go-git/v5/utils/binary +github.com/jesseduffield/go-git/v5/utils/diff +github.com/jesseduffield/go-git/v5/utils/ioutil +github.com/jesseduffield/go-git/v5/utils/merkletrie +github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem +github.com/jesseduffield/go-git/v5/utils/merkletrie/index +github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame +github.com/jesseduffield/go-git/v5/utils/merkletrie/noder # github.com/jesseduffield/gocui v0.3.1-0.20200930205305-1b445b9bd5da ## explicit github.com/jesseduffield/gocui @@ -235,3 +238,4 @@ gopkg.in/warnings.v0 # gopkg.in/yaml.v2 v2.2.7 ## explicit gopkg.in/yaml.v2 +# github.com/go-git/go-git/v5 => github.com/jesseduffield/go-git/v5 v5.1.1