From aba274ca7daf59d07d9559e6f99ca18ef0b78c7b Mon Sep 17 00:00:00 2001 From: "paul.t" Date: Mon, 11 Oct 2021 12:48:29 +0100 Subject: resolve external reference deltas --- plumbing/format/packfile/parser.go | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'plumbing') diff --git a/plumbing/format/packfile/parser.go b/plumbing/format/packfile/parser.go index 4b5a570..4c28a4a 100644 --- a/plumbing/format/packfile/parser.go +++ b/plumbing/format/packfile/parser.go @@ -287,6 +287,7 @@ func (p *Parser) resolveDeltas() error { if err := p.resolveObject(stdioutil.Discard, child, content); err != nil { return err } + p.resolveExternalRef(child) } // Remove the delta from the cache. @@ -299,6 +300,16 @@ func (p *Parser) resolveDeltas() error { return nil } +func (p *Parser) resolveExternalRef(o *objectInfo) { + if ref, ok := p.oiByHash[o.SHA1]; ok && ref.ExternalRef { + p.oiByHash[o.SHA1] = o + o.Children = ref.Children + for _, c := range o.Children { + c.Parent = o + } + } +} + 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) -- cgit From 589a41ceedfa89e1ff334a969d1beb28cb731de9 Mon Sep 17 00:00:00 2001 From: John Cai Date: Wed, 3 Nov 2021 14:04:06 -0400 Subject: Add Atomic to push options push --atomic allows a push to succeed or fail atomically. If one ref fails, the whole push fails. This commit allows the user to set Atomic as an option for a push. --- plumbing/protocol/packp/updreq_encode_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'plumbing') diff --git a/plumbing/protocol/packp/updreq_encode_test.go b/plumbing/protocol/packp/updreq_encode_test.go index 6ba0043..4370b79 100644 --- a/plumbing/protocol/packp/updreq_encode_test.go +++ b/plumbing/protocol/packp/updreq_encode_test.go @@ -170,3 +170,22 @@ func (s *UpdReqEncodeSuite) TestPushOptions(c *C) { s.testEncode(c, r, expected) } + +func (s *UpdReqEncodeSuite) TestPushAtomic(c *C) { + hash1 := plumbing.NewHash("1ecf0ef2c2dffb796033e5a02219af86ec6584e5") + hash2 := plumbing.NewHash("2ecf0ef2c2dffb796033e5a02219af86ec6584e5") + name := plumbing.ReferenceName("myref") + + r := NewReferenceUpdateRequest() + r.Capabilities.Set(capability.Atomic) + r.Commands = []*Command{ + {Name: name, Old: hash1, New: hash2}, + } + + expected := pktlines(c, + "1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00atomic", + pktline.FlushString, + ) + + s.testEncode(c, r, expected) +} -- cgit From a04ddf534f941bb531459dbdf98c875495272069 Mon Sep 17 00:00:00 2001 From: John Cai Date: Fri, 5 Nov 2021 14:57:38 -0400 Subject: Support v3 index Currently the index encoder does not support the v3 index format. This change adds support to the encoder. This helps to unlock sparse checkout. --- plumbing/format/index/encoder.go | 34 +++++++++++++++++++++++++--------- plumbing/format/index/encoder_test.go | 26 +++++++++++++++++++++----- 2 files changed, 46 insertions(+), 14 deletions(-) (limited to 'plumbing') diff --git a/plumbing/format/index/encoder.go b/plumbing/format/index/encoder.go index 00d4e7a..2c94d93 100644 --- a/plumbing/format/index/encoder.go +++ b/plumbing/format/index/encoder.go @@ -14,7 +14,7 @@ import ( var ( // EncodeVersionSupported is the range of supported index versions - EncodeVersionSupported uint32 = 2 + EncodeVersionSupported uint32 = 3 // ErrInvalidTimestamp is returned by Encode if a Index with a Entry with // negative timestamp values @@ -36,9 +36,9 @@ func NewEncoder(w io.Writer) *Encoder { // Encode writes the Index to the stream of the encoder. func (e *Encoder) Encode(idx *Index) error { - // TODO: support versions v3 and v4 + // TODO: support v4 // TODO: support extensions - if idx.Version != EncodeVersionSupported { + if idx.Version > EncodeVersionSupported { return ErrUnsupportedVersion } @@ -68,8 +68,12 @@ func (e *Encoder) encodeEntries(idx *Index) error { if err := e.encodeEntry(entry); err != nil { return err } + entryLength := entryHeaderLength + if entry.IntentToAdd || entry.SkipWorktree { + entryLength += 2 + } - wrote := entryHeaderLength + len(entry.Name) + wrote := entryLength + len(entry.Name) if err := e.padEntry(wrote); err != nil { return err } @@ -79,10 +83,6 @@ func (e *Encoder) encodeEntries(idx *Index) error { } func (e *Encoder) encodeEntry(entry *Entry) error { - if entry.IntentToAdd || entry.SkipWorktree { - return ErrUnsupportedVersion - } - sec, nsec, err := e.timeToUint32(&entry.CreatedAt) if err != nil { return err @@ -110,9 +110,25 @@ func (e *Encoder) encodeEntry(entry *Entry) error { entry.GID, entry.Size, entry.Hash[:], - flags, } + flagsFlow := []interface{}{flags} + + if entry.IntentToAdd || entry.SkipWorktree { + var extendedFlags uint16 + + if entry.IntentToAdd { + extendedFlags |= intentToAddMask + } + if entry.SkipWorktree { + extendedFlags |= skipWorkTreeMask + } + + flagsFlow = []interface{}{flags | entryExtended, extendedFlags} + } + + flow = append(flow, flagsFlow...) + if err := binary.Write(e.w, flow...); err != nil { return err } diff --git a/plumbing/format/index/encoder_test.go b/plumbing/format/index/encoder_test.go index b7a73cb..25c24f1 100644 --- a/plumbing/format/index/encoder_test.go +++ b/plumbing/format/index/encoder_test.go @@ -57,7 +57,7 @@ func (s *IndexSuite) TestEncode(c *C) { } func (s *IndexSuite) TestEncodeUnsupportedVersion(c *C) { - idx := &Index{Version: 3} + idx := &Index{Version: 4} buf := bytes.NewBuffer(nil) e := NewEncoder(buf) @@ -67,24 +67,40 @@ func (s *IndexSuite) TestEncodeUnsupportedVersion(c *C) { func (s *IndexSuite) TestEncodeWithIntentToAddUnsupportedVersion(c *C) { idx := &Index{ - Version: 2, + Version: 3, Entries: []*Entry{{IntentToAdd: true}}, } buf := bytes.NewBuffer(nil) e := NewEncoder(buf) err := e.Encode(idx) - c.Assert(err, Equals, ErrUnsupportedVersion) + c.Assert(err, IsNil) + + output := &Index{} + d := NewDecoder(buf) + err = d.Decode(output) + c.Assert(err, IsNil) + + c.Assert(cmp.Equal(idx, output), Equals, true) + c.Assert(output.Entries[0].IntentToAdd, Equals, true) } func (s *IndexSuite) TestEncodeWithSkipWorktreeUnsupportedVersion(c *C) { idx := &Index{ - Version: 2, + Version: 3, Entries: []*Entry{{SkipWorktree: true}}, } buf := bytes.NewBuffer(nil) e := NewEncoder(buf) err := e.Encode(idx) - c.Assert(err, Equals, ErrUnsupportedVersion) + c.Assert(err, IsNil) + + output := &Index{} + d := NewDecoder(buf) + err = d.Decode(output) + c.Assert(err, IsNil) + + c.Assert(cmp.Equal(idx, output), Equals, true) + c.Assert(output.Entries[0].SkipWorktree, Equals, true) } -- cgit From f92011d95f98f5deea4959c7d432704a4300d3a8 Mon Sep 17 00:00:00 2001 From: John Cai Date: Thu, 4 Nov 2021 15:02:00 -0400 Subject: simplified sparse checkout This is the initial logic to support a simple sparse checkout where directories to be included can be specified in CheckoutOptions. This change doesn't fully support the sparse patterns, nor does this change include the optimization to collapse flie entries in ithe index that are excluded via the sparse checkout directory patterns included under the parent directory. --- plumbing/format/index/index.go | 18 ++++++++++++++++++ plumbing/object/treenoder.go | 4 ++++ 2 files changed, 22 insertions(+) (limited to 'plumbing') diff --git a/plumbing/format/index/index.go b/plumbing/format/index/index.go index 649416a..f4c7647 100644 --- a/plumbing/format/index/index.go +++ b/plumbing/format/index/index.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "path/filepath" + "strings" "time" "github.com/go-git/go-git/v5/plumbing" @@ -211,3 +212,20 @@ type EndOfIndexEntry struct { // their contents). Hash plumbing.Hash } + +// SkipUnless applies patterns in the form of A, A/B, A/B/C +// to the index to prevent the files from being checked out +func (i *Index) SkipUnless(patterns []string) { + for _, e := range i.Entries { + var include bool + for _, pattern := range patterns { + if strings.HasPrefix(e.Name, pattern) { + include = true + break + } + } + if !include { + e.SkipWorktree = true + } + } +} diff --git a/plumbing/object/treenoder.go b/plumbing/object/treenoder.go index b4891b9..6e7b334 100644 --- a/plumbing/object/treenoder.go +++ b/plumbing/object/treenoder.go @@ -38,6 +38,10 @@ func NewTreeRootNode(t *Tree) noder.Noder { } } +func (t *treeNoder) Skip() bool { + return false +} + func (t *treeNoder) isRoot() bool { return t.name == "" } -- cgit From 07a8bcc71afb5814c00c7a7b19c29b0c493a18fd Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Sat, 27 Nov 2021 14:26:38 -0800 Subject: Remove unused variables/types/functions [staticcheck](https://staticcheck.io/) reported a number of unused fields, functions, types, and variables across the code. Where possible, use them (assert unchecked errors in tests, for example) and otherwise remove them. --- plumbing/format/packfile/fsobject.go | 15 --------------- plumbing/format/packfile/packfile_test.go | 17 ----------------- plumbing/format/packfile/parser.go | 1 - plumbing/object/patch.go | 4 ---- plumbing/protocol/packp/common.go | 1 - plumbing/protocol/packp/updreq_encode.go | 4 ---- plumbing/protocol/packp/uppackresp.go | 1 - plumbing/revlist/revlist_test.go | 6 ------ plumbing/transport/client/client_test.go | 5 ----- plumbing/transport/internal/common/common.go | 5 ----- plumbing/transport/ssh/common_test.go | 3 +-- 11 files changed, 1 insertion(+), 61 deletions(-) (limited to 'plumbing') diff --git a/plumbing/format/packfile/fsobject.go b/plumbing/format/packfile/fsobject.go index a395d17..238339d 100644 --- a/plumbing/format/packfile/fsobject.go +++ b/plumbing/format/packfile/fsobject.go @@ -13,7 +13,6 @@ import ( // FSObject is an object from the packfile on the filesystem. type FSObject struct { hash plumbing.Hash - h *ObjectHeader offset int64 size int64 typ plumbing.ObjectType @@ -118,17 +117,3 @@ func (o *FSObject) Type() plumbing.ObjectType { func (o *FSObject) Writer() (io.WriteCloser, error) { return nil, nil } - -type objectReader struct { - io.ReadCloser - f billy.File -} - -func (r *objectReader) Close() error { - if err := r.ReadCloser.Close(); err != nil { - _ = r.f.Close() - return err - } - - return r.f.Close() -} diff --git a/plumbing/format/packfile/packfile_test.go b/plumbing/format/packfile/packfile_test.go index 6af8817..2eb099d 100644 --- a/plumbing/format/packfile/packfile_test.go +++ b/plumbing/format/packfile/packfile_test.go @@ -8,7 +8,6 @@ import ( "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/packfile" - "github.com/go-git/go-git/v5/plumbing/storer" . "gopkg.in/check.v1" ) @@ -236,22 +235,6 @@ var expectedHashes = []string{ "7e59600739c96546163833214c36459e324bad0a", } -func assertObjects(c *C, s storer.EncodedObjectStorer, expects []string) { - i, err := s.IterEncodedObjects(plumbing.AnyObject) - c.Assert(err, IsNil) - - var count int - err = i.ForEach(func(plumbing.EncodedObject) error { count++; return nil }) - c.Assert(err, IsNil) - c.Assert(count, Equals, len(expects)) - - for _, exp := range expects { - obt, err := s.EncodedObject(plumbing.AnyObject, plumbing.NewHash(exp)) - c.Assert(err, IsNil) - c.Assert(obt.Hash().String(), Equals, exp) - } -} - func getIndexFromIdxFile(r io.Reader) idxfile.Index { idx := idxfile.NewMemoryIndex() if err := idxfile.NewDecoder(r).Decode(idx); err != nil { diff --git a/plumbing/format/packfile/parser.go b/plumbing/format/packfile/parser.go index 4b5a570..ee5c289 100644 --- a/plumbing/format/packfile/parser.go +++ b/plumbing/format/packfile/parser.go @@ -46,7 +46,6 @@ type Parser struct { oi []*objectInfo oiByHash map[plumbing.Hash]*objectInfo oiByOffset map[int64]*objectInfo - hashOffset map[plumbing.Hash]int64 checksum plumbing.Hash cache *cache.BufferLRU diff --git a/plumbing/object/patch.go b/plumbing/object/patch.go index 56b62c1..06bc35b 100644 --- a/plumbing/object/patch.go +++ b/plumbing/object/patch.go @@ -96,10 +96,6 @@ func filePatchWithContext(ctx context.Context, c *Change) (fdiff.FilePatch, erro } -func filePatch(c *Change) (fdiff.FilePatch, error) { - return filePatchWithContext(context.Background(), c) -} - func fileContent(f *File) (content string, isBinary bool, err error) { if f == nil { return diff --git a/plumbing/protocol/packp/common.go b/plumbing/protocol/packp/common.go index ab07ac8..fef50a4 100644 --- a/plumbing/protocol/packp/common.go +++ b/plumbing/protocol/packp/common.go @@ -19,7 +19,6 @@ var ( // common sp = []byte(" ") eol = []byte("\n") - eq = []byte{'='} // advertised-refs null = []byte("\x00") diff --git a/plumbing/protocol/packp/updreq_encode.go b/plumbing/protocol/packp/updreq_encode.go index 08a819e..1205cfa 100644 --- a/plumbing/protocol/packp/updreq_encode.go +++ b/plumbing/protocol/packp/updreq_encode.go @@ -9,10 +9,6 @@ import ( "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" ) -var ( - zeroHashString = plumbing.ZeroHash.String() -) - // Encode writes the ReferenceUpdateRequest encoding to the stream. func (req *ReferenceUpdateRequest) Encode(w io.Writer) error { if err := req.validate(); err != nil { diff --git a/plumbing/protocol/packp/uppackresp.go b/plumbing/protocol/packp/uppackresp.go index a9a7192..26ae61e 100644 --- a/plumbing/protocol/packp/uppackresp.go +++ b/plumbing/protocol/packp/uppackresp.go @@ -24,7 +24,6 @@ type UploadPackResponse struct { r io.ReadCloser isShallow bool isMultiACK bool - isOk bool } // NewUploadPackResponse create a new UploadPackResponse instance, the request diff --git a/plumbing/revlist/revlist_test.go b/plumbing/revlist/revlist_test.go index a1ee504..9f2f93b 100644 --- a/plumbing/revlist/revlist_test.go +++ b/plumbing/revlist/revlist_test.go @@ -55,12 +55,6 @@ func (s *RevListSuite) SetUpTest(c *C) { s.Storer = sto } -func (s *RevListSuite) commit(c *C, h plumbing.Hash) *object.Commit { - commit, err := object.GetCommit(s.Storer, h) - c.Assert(err, IsNil) - return commit -} - func (s *RevListSuite) TestRevListObjects_Submodules(c *C) { submodules := map[string]bool{ "6ecf0ef2c2dffb796033e5a02219af86ec6584e5": true, diff --git a/plumbing/transport/client/client_test.go b/plumbing/transport/client/client_test.go index 9ebe113..92db525 100644 --- a/plumbing/transport/client/client_test.go +++ b/plumbing/transport/client/client_test.go @@ -1,7 +1,6 @@ package client import ( - "fmt" "net/http" "testing" @@ -68,7 +67,3 @@ func (*dummyClient) NewReceivePackSession(*transport.Endpoint, transport.AuthMet transport.ReceivePackSession, error) { return nil, nil } - -func typeAsString(v interface{}) string { - return fmt.Sprintf("%T", v) -} diff --git a/plumbing/transport/internal/common/common.go b/plumbing/transport/internal/common/common.go index fdb148f..d0e9a29 100644 --- a/plumbing/transport/internal/common/common.go +++ b/plumbing/transport/internal/common/common.go @@ -428,11 +428,6 @@ func isRepoNotFoundError(s string) bool { return false } -var ( - nak = []byte("NAK") - eol = []byte("\n") -) - // uploadPack implements the git-upload-pack protocol. func uploadPack(w io.WriteCloser, r io.Reader, req *packp.UploadPackRequest) error { // TODO support multi_ack mode diff --git a/plumbing/transport/ssh/common_test.go b/plumbing/transport/ssh/common_test.go index e04a9c5..6d634d5 100644 --- a/plumbing/transport/ssh/common_test.go +++ b/plumbing/transport/ssh/common_test.go @@ -7,7 +7,6 @@ import ( "github.com/kevinburke/ssh_config" "golang.org/x/crypto/ssh" - stdssh "golang.org/x/crypto/ssh" . "gopkg.in/check.v1" ) @@ -99,7 +98,7 @@ func (s *SuiteCommon) TestIssue70(c *C) { uploadPack.SetUpSuite(c) config := &ssh.ClientConfig{ - HostKeyCallback: stdssh.InsecureIgnoreHostKey(), + HostKeyCallback: ssh.InsecureIgnoreHostKey(), } r := &runner{ config: config, -- cgit From fe308ea0d0ff6c31f2a218f8b47d8ace124ea679 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Sat, 27 Nov 2021 16:51:55 -0800 Subject: packp: Actions should have type Action Per the [Go Spec](https://go.dev/ref/spec#Constant_declarations), the following yields the type `Action` for `Bar` and `Baz` only if there is no `=`. const ( Foo Action = ... Bar Baz ) The following has the type `Action` for the first item, but not the rest. Those are untyped constants of the corresponding type. const ( Foo Action = ... Bar = ... Baz = ... ) This means that `packp.{Update, Delete, Invalid}` are currently untyped string constants, and not `Action` constants as was intended here. This change fixes these. --- plumbing/protocol/packp/updreq.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plumbing') diff --git a/plumbing/protocol/packp/updreq.go b/plumbing/protocol/packp/updreq.go index 46ad6fd..5dbd8ac 100644 --- a/plumbing/protocol/packp/updreq.go +++ b/plumbing/protocol/packp/updreq.go @@ -87,9 +87,9 @@ type Action string const ( Create Action = "create" - Update = "update" - Delete = "delete" - Invalid = "invalid" + Update Action = "update" + Delete Action = "delete" + Invalid Action = "invalid" ) type Command struct { -- cgit From 0dcebfb72bbdaf01554f938402e699d67937c5a0 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Sat, 4 Dec 2021 15:16:09 -0800 Subject: error strings: Don't capitalize, use periods, or newlines Per [Go Code Review Comments][1], > Error strings should not be capitalized (unless beginning with proper > nouns or acronyms) or end with punctuation staticcheck's [ST1005][2] also complains about these. For example, ``` object_walker.go:63:10: error strings should not be capitalized (ST1005) object_walker.go:101:10: error strings should not be capitalized (ST1005) object_walker.go:101:10: error strings should not end with punctuation or a newline (ST1005) plumbing/format/commitgraph/file.go:17:26: error strings should not be capitalized (ST1005) ``` This fixes all instances of this issue reported by staticcheck. [1]: https://github.com/golang/go/wiki/CodeReviewComments#error-strings [2]: https://staticcheck.io/docs/checks/#ST1005 --- plumbing/format/commitgraph/file.go | 6 +++--- plumbing/format/gitattributes/attributes.go | 2 +- plumbing/format/idxfile/decoder.go | 4 ++-- plumbing/object/change_adaptor.go | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'plumbing') diff --git a/plumbing/format/commitgraph/file.go b/plumbing/format/commitgraph/file.go index 0ce7198..1d25238 100644 --- a/plumbing/format/commitgraph/file.go +++ b/plumbing/format/commitgraph/file.go @@ -14,14 +14,14 @@ import ( var ( // ErrUnsupportedVersion is returned by OpenFileIndex when the commit graph // file version is not supported. - ErrUnsupportedVersion = errors.New("Unsupported version") + ErrUnsupportedVersion = errors.New("unsupported version") // ErrUnsupportedHash is returned by OpenFileIndex when the commit graph // hash function is not supported. Currently only SHA-1 is defined and // supported - ErrUnsupportedHash = errors.New("Unsupported hash algorithm") + ErrUnsupportedHash = errors.New("unsupported hash algorithm") // ErrMalformedCommitGraphFile is returned by OpenFileIndex when the commit // graph file is corrupted. - ErrMalformedCommitGraphFile = errors.New("Malformed commit graph file") + ErrMalformedCommitGraphFile = errors.New("malformed commit graph file") commitFileSignature = []byte{'C', 'G', 'P', 'H'} oidFanoutSignature = []byte{'O', 'I', 'D', 'F'} diff --git a/plumbing/format/gitattributes/attributes.go b/plumbing/format/gitattributes/attributes.go index d13c2a9..329e667 100644 --- a/plumbing/format/gitattributes/attributes.go +++ b/plumbing/format/gitattributes/attributes.go @@ -15,7 +15,7 @@ const ( var ( ErrMacroNotAllowed = errors.New("macro not allowed") - ErrInvalidAttributeName = errors.New("Invalid attribute name") + ErrInvalidAttributeName = errors.New("invalid attribute name") ) type MatchAttribute struct { diff --git a/plumbing/format/idxfile/decoder.go b/plumbing/format/idxfile/decoder.go index 7768bd6..51a3904 100644 --- a/plumbing/format/idxfile/decoder.go +++ b/plumbing/format/idxfile/decoder.go @@ -12,9 +12,9 @@ import ( var ( // ErrUnsupportedVersion is returned by Decode when the idx file version // is not supported. - ErrUnsupportedVersion = errors.New("Unsupported version") + ErrUnsupportedVersion = errors.New("unsupported version") // ErrMalformedIdxFile is returned by Decode when the idx file is corrupted. - ErrMalformedIdxFile = errors.New("Malformed IDX file") + ErrMalformedIdxFile = errors.New("malformed IDX file") ) const ( diff --git a/plumbing/object/change_adaptor.go b/plumbing/object/change_adaptor.go index f701188..b96ee84 100644 --- a/plumbing/object/change_adaptor.go +++ b/plumbing/object/change_adaptor.go @@ -16,11 +16,11 @@ func newChange(c merkletrie.Change) (*Change, error) { var err error if ret.From, err = newChangeEntry(c.From); err != nil { - return nil, fmt.Errorf("From field: %s", err) + return nil, fmt.Errorf("from field: %s", err) } if ret.To, err = newChangeEntry(c.To); err != nil { - return nil, fmt.Errorf("To field: %s", err) + return nil, fmt.Errorf("to field: %s", err) } return ret, nil -- cgit