aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/codeql.yml44
-rw-r--r--SECURITY.md38
-rw-r--r--_examples/commit/main.go3
-rw-r--r--_examples/common_test.go3
-rw-r--r--_examples/sha256/main.go3
-rw-r--r--_examples/tag-create-push/main.go3
-rw-r--r--common_test.go59
-rw-r--r--config/config.go3
-rw-r--r--example_test.go7
-rw-r--r--go.mod22
-rw-r--r--go.sum37
-rw-r--r--options.go2
-rw-r--r--plumbing/format/gitattributes/attributes.go3
-rw-r--r--plumbing/format/gitignore/dir.go22
-rw-r--r--plumbing/format/gitignore/dir_test.go119
-rw-r--r--plumbing/format/gitignore/pattern.go2
-rw-r--r--plumbing/format/idxfile/decoder_test.go3
-rw-r--r--plumbing/format/idxfile/encoder_test.go4
-rw-r--r--plumbing/format/idxfile/writer.go29
-rw-r--r--plumbing/format/idxfile/writer_test.go6
-rw-r--r--plumbing/format/index/decoder.go4
-rw-r--r--plumbing/format/objfile/reader_test.go3
-rw-r--r--plumbing/format/packfile/delta_test.go10
-rw-r--r--plumbing/format/packfile/encoder.go6
-rw-r--r--plumbing/format/packfile/encoder_test.go5
-rw-r--r--plumbing/format/packfile/parser.go3
-rw-r--r--plumbing/format/packfile/scanner.go5
-rw-r--r--plumbing/memory_test.go5
-rw-r--r--plumbing/object/blob_test.go7
-rw-r--r--plumbing/object/commit_test.go5
-rw-r--r--plumbing/object/object_test.go3
-rw-r--r--plumbing/object/rename.go5
-rw-r--r--plumbing/object/tag_test.go3
-rw-r--r--plumbing/protocol/packp/advrefs.go14
-rw-r--r--plumbing/protocol/packp/sideband/demux_test.go3
-rw-r--r--plumbing/protocol/packp/updreq_decode.go3
-rw-r--r--plumbing/protocol/packp/updreq_decode_test.go15
-rw-r--r--plumbing/protocol/packp/updreq_encode_test.go5
-rw-r--r--plumbing/protocol/packp/uppackresp_test.go20
-rw-r--r--plumbing/reference.go8
-rw-r--r--plumbing/transport/file/common_test.go3
-rw-r--r--plumbing/transport/git/common.go5
-rw-r--r--plumbing/transport/git/common_test.go3
-rw-r--r--plumbing/transport/http/common_test.go3
-rw-r--r--plumbing/transport/http/upload_pack_test.go4
-rw-r--r--plumbing/transport/internal/common/common.go3
-rw-r--r--plumbing/transport/ssh/auth_method.go3
-rw-r--r--plumbing/transport/ssh/common.go4
-rw-r--r--plumbing/transport/ssh/internal/test/proxy_test.go3
-rw-r--r--plumbing/transport/ssh/proxy_test.go3
-rw-r--r--plumbing/transport/ssh/upload_pack_test.go3
-rw-r--r--plumbing/transport/test/receive_pack.go6
-rw-r--r--plumbing/transport/test/upload_pack.go6
-rw-r--r--remote.go125
-rw-r--r--remote_test.go168
-rw-r--r--repository.go68
-rw-r--r--repository_test.go115
-rw-r--r--storage/filesystem/dotgit/dotgit.go3
-rw-r--r--storage/filesystem/dotgit/dotgit_test.go7
-rw-r--r--storage/filesystem/object_test.go3
-rw-r--r--storage/test/storage_suite.go5
-rw-r--r--submodule.go14
-rw-r--r--submodule_test.go42
-rw-r--r--utils/ioutil/common_test.go8
-rw-r--r--worktree.go5
-rw-r--r--worktree_test.go11
66 files changed, 811 insertions, 356 deletions
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000..fbb867c
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,44 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+ schedule:
+ - cron: '00 5 * * 1'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'go' ]
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3
+ with:
+ languages: ${{ matrix.language }}
+ # xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+ # xref: https://codeql.github.com/codeql-query-help/go/
+ queries: security-and-quality
+
+ - name: Manual Build
+ run: go build ./...
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3
+ with:
+ category: "/language:${{matrix.language}}"
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..0d2f8d0
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,38 @@
+# go-git Security Policy
+
+The purpose of this security policy is to outline `go-git`'s process
+for reporting, handling and disclosing security sensitive information.
+
+## Supported Versions
+
+The project follows a version support policy where only the latest minor
+release is actively supported. Therefore, only issues that impact the latest
+minor release will be fixed. Users are encouraged to upgrade to the latest
+minor/patch release to benefit from the most up-to-date features, bug fixes,
+and security enhancements.​
+
+The supported versions policy applies to both the `go-git` library and its
+associated repositories within the `go-git` org.
+
+## Reporting Security Issues
+
+Please report any security vulnerabilities or potential weaknesses in `go-git`
+privately via go-git-security@googlegroups.com. Do not publicly disclose the
+details of the vulnerability until a fix has been implemented and released.
+
+During the process the project maintainers will investigate the report, so please
+provide detailed information, including steps to reproduce, affected versions, and any mitigations if known.
+
+The project maintainers will acknowledge the receipt of the report and work with
+the reporter to validate and address the issue.
+
+Please note that `go-git` does not have any bounty programs, and therefore do
+not provide financial compensation for disclosures.
+
+## Security Disclosure Process
+
+The project maintainers will make every effort to promptly address security issues.
+
+Once a security vulnerability is fixed, a security advisory will be published to notify users and provide appropriate mitigation measures.
+
+All `go-git` advisories can be found at https://github.com/go-git/go-git/security/advisories.
diff --git a/_examples/commit/main.go b/_examples/commit/main.go
index 4529c84..3f3c880 100644
--- a/_examples/commit/main.go
+++ b/_examples/commit/main.go
@@ -2,7 +2,6 @@ package main
import (
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"time"
@@ -29,7 +28,7 @@ func main() {
// worktree of the project using the go standard library.
Info("echo \"hello world!\" > example-git-file")
filename := filepath.Join(directory, "example-git-file")
- err = ioutil.WriteFile(filename, []byte("hello world!"), 0644)
+ err = os.WriteFile(filename, []byte("hello world!"), 0644)
CheckIfError(err)
// Adds the new file to the staging area.
diff --git a/_examples/common_test.go b/_examples/common_test.go
index 9945c87..6630f15 100644
--- a/_examples/common_test.go
+++ b/_examples/common_test.go
@@ -3,7 +3,6 @@ package examples
import (
"flag"
"go/build"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -65,7 +64,7 @@ func TestExamples(t *testing.T) {
}
func tempFolder() string {
- path, err := ioutil.TempDir("", "")
+ path, err := os.MkdirTemp("", "")
CheckIfError(err)
tempFolders = append(tempFolders, path)
diff --git a/_examples/sha256/main.go b/_examples/sha256/main.go
index 2a257e8..e1772d2 100644
--- a/_examples/sha256/main.go
+++ b/_examples/sha256/main.go
@@ -2,7 +2,6 @@ package main
import (
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"time"
@@ -34,7 +33,7 @@ func main() {
// worktree of the project using the go standard library.
Info("echo \"hello world!\" > example-git-file")
filename := filepath.Join(directory, "example-git-file")
- err = ioutil.WriteFile(filename, []byte("hello world!"), 0644)
+ err = os.WriteFile(filename, []byte("hello world!"), 0644)
CheckIfError(err)
// Adds the new file to the staging area.
diff --git a/_examples/tag-create-push/main.go b/_examples/tag-create-push/main.go
index c443641..b820c76 100644
--- a/_examples/tag-create-push/main.go
+++ b/_examples/tag-create-push/main.go
@@ -2,7 +2,6 @@ package main
import (
"fmt"
- "io/ioutil"
"log"
"os"
@@ -67,7 +66,7 @@ func cloneRepo(url, dir, publicKeyPath string) (*git.Repository, error) {
func publicKey(filePath string) (*ssh.PublicKeys, error) {
var publicKey *ssh.PublicKeys
- sshKey, _ := ioutil.ReadFile(filePath)
+ sshKey, _ := os.ReadFile(filePath)
publicKey, err := ssh.NewPublicKeys("git", []byte(sshKey), "")
if err != nil {
return nil, err
diff --git a/common_test.go b/common_test.go
index c0c4009..7f9b84b 100644
--- a/common_test.go
+++ b/common_test.go
@@ -3,10 +3,12 @@ package git
import (
"os"
"testing"
+ "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/packfile"
+ "github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/go-git/go-git/v5/storage/memory"
@@ -37,7 +39,7 @@ func (s *BaseSuite) TearDownSuite(c *C) {
s.Suite.TearDownSuite(c)
}
-func (s *BaseSuite) buildBasicRepository(c *C) {
+func (s *BaseSuite) buildBasicRepository(_ *C) {
f := fixtures.Basic().One()
s.Repository = s.NewRepository(f)
}
@@ -105,13 +107,16 @@ func (s *BaseSuite) NewRepositoryFromPackfile(f *fixtures.Fixture) *Repository {
storer := memory.NewStorage()
p := f.Packfile()
- defer p.Close()
+ defer func() { _ = p.Close() }()
if err := packfile.UpdateObjectStorage(storer, p); err != nil {
panic(err)
}
- storer.SetReference(plumbing.NewHashReference(plumbing.HEAD, plumbing.NewHash(f.Head)))
+ err := storer.SetReference(plumbing.NewHashReference(plumbing.HEAD, plumbing.NewHash(f.Head)))
+ if err != nil {
+ panic(err)
+ }
r, err := Open(storer, memfs.New())
if err != nil {
@@ -133,14 +138,17 @@ func (s *BaseSuite) GetLocalRepositoryURL(f *fixtures.Fixture) string {
func (s *BaseSuite) TemporalDir() (path string, clean func()) {
fs := osfs.New(os.TempDir())
- path, err := util.TempDir(fs, "", "")
+ relPath, err := util.TempDir(fs, "", "")
if err != nil {
panic(err)
}
- return fs.Join(fs.Root(), path), func() {
- util.RemoveAll(fs, path)
+ path = fs.Join(fs.Root(), relPath)
+ clean = func() {
+ _ = util.RemoveAll(fs, relPath)
}
+
+ return
}
func (s *BaseSuite) TemporalFilesystem() (fs billy.Filesystem, clean func()) {
@@ -155,9 +163,11 @@ func (s *BaseSuite) TemporalFilesystem() (fs billy.Filesystem, clean func()) {
panic(err)
}
- return fs, func() {
- util.RemoveAll(fs, path)
+ clean = func() {
+ _ = util.RemoveAll(fs, path)
}
+
+ return
}
type SuiteCommon struct{}
@@ -204,3 +214,36 @@ func AssertReferencesMissing(c *C, r *Repository, expected []string) {
c.Assert(err, Equals, plumbing.ErrReferenceNotFound)
}
}
+
+func CommitNewFile(c *C, repo *Repository, fileName string) plumbing.Hash {
+ wt, err := repo.Worktree()
+ c.Assert(err, IsNil)
+
+ fd, err := wt.Filesystem.Create(fileName)
+ c.Assert(err, IsNil)
+
+ _, err = fd.Write([]byte("# test file"))
+ c.Assert(err, IsNil)
+
+ err = fd.Close()
+ c.Assert(err, IsNil)
+
+ _, err = wt.Add(fileName)
+ c.Assert(err, IsNil)
+
+ sha, err := wt.Commit("test commit", &CommitOptions{
+ Author: &object.Signature{
+ Name: "test",
+ Email: "test@example.com",
+ When: time.Now(),
+ },
+ Committer: &object.Signature{
+ Name: "test",
+ Email: "test@example.com",
+ When: time.Now(),
+ },
+ })
+ c.Assert(err, IsNil)
+
+ return sha
+}
diff --git a/config/config.go b/config/config.go
index 60dfca4..82af12d 100644
--- a/config/config.go
+++ b/config/config.go
@@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"sort"
@@ -144,7 +143,7 @@ func NewConfig() *Config {
// ReadConfig reads a config file from a io.Reader.
func ReadConfig(r io.Reader) (*Config, error) {
- b, err := ioutil.ReadAll(r)
+ b, err := io.ReadAll(r)
if err != nil {
return nil, err
}
diff --git a/example_test.go b/example_test.go
index bba2961..27ea4a2 100644
--- a/example_test.go
+++ b/example_test.go
@@ -3,7 +3,6 @@ package git_test
import (
"fmt"
"io"
- "io/ioutil"
"log"
"os"
"path/filepath"
@@ -44,7 +43,7 @@ func ExampleClone() {
func ExamplePlainClone() {
// Tempdir to clone the repository
- dir, err := ioutil.TempDir("", "clone-example")
+ dir, err := os.MkdirTemp("", "clone-example")
if err != nil {
log.Fatal(err)
}
@@ -72,7 +71,7 @@ func ExamplePlainClone() {
func ExamplePlainClone_usernamePassword() {
// Tempdir to clone the repository
- dir, err := ioutil.TempDir("", "clone-example")
+ dir, err := os.MkdirTemp("", "clone-example")
if err != nil {
log.Fatal(err)
}
@@ -95,7 +94,7 @@ func ExamplePlainClone_usernamePassword() {
func ExamplePlainClone_accessToken() {
// Tempdir to clone the repository
- dir, err := ioutil.TempDir("", "clone-example")
+ dir, err := os.MkdirTemp("", "clone-example")
if err != nil {
log.Fatal(err)
}
diff --git a/go.mod b/go.mod
index f062b1a..ee58848 100644
--- a/go.mod
+++ b/go.mod
@@ -1,9 +1,10 @@
module github.com/go-git/go-git/v5
-go 1.13
+// go-git supports the last 3 stable Go versions.
+go 1.18
require (
- github.com/ProtonMail/go-crypto v0.0.0-20230417170513-8ee5748c52b5
+ github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903
github.com/acomagu/bufpipe v1.0.4
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819
@@ -20,11 +21,20 @@ require (
github.com/kevinburke/ssh_config v1.2.0
github.com/pjbgf/sha1cd v0.3.0
github.com/sergi/go-diff v1.1.0
- github.com/skeema/knownhosts v1.1.0
+ github.com/skeema/knownhosts v1.1.1
github.com/xanzy/ssh-agent v0.3.3
- golang.org/x/crypto v0.8.0
- golang.org/x/net v0.9.0
- golang.org/x/sys v0.7.0
+ golang.org/x/crypto v0.9.0
+ golang.org/x/net v0.10.0
+ golang.org/x/sys v0.8.0
golang.org/x/text v0.9.0
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
)
+
+require (
+ github.com/Microsoft/go-winio v0.5.2 // indirect
+ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
+ github.com/cloudflare/circl v1.3.3 // indirect
+ github.com/kr/pretty v0.2.1 // indirect
+ github.com/kr/text v0.2.0 // indirect
+ gopkg.in/warnings.v0 v0.1.2 // indirect
+)
diff --git a/go.sum b/go.sum
index db7d92b..fcfc9f5 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,7 @@
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
-github.com/ProtonMail/go-crypto v0.0.0-20230417170513-8ee5748c52b5 h1:QXMwHM/lB4ZQhdEF7JUTNgYOJR/gWoFbgQ/2Aj1h3Dk=
-github.com/ProtonMail/go-crypto v0.0.0-20230417170513-8ee5748c52b5/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
+github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek=
+github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
@@ -9,8 +9,9 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
-github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
+github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
+github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -51,7 +52,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
-github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
@@ -63,8 +63,8 @@ github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYe
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
-github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
+github.com/skeema/knownhosts v1.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE=
+github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -73,29 +73,24 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
-golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
-golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
+golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
+golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -113,25 +108,21 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
-golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
@@ -139,7 +130,6 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -154,4 +144,3 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/options.go b/options.go
index 8b26022..6d802d1 100644
--- a/options.go
+++ b/options.go
@@ -643,6 +643,8 @@ type ListOptions struct {
PeelingOption PeelingOption
// ProxyOptions provides info required for connecting to a proxy.
ProxyOptions transport.ProxyOptions
+ // Timeout specifies the timeout in seconds for list operations
+ Timeout int
}
// PeelingOption represents the different ways to handle peeled references.
diff --git a/plumbing/format/gitattributes/attributes.go b/plumbing/format/gitattributes/attributes.go
index 329e667..d36ec1b 100644
--- a/plumbing/format/gitattributes/attributes.go
+++ b/plumbing/format/gitattributes/attributes.go
@@ -3,7 +3,6 @@ package gitattributes
import (
"errors"
"io"
- "io/ioutil"
"strings"
)
@@ -89,7 +88,7 @@ func (a attribute) String() string {
// ReadAttributes reads patterns and attributes from the gitattributes format.
func ReadAttributes(r io.Reader, domain []string, allowMacro bool) (attributes []MatchAttribute, err error) {
- data, err := ioutil.ReadAll(r)
+ data, err := io.ReadAll(r)
if err != nil {
return nil, err
}
diff --git a/plumbing/format/gitignore/dir.go b/plumbing/format/gitignore/dir.go
index 15bc9c7..3c4469a 100644
--- a/plumbing/format/gitignore/dir.go
+++ b/plumbing/format/gitignore/dir.go
@@ -3,8 +3,9 @@ package gitignore
import (
"bufio"
"bytes"
- "io/ioutil"
+ "io"
"os"
+ "os/user"
"strings"
"github.com/go-git/go-billy/v5"
@@ -25,6 +26,23 @@ const (
// readIgnoreFile reads a specific git ignore file.
func readIgnoreFile(fs billy.Filesystem, path []string, ignoreFile string) (ps []Pattern, err error) {
+
+ if strings.HasPrefix(ignoreFile, "~") {
+ firstSlash := strings.Index(ignoreFile, "/")
+ if firstSlash == 1 {
+ home, err := os.UserHomeDir()
+ if err == nil {
+ ignoreFile = strings.Replace(ignoreFile, "~", home, 1)
+ }
+ } else if firstSlash > 1 {
+ username := ignoreFile[1:firstSlash]
+ userAccount, err := user.Lookup(username)
+ if err == nil {
+ ignoreFile = strings.Replace(ignoreFile, ignoreFile[:firstSlash], userAccount.HomeDir, 1)
+ }
+ }
+ }
+
f, err := fs.Open(fs.Join(append(path, ignoreFile)...))
if err == nil {
defer f.Close()
@@ -86,7 +104,7 @@ func loadPatterns(fs billy.Filesystem, path string) (ps []Pattern, err error) {
defer gioutil.CheckClose(f, &err)
- b, err := ioutil.ReadAll(f)
+ b, err := io.ReadAll(f)
if err != nil {
return
}
diff --git a/plumbing/format/gitignore/dir_test.go b/plumbing/format/gitignore/dir_test.go
index facc36d..465c571 100644
--- a/plumbing/format/gitignore/dir_test.go
+++ b/plumbing/format/gitignore/dir_test.go
@@ -2,7 +2,9 @@ package gitignore
import (
"os"
+ "os/user"
"strconv"
+ "strings"
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/memfs"
@@ -12,6 +14,8 @@ import (
type MatcherSuite struct {
GFS billy.Filesystem // git repository root
RFS billy.Filesystem // root that contains user home
+ RFSR billy.Filesystem // root that contains user home, but with relative ~/.gitignore_global
+ RFSU billy.Filesystem // root that contains user home, but with relative ~user/.gitignore_global
MCFS billy.Filesystem // root that contains user home, but missing ~/.gitconfig
MEFS billy.Filesystem // root that contains user home, but missing excludesfile entry
MIFS billy.Filesystem // root that contains user home, but missing .gitignore
@@ -63,6 +67,27 @@ func (s *MatcherSuite) SetUpTest(c *C) {
err = fs.MkdirAll("vendor/gopkg.in", os.ModePerm)
c.Assert(err, IsNil)
+ err = fs.MkdirAll("multiple/sub/ignores/first", os.ModePerm)
+ c.Assert(err, IsNil)
+ err = fs.MkdirAll("multiple/sub/ignores/second", os.ModePerm)
+ c.Assert(err, IsNil)
+ f, err = fs.Create("multiple/sub/ignores/first/.gitignore")
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("ignore_dir\n"))
+ c.Assert(err, IsNil)
+ err = f.Close()
+ c.Assert(err, IsNil)
+ f, err = fs.Create("multiple/sub/ignores/second/.gitignore")
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("ignore_dir\n"))
+ c.Assert(err, IsNil)
+ err = f.Close()
+ c.Assert(err, IsNil)
+ err = fs.MkdirAll("multiple/sub/ignores/first/ignore_dir", os.ModePerm)
+ c.Assert(err, IsNil)
+ err = fs.MkdirAll("multiple/sub/ignores/second/ignore_dir", os.ModePerm)
+ c.Assert(err, IsNil)
+
s.GFS = fs
// setup root that contains user home
@@ -95,6 +120,64 @@ func (s *MatcherSuite) SetUpTest(c *C) {
s.RFS = fs
+ // root that contains user home, but with relative ~/.gitignore_global
+ fs = memfs.New()
+ err = fs.MkdirAll(home, os.ModePerm)
+ c.Assert(err, IsNil)
+
+ f, err = fs.Create(fs.Join(home, gitconfigFile))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("[core]\n"))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte(" excludesfile = ~/.gitignore_global" + "\n"))
+ c.Assert(err, IsNil)
+ err = f.Close()
+ c.Assert(err, IsNil)
+
+ f, err = fs.Create(fs.Join(home, ".gitignore_global"))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("# IntelliJ\n"))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte(".idea/\n"))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("*.iml\n"))
+ c.Assert(err, IsNil)
+ err = f.Close()
+ c.Assert(err, IsNil)
+
+ s.RFSR = fs
+
+ // root that contains user home, but with relative ~user/.gitignore_global
+ fs = memfs.New()
+ err = fs.MkdirAll(home, os.ModePerm)
+ c.Assert(err, IsNil)
+
+ f, err = fs.Create(fs.Join(home, gitconfigFile))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("[core]\n"))
+ c.Assert(err, IsNil)
+ currentUser, err := user.Current()
+ c.Assert(err, IsNil)
+ // remove domain for windows
+ username := currentUser.Username[strings.Index(currentUser.Username, "\\")+1:]
+ _, err = f.Write([]byte(" excludesfile = ~" + username + "/.gitignore_global" + "\n"))
+ c.Assert(err, IsNil)
+ err = f.Close()
+ c.Assert(err, IsNil)
+
+ f, err = fs.Create(fs.Join(home, ".gitignore_global"))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("# IntelliJ\n"))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte(".idea/\n"))
+ c.Assert(err, IsNil)
+ _, err = f.Write([]byte("*.iml\n"))
+ c.Assert(err, IsNil)
+ err = f.Close()
+ c.Assert(err, IsNil)
+
+ s.RFSU = fs
+
// root that contains user home, but missing ~/.gitconfig
fs = memfs.New()
err = fs.MkdirAll(home, os.ModePerm)
@@ -183,15 +266,39 @@ func (s *MatcherSuite) SetUpTest(c *C) {
}
func (s *MatcherSuite) TestDir_ReadPatterns(c *C) {
+ checkPatterns := func(ps []Pattern) {
+ c.Assert(ps, HasLen, 6)
+ m := NewMatcher(ps)
+
+ c.Assert(m.Match([]string{"exclude.crlf"}, true), Equals, true)
+ c.Assert(m.Match([]string{"ignore.crlf"}, true), Equals, true)
+ c.Assert(m.Match([]string{"vendor", "gopkg.in"}, true), Equals, true)
+ c.Assert(m.Match([]string{"vendor", "github.com"}, true), Equals, false)
+ c.Assert(m.Match([]string{"multiple", "sub", "ignores", "first", "ignore_dir"}, true), Equals, true)
+ c.Assert(m.Match([]string{"multiple", "sub", "ignores", "second", "ignore_dir"}, true), Equals, true)
+ }
+
ps, err := ReadPatterns(s.GFS, nil)
c.Assert(err, IsNil)
- c.Assert(ps, HasLen, 4)
+ checkPatterns(ps)
- m := NewMatcher(ps)
- c.Assert(m.Match([]string{"exclude.crlf"}, true), Equals, true)
- c.Assert(m.Match([]string{"ignore.crlf"}, true), Equals, true)
- c.Assert(m.Match([]string{"vendor", "gopkg.in"}, true), Equals, true)
- c.Assert(m.Match([]string{"vendor", "github.com"}, true), Equals, false)
+ // passing an empty slice with capacity to check we don't hit a bug where the extra capacity is reused incorrectly
+ ps, err = ReadPatterns(s.GFS, make([]string, 0, 6))
+ c.Assert(err, IsNil)
+ checkPatterns(ps)
+}
+
+func (s *MatcherSuite) TestDir_ReadRelativeGlobalGitIgnore(c *C) {
+ for _, fs := range []billy.Filesystem{s.RFSR, s.RFSU} {
+ ps, err := LoadGlobalPatterns(fs)
+ c.Assert(err, IsNil)
+ c.Assert(ps, HasLen, 2)
+
+ m := NewMatcher(ps)
+ c.Assert(m.Match([]string{".idea/"}, true), Equals, false)
+ c.Assert(m.Match([]string{"*.iml"}, true), Equals, true)
+ c.Assert(m.Match([]string{"IntelliJ"}, true), Equals, false)
+ }
}
func (s *MatcherSuite) TestDir_LoadGlobalPatterns(c *C) {
diff --git a/plumbing/format/gitignore/pattern.go b/plumbing/format/gitignore/pattern.go
index 098cb50..450b3cd 100644
--- a/plumbing/format/gitignore/pattern.go
+++ b/plumbing/format/gitignore/pattern.go
@@ -39,6 +39,8 @@ type pattern struct {
// ParsePattern parses a gitignore pattern string into the Pattern structure.
func ParsePattern(p string, domain []string) Pattern {
+ // storing domain, copy it to ensure it isn't changed externally
+ domain = append([]string(nil), domain...)
res := pattern{domain: domain}
if strings.HasPrefix(p, inclusionPrefix) {
diff --git a/plumbing/format/idxfile/decoder_test.go b/plumbing/format/idxfile/decoder_test.go
index 94059cc..2c4a801 100644
--- a/plumbing/format/idxfile/decoder_test.go
+++ b/plumbing/format/idxfile/decoder_test.go
@@ -5,7 +5,6 @@ import (
"encoding/base64"
"fmt"
"io"
- "io/ioutil"
"testing"
"github.com/go-git/go-git/v5/plumbing"
@@ -119,7 +118,7 @@ ch2xUA==
func BenchmarkDecode(b *testing.B) {
f := fixtures.Basic().One()
- fixture, err := ioutil.ReadAll(f.Idx())
+ fixture, err := io.ReadAll(f.Idx())
if err != nil {
b.Errorf("unexpected error reading idx file: %s", err)
}
diff --git a/plumbing/format/idxfile/encoder_test.go b/plumbing/format/idxfile/encoder_test.go
index 32b60f9..b8ece83 100644
--- a/plumbing/format/idxfile/encoder_test.go
+++ b/plumbing/format/idxfile/encoder_test.go
@@ -2,7 +2,7 @@ package idxfile_test
import (
"bytes"
- "io/ioutil"
+ "io"
. "github.com/go-git/go-git/v5/plumbing/format/idxfile"
@@ -12,7 +12,7 @@ import (
func (s *IdxfileSuite) TestDecodeEncode(c *C) {
fixtures.ByTag("packfile").Test(c, func(f *fixtures.Fixture) {
- expected, err := ioutil.ReadAll(f.Idx())
+ expected, err := io.ReadAll(f.Idx())
c.Assert(err, IsNil)
idx := new(MemoryIndex)
diff --git a/plumbing/format/idxfile/writer.go b/plumbing/format/idxfile/writer.go
index daa1605..c4c21e1 100644
--- a/plumbing/format/idxfile/writer.go
+++ b/plumbing/format/idxfile/writer.go
@@ -84,11 +84,8 @@ func (w *Writer) OnFooter(h plumbing.Hash) error {
w.checksum = h
w.finished = true
_, err := w.createIndex()
- if err != nil {
- return err
- }
- return nil
+ return err
}
// creatIndex returns a filled MemoryIndex with the information filled by
@@ -139,15 +136,23 @@ func (w *Writer) createIndex() (*MemoryIndex, error) {
offset := o.Offset
if offset > math.MaxInt32 {
- offset = w.addOffset64(offset)
+ var err error
+ offset, err = w.addOffset64(offset)
+ if err != nil {
+ return nil, err
+ }
}
buf.Truncate(0)
- binary.WriteUint32(buf, uint32(offset))
+ if err := binary.WriteUint32(buf, uint32(offset)); err != nil {
+ return nil, err
+ }
idx.Offset32[bucket] = append(idx.Offset32[bucket], buf.Bytes()...)
buf.Truncate(0)
- binary.WriteUint32(buf, o.CRC32)
+ if err := binary.WriteUint32(buf, o.CRC32); err != nil {
+ return nil, err
+ }
idx.CRC32[bucket] = append(idx.CRC32[bucket], buf.Bytes()...)
}
@@ -161,15 +166,17 @@ func (w *Writer) createIndex() (*MemoryIndex, error) {
return idx, nil
}
-func (w *Writer) addOffset64(pos uint64) uint64 {
+func (w *Writer) addOffset64(pos uint64) (uint64, error) {
buf := new(bytes.Buffer)
- binary.WriteUint64(buf, pos)
- w.index.Offset64 = append(w.index.Offset64, buf.Bytes()...)
+ if err := binary.WriteUint64(buf, pos); err != nil {
+ return 0, err
+ }
+ w.index.Offset64 = append(w.index.Offset64, buf.Bytes()...)
index := uint64(w.offset64 | (1 << 31))
w.offset64++
- return index
+ return index, nil
}
func (o objects) Len() int {
diff --git a/plumbing/format/idxfile/writer_test.go b/plumbing/format/idxfile/writer_test.go
index fba3e42..eaa8605 100644
--- a/plumbing/format/idxfile/writer_test.go
+++ b/plumbing/format/idxfile/writer_test.go
@@ -3,7 +3,7 @@ package idxfile_test
import (
"bytes"
"encoding/base64"
- "io/ioutil"
+ "io"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/idxfile"
@@ -34,7 +34,7 @@ func (s *WriterSuite) TestWriter(c *C) {
c.Assert(err, IsNil)
idxFile := f.Idx()
- expected, err := ioutil.ReadAll(idxFile)
+ expected, err := io.ReadAll(idxFile)
c.Assert(err, IsNil)
idxFile.Close()
@@ -65,7 +65,7 @@ func (s *WriterSuite) TestWriterLarge(c *C) {
// load fixture index
f := bytes.NewBufferString(fixtureLarge4GB)
- expected, err := ioutil.ReadAll(base64.NewDecoder(base64.StdEncoding, f))
+ expected, err := io.ReadAll(base64.NewDecoder(base64.StdEncoding, f))
c.Assert(err, IsNil)
buf := new(bytes.Buffer)
diff --git a/plumbing/format/index/decoder.go b/plumbing/format/index/decoder.go
index 8834e25..6778cf7 100644
--- a/plumbing/format/index/decoder.go
+++ b/plumbing/format/index/decoder.go
@@ -5,7 +5,7 @@ import (
"bytes"
"errors"
"io"
- "io/ioutil"
+
"strconv"
"time"
@@ -201,7 +201,7 @@ func (d *Decoder) padEntry(idx *Index, e *Entry, read int) error {
entrySize := read + len(e.Name)
padLen := 8 - entrySize%8
- _, err := io.CopyN(ioutil.Discard, d.r, int64(padLen))
+ _, err := io.CopyN(io.Discard, d.r, int64(padLen))
return err
}
diff --git a/plumbing/format/objfile/reader_test.go b/plumbing/format/objfile/reader_test.go
index d697d54..5526f7f 100644
--- a/plumbing/format/objfile/reader_test.go
+++ b/plumbing/format/objfile/reader_test.go
@@ -5,7 +5,6 @@ import (
"encoding/base64"
"fmt"
"io"
- "io/ioutil"
"github.com/go-git/go-git/v5/plumbing"
@@ -36,7 +35,7 @@ func testReader(c *C, source io.Reader, hash plumbing.Hash, t plumbing.ObjectTyp
c.Assert(typ, Equals, t)
c.Assert(content, HasLen, int(size))
- rc, err := ioutil.ReadAll(r)
+ rc, err := io.ReadAll(r)
c.Assert(err, IsNil)
c.Assert(rc, DeepEquals, content, Commentf("%scontent=%s, expected=%s", base64.StdEncoding.EncodeToString(rc), base64.StdEncoding.EncodeToString(content)))
diff --git a/plumbing/format/packfile/delta_test.go b/plumbing/format/packfile/delta_test.go
index 137e485..e8f5ea6 100644
--- a/plumbing/format/packfile/delta_test.go
+++ b/plumbing/format/packfile/delta_test.go
@@ -2,7 +2,7 @@ package packfile
import (
"bytes"
- "io/ioutil"
+ "io"
"math/rand"
"github.com/go-git/go-git/v5/plumbing"
@@ -109,14 +109,14 @@ func (s *DeltaSuite) TestAddDeltaReader(c *C) {
targetBuf := genBytes(t.target)
delta := DiffDelta(baseBuf, targetBuf)
- deltaRC := ioutil.NopCloser(bytes.NewReader(delta))
+ deltaRC := io.NopCloser(bytes.NewReader(delta))
c.Log("Executing test case:", t.description)
resultRC, err := ReaderFromDelta(baseObj, deltaRC)
c.Assert(err, IsNil)
- result, err := ioutil.ReadAll(resultRC)
+ result, err := io.ReadAll(resultRC)
c.Assert(err, IsNil)
err = resultRC.Close()
@@ -164,12 +164,12 @@ func (s *DeltaSuite) TestMaxCopySizeDeltaReader(c *C) {
targetBuf = append(targetBuf, byte(1))
delta := DiffDelta(baseBuf, targetBuf)
- deltaRC := ioutil.NopCloser(bytes.NewReader(delta))
+ deltaRC := io.NopCloser(bytes.NewReader(delta))
resultRC, err := ReaderFromDelta(baseObj, deltaRC)
c.Assert(err, IsNil)
- result, err := ioutil.ReadAll(resultRC)
+ result, err := io.ReadAll(resultRC)
c.Assert(err, IsNil)
err = resultRC.Close()
diff --git a/plumbing/format/packfile/encoder.go b/plumbing/format/packfile/encoder.go
index c9d19b3..804f5a8 100644
--- a/plumbing/format/packfile/encoder.go
+++ b/plumbing/format/packfile/encoder.go
@@ -131,11 +131,7 @@ func (e *Encoder) entry(o *ObjectToPack) (err error) {
defer ioutil.CheckClose(or, &err)
_, err = io.Copy(e.zw, or)
- if err != nil {
- return err
- }
-
- return nil
+ return err
}
func (e *Encoder) writeBaseIfDelta(o *ObjectToPack) error {
diff --git a/plumbing/format/packfile/encoder_test.go b/plumbing/format/packfile/encoder_test.go
index 902d8cc..6719f37 100644
--- a/plumbing/format/packfile/encoder_test.go
+++ b/plumbing/format/packfile/encoder_test.go
@@ -3,7 +3,6 @@ package packfile
import (
"bytes"
"io"
- stdioutil "io/ioutil"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/idxfile"
@@ -278,13 +277,13 @@ func objectsEqual(c *C, o1, o2 plumbing.EncodedObject) {
r1, err := o1.Reader()
c.Assert(err, IsNil)
- b1, err := stdioutil.ReadAll(r1)
+ b1, err := io.ReadAll(r1)
c.Assert(err, IsNil)
r2, err := o2.Reader()
c.Assert(err, IsNil)
- b2, err := stdioutil.ReadAll(r2)
+ b2, err := io.ReadAll(r2)
c.Assert(err, IsNil)
c.Assert(bytes.Compare(b1, b2), Equals, 0)
diff --git a/plumbing/format/packfile/parser.go b/plumbing/format/packfile/parser.go
index 6012b04..edbc0e7 100644
--- a/plumbing/format/packfile/parser.go
+++ b/plumbing/format/packfile/parser.go
@@ -4,7 +4,6 @@ import (
"bytes"
"errors"
"io"
- stdioutil "io/ioutil"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/cache"
@@ -297,7 +296,7 @@ func (p *Parser) resolveDeltas() error {
if !obj.IsDelta() && len(obj.Children) > 0 {
for _, child := range obj.Children {
- if err := p.resolveObject(stdioutil.Discard, child, content); err != nil {
+ if err := p.resolveObject(io.Discard, child, content); err != nil {
return err
}
p.resolveExternalRef(child)
diff --git a/plumbing/format/packfile/scanner.go b/plumbing/format/packfile/scanner.go
index 9ebb84a..730343e 100644
--- a/plumbing/format/packfile/scanner.go
+++ b/plumbing/format/packfile/scanner.go
@@ -7,7 +7,6 @@ import (
"hash"
"hash/crc32"
"io"
- stdioutil "io/ioutil"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/utils/binary"
@@ -242,7 +241,7 @@ func (s *Scanner) discardObjectIfNeeded() error {
}
h := s.pendingObject
- n, _, err := s.NextObject(stdioutil.Discard)
+ n, _, err := s.NextObject(io.Discard)
if err != nil {
return err
}
@@ -381,7 +380,7 @@ func (s *Scanner) Checksum() (plumbing.Hash, error) {
// Close reads the reader until io.EOF
func (s *Scanner) Close() error {
buf := sync.GetByteSlice()
- _, err := io.CopyBuffer(stdioutil.Discard, s.r, *buf)
+ _, err := io.CopyBuffer(io.Discard, s.r, *buf)
sync.PutByteSlice(buf)
return err
diff --git a/plumbing/memory_test.go b/plumbing/memory_test.go
index 2a141f4..f76b4f4 100644
--- a/plumbing/memory_test.go
+++ b/plumbing/memory_test.go
@@ -2,7 +2,6 @@ package plumbing
import (
"io"
- "io/ioutil"
. "gopkg.in/check.v1"
)
@@ -52,7 +51,7 @@ func (s *MemoryObjectSuite) TestReader(c *C) {
c.Assert(err, IsNil)
defer func() { c.Assert(reader.Close(), IsNil) }()
- b, err := ioutil.ReadAll(reader)
+ b, err := io.ReadAll(reader)
c.Assert(err, IsNil)
c.Assert(b, DeepEquals, []byte("foo"))
}
@@ -75,7 +74,7 @@ func (s *MemoryObjectSuite) TestSeekableReader(c *C) {
_, err = rs.Seek(pageSize, io.SeekStart)
c.Assert(err, IsNil)
- b, err := ioutil.ReadAll(rs)
+ b, err := io.ReadAll(rs)
c.Assert(err, IsNil)
c.Assert(b, DeepEquals, []byte(payload))
diff --git a/plumbing/object/blob_test.go b/plumbing/object/blob_test.go
index 4461343..9481dbe 100644
--- a/plumbing/object/blob_test.go
+++ b/plumbing/object/blob_test.go
@@ -3,7 +3,6 @@ package object
import (
"bytes"
"io"
- "io/ioutil"
"github.com/go-git/go-git/v5/plumbing"
@@ -37,7 +36,7 @@ func (s *BlobsSuite) TestBlobHash(c *C) {
c.Assert(err, IsNil)
defer func() { c.Assert(reader.Close(), IsNil) }()
- data, err := ioutil.ReadAll(reader)
+ data, err := io.ReadAll(reader)
c.Assert(err, IsNil)
c.Assert(string(data), Equals, "FOO")
}
@@ -96,14 +95,14 @@ func (s *BlobsSuite) TestBlobIter(c *C) {
r1, err := b.Reader()
c.Assert(err, IsNil)
- b1, err := ioutil.ReadAll(r1)
+ b1, err := io.ReadAll(r1)
c.Assert(err, IsNil)
c.Assert(r1.Close(), IsNil)
r2, err := blobs[i].Reader()
c.Assert(err, IsNil)
- b2, err := ioutil.ReadAll(r2)
+ b2, err := io.ReadAll(r2)
c.Assert(err, IsNil)
c.Assert(r2.Close(), IsNil)
diff --git a/plumbing/object/commit_test.go b/plumbing/object/commit_test.go
index 468a751..a939bc6 100644
--- a/plumbing/object/commit_test.go
+++ b/plumbing/object/commit_test.go
@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"io"
- "io/ioutil"
"strings"
"time"
@@ -449,7 +448,7 @@ YIefGtzXfldDxg4=
`
e, err := commit.Verify(armoredKeyRing)
- c.Assert(err, IsNil)
+ c.Assert(err, IsNil)
_, ok := e.Identities["go-git test key"]
c.Assert(ok, Equals, true)
@@ -492,7 +491,7 @@ func (s *SuiteCommit) TestEncodeWithoutSignature(c *C) {
c.Assert(err, IsNil)
er, err := encoded.Reader()
c.Assert(err, IsNil)
- payload, err := ioutil.ReadAll(er)
+ payload, err := io.ReadAll(er)
c.Assert(err, IsNil)
c.Assert(string(payload), Equals, ""+
diff --git a/plumbing/object/object_test.go b/plumbing/object/object_test.go
index 6c95eef..c4fdb4c 100644
--- a/plumbing/object/object_test.go
+++ b/plumbing/object/object_test.go
@@ -2,7 +2,6 @@ package object
import (
"io"
- "io/ioutil"
"testing"
"time"
@@ -103,7 +102,7 @@ func (s *ObjectsSuite) TestParseTree(c *C) {
reader, err := f.Reader()
c.Assert(err, IsNil)
defer func() { c.Assert(reader.Close(), IsNil) }()
- content, _ := ioutil.ReadAll(reader)
+ content, _ := io.ReadAll(reader)
c.Assert(content, HasLen, 2780)
}
}
diff --git a/plumbing/object/rename.go b/plumbing/object/rename.go
index 0394613..ad2b902 100644
--- a/plumbing/object/rename.go
+++ b/plumbing/object/rename.go
@@ -741,10 +741,7 @@ func (i *similarityIndex) add(key int, cnt uint64) error {
// 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
+ return err
} else if j+1 >= len(i.hashes) {
j = 0
} else {
diff --git a/plumbing/object/tag_test.go b/plumbing/object/tag_test.go
index 15b943e..d374c6c 100644
--- a/plumbing/object/tag_test.go
+++ b/plumbing/object/tag_test.go
@@ -3,7 +3,6 @@ package object
import (
"fmt"
"io"
- "io/ioutil"
"strings"
"time"
@@ -466,7 +465,7 @@ func (s *TagSuite) TestEncodeWithoutSignature(c *C) {
c.Assert(err, IsNil)
er, err := encoded.Reader()
c.Assert(err, IsNil)
- payload, err := ioutil.ReadAll(er)
+ payload, err := io.ReadAll(er)
c.Assert(err, IsNil)
c.Assert(string(payload), Equals, ""+
diff --git a/plumbing/protocol/packp/advrefs.go b/plumbing/protocol/packp/advrefs.go
index 1bd724c..f93ad30 100644
--- a/plumbing/protocol/packp/advrefs.go
+++ b/plumbing/protocol/packp/advrefs.go
@@ -57,7 +57,7 @@ func (a *AdvRefs) AddReference(r *plumbing.Reference) error {
switch r.Type() {
case plumbing.SymbolicReference:
v := fmt.Sprintf("%s:%s", r.Name().String(), r.Target().String())
- a.Capabilities.Add(capability.SymRef, v)
+ return a.Capabilities.Add(capability.SymRef, v)
case plumbing.HashReference:
a.References[r.Name().String()] = r.Hash()
default:
@@ -96,12 +96,12 @@ func (a *AdvRefs) addRefs(s storer.ReferenceStorer) error {
//
// Git versions prior to 1.8.4.3 has an special procedure to get
// the reference where is pointing to HEAD:
-// - Check if a reference called master exists. If exists and it
-// has the same hash as HEAD hash, we can say that HEAD is pointing to master
-// - If master does not exists or does not have the same hash as HEAD,
-// order references and check in that order if that reference has the same
-// hash than HEAD. If yes, set HEAD pointing to that branch hash
-// - If no reference is found, throw an error
+// - Check if a reference called master exists. If exists and it
+// has the same hash as HEAD hash, we can say that HEAD is pointing to master
+// - If master does not exists or does not have the same hash as HEAD,
+// order references and check in that order if that reference has the same
+// hash than HEAD. If yes, set HEAD pointing to that branch hash
+// - If no reference is found, throw an error
func (a *AdvRefs) resolveHead(s storer.ReferenceStorer) error {
if a.Head == nil {
return nil
diff --git a/plumbing/protocol/packp/sideband/demux_test.go b/plumbing/protocol/packp/sideband/demux_test.go
index 6cda703..8f23353 100644
--- a/plumbing/protocol/packp/sideband/demux_test.go
+++ b/plumbing/protocol/packp/sideband/demux_test.go
@@ -4,7 +4,6 @@ import (
"bytes"
"errors"
"io"
- "io/ioutil"
"testing"
"github.com/go-git/go-git/v5/plumbing/format/pktline"
@@ -101,7 +100,7 @@ func (s *SidebandSuite) TestDecodeWithProgress(c *C) {
c.Assert(n, Equals, 26)
c.Assert(content, DeepEquals, expected)
- progress, err := ioutil.ReadAll(output)
+ progress, err := io.ReadAll(output)
c.Assert(err, IsNil)
c.Assert(progress, DeepEquals, []byte{'F', 'O', 'O', '\n'})
}
diff --git a/plumbing/protocol/packp/updreq_decode.go b/plumbing/protocol/packp/updreq_decode.go
index 2c9843a..076de54 100644
--- a/plumbing/protocol/packp/updreq_decode.go
+++ b/plumbing/protocol/packp/updreq_decode.go
@@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/pktline"
@@ -81,7 +80,7 @@ func (req *ReferenceUpdateRequest) Decode(r io.Reader) error {
var ok bool
rc, ok = r.(io.ReadCloser)
if !ok {
- rc = ioutil.NopCloser(r)
+ rc = io.NopCloser(r)
}
d := &updReqDecoder{r: rc, s: pktline.NewScanner(r)}
diff --git a/plumbing/protocol/packp/updreq_decode_test.go b/plumbing/protocol/packp/updreq_decode_test.go
index 2630112..bdcbdf5 100644
--- a/plumbing/protocol/packp/updreq_decode_test.go
+++ b/plumbing/protocol/packp/updreq_decode_test.go
@@ -3,7 +3,6 @@ package packp
import (
"bytes"
"io"
- "io/ioutil"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/pktline"
@@ -157,7 +156,7 @@ func (s *UpdReqDecodeSuite) TestOneUpdateCommand(c *C) {
expected.Commands = []*Command{
{Name: name, Old: hash1, New: hash2},
}
- expected.Packfile = ioutil.NopCloser(bytes.NewReader([]byte{}))
+ expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))
payloads := []string{
"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
@@ -177,7 +176,7 @@ func (s *UpdReqDecodeSuite) TestMultipleCommands(c *C) {
{Name: plumbing.ReferenceName("myref2"), Old: plumbing.ZeroHash, New: hash2},
{Name: plumbing.ReferenceName("myref3"), Old: hash1, New: plumbing.ZeroHash},
}
- expected.Packfile = ioutil.NopCloser(bytes.NewReader([]byte{}))
+ expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))
payloads := []string{
"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref1\x00",
@@ -200,7 +199,7 @@ func (s *UpdReqDecodeSuite) TestMultipleCommandsAndCapabilities(c *C) {
{Name: plumbing.ReferenceName("myref3"), Old: hash1, New: plumbing.ZeroHash},
}
expected.Capabilities.Add("shallow")
- expected.Packfile = ioutil.NopCloser(bytes.NewReader([]byte{}))
+ expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))
payloads := []string{
"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref1\x00shallow",
@@ -224,7 +223,7 @@ func (s *UpdReqDecodeSuite) TestMultipleCommandsAndCapabilitiesShallow(c *C) {
}
expected.Capabilities.Add("shallow")
expected.Shallow = &hash1
- expected.Packfile = ioutil.NopCloser(bytes.NewReader([]byte{}))
+ expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))
payloads := []string{
"shallow 1ecf0ef2c2dffb796033e5a02219af86ec6584e5",
@@ -247,7 +246,7 @@ func (s *UpdReqDecodeSuite) TestWithPackfile(c *C) {
{Name: name, Old: hash1, New: hash2},
}
packfileContent := []byte("PACKabc")
- expected.Packfile = ioutil.NopCloser(bytes.NewReader(packfileContent))
+ expected.Packfile = io.NopCloser(bytes.NewReader(packfileContent))
payloads := []string{
"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
@@ -298,10 +297,10 @@ func (s *UpdReqDecodeSuite) testDecodeOkExpected(c *C, expected *ReferenceUpdate
}
func (s *UpdReqDecodeSuite) compareReaders(c *C, a io.ReadCloser, b io.ReadCloser) {
- pba, err := ioutil.ReadAll(a)
+ pba, err := io.ReadAll(a)
c.Assert(err, IsNil)
c.Assert(a.Close(), IsNil)
- pbb, err := ioutil.ReadAll(b)
+ pbb, err := io.ReadAll(b)
c.Assert(err, IsNil)
c.Assert(b.Close(), IsNil)
c.Assert(pba, DeepEquals, pbb)
diff --git a/plumbing/protocol/packp/updreq_encode_test.go b/plumbing/protocol/packp/updreq_encode_test.go
index 4370b79..97868bd 100644
--- a/plumbing/protocol/packp/updreq_encode_test.go
+++ b/plumbing/protocol/packp/updreq_encode_test.go
@@ -2,13 +2,12 @@ package packp
import (
"bytes"
+ "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"
- "io/ioutil"
-
. "gopkg.in/check.v1"
)
@@ -128,7 +127,7 @@ func (s *UpdReqEncodeSuite) TestWithPackfile(c *C) {
packfileContent := []byte("PACKabc")
packfileReader := bytes.NewReader(packfileContent)
- packfileReadCloser := ioutil.NopCloser(packfileReader)
+ packfileReadCloser := io.NopCloser(packfileReader)
r := NewReferenceUpdateRequest()
r.Commands = []*Command{
diff --git a/plumbing/protocol/packp/uppackresp_test.go b/plumbing/protocol/packp/uppackresp_test.go
index 3f87804..8fbf924 100644
--- a/plumbing/protocol/packp/uppackresp_test.go
+++ b/plumbing/protocol/packp/uppackresp_test.go
@@ -2,7 +2,7 @@ package packp
import (
"bytes"
- "io/ioutil"
+ "io"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
@@ -21,10 +21,10 @@ func (s *UploadPackResponseSuite) TestDecodeNAK(c *C) {
res := NewUploadPackResponse(req)
defer res.Close()
- err := res.Decode(ioutil.NopCloser(bytes.NewBufferString(raw)))
+ err := res.Decode(io.NopCloser(bytes.NewBufferString(raw)))
c.Assert(err, IsNil)
- pack, err := ioutil.ReadAll(res)
+ pack, err := io.ReadAll(res)
c.Assert(err, IsNil)
c.Assert(pack, DeepEquals, []byte("PACK"))
}
@@ -38,10 +38,10 @@ func (s *UploadPackResponseSuite) TestDecodeDepth(c *C) {
res := NewUploadPackResponse(req)
defer res.Close()
- err := res.Decode(ioutil.NopCloser(bytes.NewBufferString(raw)))
+ err := res.Decode(io.NopCloser(bytes.NewBufferString(raw)))
c.Assert(err, IsNil)
- pack, err := ioutil.ReadAll(res)
+ pack, err := io.ReadAll(res)
c.Assert(err, IsNil)
c.Assert(pack, DeepEquals, []byte("PACK"))
}
@@ -55,7 +55,7 @@ func (s *UploadPackResponseSuite) TestDecodeMalformed(c *C) {
res := NewUploadPackResponse(req)
defer res.Close()
- err := res.Decode(ioutil.NopCloser(bytes.NewBufferString(raw)))
+ err := res.Decode(io.NopCloser(bytes.NewBufferString(raw)))
c.Assert(err, NotNil)
}
@@ -70,7 +70,7 @@ func (s *UploadPackResponseSuite) TestDecodeMultiACK(c *C) {
res := NewUploadPackResponse(req)
defer res.Close()
- err := res.Decode(ioutil.NopCloser(bytes.NewBuffer(nil)))
+ err := res.Decode(io.NopCloser(bytes.NewBuffer(nil)))
c.Assert(err, IsNil)
}
@@ -87,7 +87,7 @@ func (s *UploadPackResponseSuite) TestReadNoDecode(c *C) {
}
func (s *UploadPackResponseSuite) TestEncodeNAK(c *C) {
- pf := ioutil.NopCloser(bytes.NewBuffer([]byte("[PACK]")))
+ pf := io.NopCloser(bytes.NewBuffer([]byte("[PACK]")))
req := NewUploadPackRequest()
res := NewUploadPackResponseWithPackfile(req, pf)
defer func() { c.Assert(res.Close(), IsNil) }()
@@ -100,7 +100,7 @@ func (s *UploadPackResponseSuite) TestEncodeNAK(c *C) {
}
func (s *UploadPackResponseSuite) TestEncodeDepth(c *C) {
- pf := ioutil.NopCloser(bytes.NewBuffer([]byte("PACK")))
+ pf := io.NopCloser(bytes.NewBuffer([]byte("PACK")))
req := NewUploadPackRequest()
req.Depth = DepthCommits(1)
@@ -115,7 +115,7 @@ func (s *UploadPackResponseSuite) TestEncodeDepth(c *C) {
}
func (s *UploadPackResponseSuite) TestEncodeMultiACK(c *C) {
- pf := ioutil.NopCloser(bytes.NewBuffer([]byte("[PACK]")))
+ pf := io.NopCloser(bytes.NewBuffer([]byte("[PACK]")))
req := NewUploadPackRequest()
res := NewUploadPackResponseWithPackfile(req, pf)
diff --git a/plumbing/reference.go b/plumbing/reference.go
index eef11e8..5a67f69 100644
--- a/plumbing/reference.go
+++ b/plumbing/reference.go
@@ -15,10 +15,11 @@ const (
symrefPrefix = "ref: "
)
-// RefRevParseRules are a set of rules to parse references into short names.
-// These are the same rules as used by git in shorten_unambiguous_ref.
+// RefRevParseRules are a set of rules to parse references into short names, or expand into a full reference.
+// These are the same rules as used by git in shorten_unambiguous_ref and expand_ref.
// See: https://github.com/git/git/blob/e0aaa1b6532cfce93d87af9bc813fb2e7a7ce9d7/refs.c#L417
var RefRevParseRules = []string{
+ "%s",
"refs/%s",
"refs/tags/%s",
"refs/heads/%s",
@@ -113,7 +114,7 @@ func (r ReferenceName) String() string {
func (r ReferenceName) Short() string {
s := string(r)
res := s
- for _, format := range RefRevParseRules {
+ for _, format := range RefRevParseRules[1:] {
_, err := fmt.Sscanf(s, format, &res)
if err == nil {
continue
@@ -126,6 +127,7 @@ func (r ReferenceName) Short() string {
const (
HEAD ReferenceName = "HEAD"
Master ReferenceName = "refs/heads/master"
+ Main ReferenceName = "refs/heads/main"
)
// Reference is a representation of git reference
diff --git a/plumbing/transport/file/common_test.go b/plumbing/transport/file/common_test.go
index 4d6612b..7e033a8 100644
--- a/plumbing/transport/file/common_test.go
+++ b/plumbing/transport/file/common_test.go
@@ -1,7 +1,6 @@
package file
import (
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -25,7 +24,7 @@ func (s *CommonSuite) SetUpSuite(c *C) {
}
var err error
- s.tmpDir, err = ioutil.TempDir("", "")
+ s.tmpDir, err = os.MkdirTemp("", "")
c.Assert(err, IsNil)
s.ReceivePackBin = filepath.Join(s.tmpDir, "git-receive-pack")
s.UploadPackBin = filepath.Join(s.tmpDir, "git-upload-pack")
diff --git a/plumbing/transport/git/common.go b/plumbing/transport/git/common.go
index c18d600..92fc0be 100644
--- a/plumbing/transport/git/common.go
+++ b/plumbing/transport/git/common.go
@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net"
+ "strconv"
"github.com/go-git/go-git/v5/plumbing/format/pktline"
"github.com/go-git/go-git/v5/plumbing/transport"
@@ -69,7 +70,7 @@ func (c *command) getHostWithPort() string {
port = DefaultPort
}
- return fmt.Sprintf("%s:%d", host, port)
+ return net.JoinHostPort(host, strconv.Itoa(port))
}
// StderrPipe git protocol doesn't have any dedicated error channel
@@ -92,7 +93,7 @@ func (c *command) StdoutPipe() (io.Reader, error) {
func endpointToCommand(cmd string, ep *transport.Endpoint) string {
host := ep.Host
if ep.Port != DefaultPort {
- host = fmt.Sprintf("%s:%d", ep.Host, ep.Port)
+ host = net.JoinHostPort(ep.Host, strconv.Itoa(ep.Port))
}
return fmt.Sprintf("%s %s%chost=%s%c", cmd, ep.Path, 0, host, 0)
diff --git a/plumbing/transport/git/common_test.go b/plumbing/transport/git/common_test.go
index 3391aaf..7389919 100644
--- a/plumbing/transport/git/common_test.go
+++ b/plumbing/transport/git/common_test.go
@@ -2,7 +2,6 @@ package git
import (
"fmt"
- "io/ioutil"
"net"
"os"
"os/exec"
@@ -37,7 +36,7 @@ func (s *BaseSuite) SetUpTest(c *C) {
s.port, err = freePort()
c.Assert(err, IsNil)
- s.base, err = ioutil.TempDir(os.TempDir(), fmt.Sprintf("go-git-protocol-%d", s.port))
+ s.base, err = os.MkdirTemp(os.TempDir(), fmt.Sprintf("go-git-protocol-%d", s.port))
c.Assert(err, IsNil)
}
diff --git a/plumbing/transport/http/common_test.go b/plumbing/transport/http/common_test.go
index 41188e6..1517228 100644
--- a/plumbing/transport/http/common_test.go
+++ b/plumbing/transport/http/common_test.go
@@ -3,7 +3,6 @@ package http
import (
"crypto/tls"
"fmt"
- "io/ioutil"
"log"
"net"
"net/http"
@@ -222,7 +221,7 @@ func (s *BaseSuite) SetUpTest(c *C) {
l, err := net.Listen("tcp", "localhost:0")
c.Assert(err, IsNil)
- base, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("go-git-http-%d", s.port))
+ base, err := os.MkdirTemp(os.TempDir(), fmt.Sprintf("go-git-http-%d", s.port))
c.Assert(err, IsNil)
s.port = l.Addr().(*net.TCPAddr).Port
diff --git a/plumbing/transport/http/upload_pack_test.go b/plumbing/transport/http/upload_pack_test.go
index c088ecc..abb7adf 100644
--- a/plumbing/transport/http/upload_pack_test.go
+++ b/plumbing/transport/http/upload_pack_test.go
@@ -3,7 +3,7 @@ package http
import (
"context"
"fmt"
- "io/ioutil"
+ "io"
"net/url"
"os"
"path/filepath"
@@ -49,7 +49,7 @@ func (s *UploadPackSuite) TestuploadPackRequestToReader(c *C) {
sr, err := uploadPackRequestToReader(r)
c.Assert(err, IsNil)
- b, _ := ioutil.ReadAll(sr)
+ b, _ := io.ReadAll(sr)
c.Assert(string(b), Equals,
"0032want 2b41ef280fdb67a9b250678686a0c3e03b0a9989\n"+
"0032want d82f291cde9987322c8a0c81a325e1ba6159684c\n0000"+
diff --git a/plumbing/transport/internal/common/common.go b/plumbing/transport/internal/common/common.go
index b2c2fee..99e0850 100644
--- a/plumbing/transport/internal/common/common.go
+++ b/plumbing/transport/internal/common/common.go
@@ -11,7 +11,6 @@ import (
"errors"
"fmt"
"io"
- stdioutil "io/ioutil"
"strings"
"time"
@@ -156,7 +155,7 @@ func (c *client) listenFirstError(r io.Reader) chan string {
close(errLine)
}
- _, _ = io.Copy(stdioutil.Discard, r)
+ _, _ = io.Copy(io.Discard, r)
}()
return errLine
diff --git a/plumbing/transport/ssh/auth_method.go b/plumbing/transport/ssh/auth_method.go
index e89ce4b..ac4e358 100644
--- a/plumbing/transport/ssh/auth_method.go
+++ b/plumbing/transport/ssh/auth_method.go
@@ -3,7 +3,6 @@ package ssh
import (
"errors"
"fmt"
- "io/ioutil"
"os"
"os/user"
"path/filepath"
@@ -134,7 +133,7 @@ func NewPublicKeys(user string, pemBytes []byte, password string) (*PublicKeys,
// encoded private key. An encryption password should be given if the pemBytes
// contains a password encrypted PEM block otherwise password should be empty.
func NewPublicKeysFromFile(user, pemFile, password string) (*PublicKeys, error) {
- bytes, err := ioutil.ReadFile(pemFile)
+ bytes, err := os.ReadFile(pemFile)
if err != nil {
return nil, err
}
diff --git a/plumbing/transport/ssh/common.go b/plumbing/transport/ssh/common.go
index 6617d9b..1531603 100644
--- a/plumbing/transport/ssh/common.go
+++ b/plumbing/transport/ssh/common.go
@@ -212,7 +212,7 @@ func (c *command) getHostWithPort() string {
port = DefaultPort
}
- return fmt.Sprintf("%s:%d", host, port)
+ return net.JoinHostPort(host, strconv.Itoa(port))
}
func (c *command) doGetHostWithPortFromSSHConfig() (addr string, found bool) {
@@ -240,7 +240,7 @@ func (c *command) doGetHostWithPortFromSSHConfig() (addr string, found bool) {
}
}
- addr = fmt.Sprintf("%s:%d", host, port)
+ addr = net.JoinHostPort(host, strconv.Itoa(port))
return
}
diff --git a/plumbing/transport/ssh/internal/test/proxy_test.go b/plumbing/transport/ssh/internal/test/proxy_test.go
index 8baac2b..8e775f8 100644
--- a/plumbing/transport/ssh/internal/test/proxy_test.go
+++ b/plumbing/transport/ssh/internal/test/proxy_test.go
@@ -3,7 +3,6 @@ package test
import (
"context"
"fmt"
- "io/ioutil"
"log"
"net"
"os"
@@ -59,7 +58,7 @@ func (s *ProxyEnvSuite) TestCommand(c *C) {
}()
s.port = sshListener.Addr().(*net.TCPAddr).Port
- s.base, err = ioutil.TempDir(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.port))
+ s.base, err = os.MkdirTemp(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.port))
c.Assert(err, IsNil)
ggssh.DefaultAuthBuilder = func(user string) (ggssh.AuthMethod, error) {
diff --git a/plumbing/transport/ssh/proxy_test.go b/plumbing/transport/ssh/proxy_test.go
index 2fab851..2ba98e8 100644
--- a/plumbing/transport/ssh/proxy_test.go
+++ b/plumbing/transport/ssh/proxy_test.go
@@ -3,7 +3,6 @@ package ssh
import (
"context"
"fmt"
- "io/ioutil"
"log"
"net"
"os"
@@ -54,7 +53,7 @@ func (s *ProxySuite) TestCommand(c *C) {
}()
s.u.port = sshListener.Addr().(*net.TCPAddr).Port
- s.u.base, err = ioutil.TempDir(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.u.port))
+ s.u.base, err = os.MkdirTemp(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.u.port))
c.Assert(err, IsNil)
DefaultAuthBuilder = func(user string) (AuthMethod, error) {
diff --git a/plumbing/transport/ssh/upload_pack_test.go b/plumbing/transport/ssh/upload_pack_test.go
index fafff48..67af566 100644
--- a/plumbing/transport/ssh/upload_pack_test.go
+++ b/plumbing/transport/ssh/upload_pack_test.go
@@ -3,7 +3,6 @@ package ssh
import (
"fmt"
"io"
- "io/ioutil"
"log"
"net"
"os"
@@ -43,7 +42,7 @@ func (s *UploadPackSuite) SetUpSuite(c *C) {
c.Assert(err, IsNil)
s.port = l.Addr().(*net.TCPAddr).Port
- s.base, err = ioutil.TempDir(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.port))
+ s.base, err = os.MkdirTemp(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.port))
c.Assert(err, IsNil)
DefaultAuthBuilder = func(user string) (AuthMethod, error) {
diff --git a/plumbing/transport/test/receive_pack.go b/plumbing/transport/test/receive_pack.go
index 018d38e..9414fba 100644
--- a/plumbing/transport/test/receive_pack.go
+++ b/plumbing/transport/test/receive_pack.go
@@ -1,13 +1,11 @@
// Package test implements common test suite for different transport
// implementations.
-//
package test
import (
"bytes"
"context"
"io"
- "io/ioutil"
"os"
"path/filepath"
@@ -235,7 +233,7 @@ func (s *ReceivePackSuite) receivePackNoCheck(c *C, ep *transport.Endpoint,
if rootPath != "" && err == nil && stat.IsDir() {
objectPath := filepath.Join(rootPath, "objects/pack")
- files, err := ioutil.ReadDir(objectPath)
+ files, err := os.ReadDir(objectPath)
c.Assert(err, IsNil)
for _, file := range files {
@@ -371,5 +369,5 @@ func (s *ReceivePackSuite) emptyPackfile() io.ReadCloser {
panic(err)
}
- return ioutil.NopCloser(&buf)
+ return io.NopCloser(&buf)
}
diff --git a/plumbing/transport/test/upload_pack.go b/plumbing/transport/test/upload_pack.go
index 3ee029d..f7842eb 100644
--- a/plumbing/transport/test/upload_pack.go
+++ b/plumbing/transport/test/upload_pack.go
@@ -1,13 +1,11 @@
// Package test implements common test suite for different transport
// implementations.
-//
package test
import (
"bytes"
"context"
"io"
- "io/ioutil"
"time"
"github.com/go-git/go-git/v5/plumbing"
@@ -154,7 +152,7 @@ func (s *UploadPackSuite) TestUploadPackWithContextOnRead(c *C) {
cancel()
- _, err = io.Copy(ioutil.Discard, reader)
+ _, err = io.Copy(io.Discard, reader)
c.Assert(err, NotNil)
err = reader.Close()
@@ -255,7 +253,7 @@ func (s *UploadPackSuite) TestFetchError(c *C) {
}
func (s *UploadPackSuite) checkObjectNumber(c *C, r io.Reader, n int) {
- b, err := ioutil.ReadAll(r)
+ b, err := io.ReadAll(r)
c.Assert(err, IsNil)
buf := bytes.NewBuffer(b)
storage := memory.NewStorage()
diff --git a/remote.go b/remote.go
index df26491..25ec093 100644
--- a/remote.go
+++ b/remote.go
@@ -445,7 +445,7 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
return nil, err
}
- refs, err := calculateRefs(o.RefSpecs, remoteRefs, o.Tags)
+ refs, specToRefs, err := calculateRefs(o.RefSpecs, remoteRefs, o.Tags)
if err != nil {
return nil, err
}
@@ -457,9 +457,9 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
}
}
- req.Wants, err = getWants(r.s, refs)
+ req.Wants, err = getWants(r.s, refs, o.Depth)
if len(req.Wants) > 0 {
- req.Haves, err = getHaves(localRefs, remoteRefs, r.s)
+ req.Haves, err = getHaves(localRefs, remoteRefs, r.s, o.Depth)
if err != nil {
return nil, err
}
@@ -469,7 +469,7 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
}
}
- updated, err := r.updateLocalReferenceStorage(o.RefSpecs, refs, remoteRefs, o.Tags, o.Force)
+ updated, err := r.updateLocalReferenceStorage(o.RefSpecs, refs, remoteRefs, specToRefs, o.Tags, o.Force)
if err != nil {
return nil, err
}
@@ -837,6 +837,7 @@ func getHavesFromRef(
remoteRefs map[plumbing.Hash]bool,
s storage.Storer,
haves map[plumbing.Hash]bool,
+ depth int,
) error {
h := ref.Hash()
if haves[h] {
@@ -862,7 +863,13 @@ func getHavesFromRef(
// commits from the history of each ref.
walker := object.NewCommitPreorderIter(commit, haves, nil)
toVisit := maxHavesToVisitPerRef
- return walker.ForEach(func(c *object.Commit) error {
+ // But only need up to the requested depth
+ if depth > 0 && depth < maxHavesToVisitPerRef {
+ toVisit = depth
+ }
+ // It is safe to ignore any error here as we are just trying to find the references that we already have
+ // An example of a legitimate failure is we have a shallow clone and don't have the previous commit(s)
+ _ = walker.ForEach(func(c *object.Commit) error {
haves[c.Hash] = true
toVisit--
// If toVisit starts out at 0 (indicating there is no
@@ -873,12 +880,15 @@ func getHavesFromRef(
}
return nil
})
+
+ return nil
}
func getHaves(
localRefs []*plumbing.Reference,
remoteRefStorer storer.ReferenceStorer,
s storage.Storer,
+ depth int,
) ([]plumbing.Hash, error) {
haves := map[plumbing.Hash]bool{}
@@ -899,7 +909,7 @@ func getHaves(
continue
}
- err = getHavesFromRef(ref, remoteRefs, s, haves)
+ err = getHavesFromRef(ref, remoteRefs, s, haves, depth)
if err != nil {
return nil, err
}
@@ -919,42 +929,41 @@ func calculateRefs(
spec []config.RefSpec,
remoteRefs storer.ReferenceStorer,
tagMode TagMode,
-) (memory.ReferenceStorage, error) {
+) (memory.ReferenceStorage, [][]*plumbing.Reference, error) {
if tagMode == AllTags {
spec = append(spec, refspecAllTags)
}
refs := make(memory.ReferenceStorage)
- for _, s := range spec {
- if err := doCalculateRefs(s, remoteRefs, refs); err != nil {
- return nil, err
+ // list of references matched for each spec
+ specToRefs := make([][]*plumbing.Reference, len(spec))
+ for i := range spec {
+ var err error
+ specToRefs[i], err = doCalculateRefs(spec[i], remoteRefs, refs)
+ if err != nil {
+ return nil, nil, err
}
}
- return refs, nil
+ return refs, specToRefs, nil
}
func doCalculateRefs(
s config.RefSpec,
remoteRefs storer.ReferenceStorer,
refs memory.ReferenceStorage,
-) error {
- iter, err := remoteRefs.IterReferences()
- if err != nil {
- return err
- }
+) ([]*plumbing.Reference, error) {
+ var refList []*plumbing.Reference
if s.IsExactSHA1() {
ref := plumbing.NewHashReference(s.Dst(""), plumbing.NewHash(s.Src()))
- return refs.SetReference(ref)
+
+ refList = append(refList, ref)
+ return refList, refs.SetReference(ref)
}
var matched bool
- err = iter.ForEach(func(ref *plumbing.Reference) error {
- if !s.Match(ref.Name()) {
- return nil
- }
-
+ onMatched := func(ref *plumbing.Reference) error {
if ref.Type() == plumbing.SymbolicReference {
target, err := storer.ResolveReference(remoteRefs, ref.Name())
if err != nil {
@@ -969,28 +978,47 @@ func doCalculateRefs(
}
matched = true
- if err := refs.SetReference(ref); err != nil {
- return err
- }
+ refList = append(refList, ref)
+ return refs.SetReference(ref)
+ }
- if !s.IsWildcard() {
- return storer.ErrStop
+ var ret error
+ if s.IsWildcard() {
+ iter, err := remoteRefs.IterReferences()
+ if err != nil {
+ return nil, err
}
+ ret = iter.ForEach(func(ref *plumbing.Reference) error {
+ if !s.Match(ref.Name()) {
+ return nil
+ }
- return nil
- })
+ return onMatched(ref)
+ })
+ } else {
+ var resolvedRef *plumbing.Reference
+ src := s.Src()
+ resolvedRef, ret = expand_ref(remoteRefs, plumbing.ReferenceName(src))
+ if ret == nil {
+ ret = onMatched(resolvedRef)
+ }
+ }
if !matched && !s.IsWildcard() {
- return NoMatchingRefSpecError{refSpec: s}
+ return nil, NoMatchingRefSpecError{refSpec: s}
}
- return err
+ return refList, ret
}
-func getWants(localStorer storage.Storer, refs memory.ReferenceStorage) ([]plumbing.Hash, error) {
+func getWants(localStorer storage.Storer, refs memory.ReferenceStorage, depth int) ([]plumbing.Hash, error) {
+ // If depth is anything other than 1 and the repo has shallow commits then just because we have the commit
+ // at the reference doesn't mean that we don't still need to fetch the parents
shallow := false
- if s, _ := localStorer.Shallow(); len(s) > 0 {
- shallow = true
+ if depth != 1 {
+ if s, _ := localStorer.Shallow(); len(s) > 0 {
+ shallow = true
+ }
}
wants := map[plumbing.Hash]bool{}
@@ -1144,27 +1172,28 @@ func buildSidebandIfSupported(l *capability.List, reader io.Reader, p sideband.P
func (r *Remote) updateLocalReferenceStorage(
specs []config.RefSpec,
fetchedRefs, remoteRefs memory.ReferenceStorage,
+ specToRefs [][]*plumbing.Reference,
tagMode TagMode,
force bool,
) (updated bool, err error) {
isWildcard := true
forceNeeded := false
- for _, spec := range specs {
+ for i, spec := range specs {
if !spec.IsWildcard() {
isWildcard = false
}
- for _, ref := range fetchedRefs {
- if !spec.Match(ref.Name()) && !spec.IsExactSHA1() {
- continue
- }
-
+ for _, ref := range specToRefs[i] {
if ref.Type() != plumbing.HashReference {
continue
}
localName := spec.Dst(ref.Name())
+ // If localName doesn't start with "refs/" then treat as a branch.
+ if !strings.HasPrefix(localName.String(), "refs/") {
+ localName = plumbing.NewBranchReferenceName(localName.String())
+ }
old, _ := storer.ResolveReference(r.s, localName)
new := plumbing.NewHashReference(localName, ref.Hash())
@@ -1250,15 +1279,19 @@ func (r *Remote) buildFetchedTags(refs memory.ReferenceStorage) (updated bool, e
// operation is complete, an error is returned. The context only affects to the
// transport operations.
func (r *Remote) ListContext(ctx context.Context, o *ListOptions) (rfs []*plumbing.Reference, err error) {
- refs, err := r.list(ctx, o)
- if err != nil {
- return refs, err
- }
- return refs, nil
+ return r.list(ctx, o)
}
func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) {
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ timeout := o.Timeout
+ // Default to the old hardcoded 10s value if a timeout is not explicitly set.
+ if timeout == 0 {
+ timeout = 10
+ }
+ if timeout < 0 {
+ return nil, fmt.Errorf("invalid timeout: %d", timeout)
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
return r.ListContext(ctx, o)
}
diff --git a/remote_test.go b/remote_test.go
index 164e4e5..ca5f261 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -5,7 +5,6 @@ import (
"context"
"errors"
"io"
- "io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -15,7 +14,6 @@ import (
"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/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/storer"
@@ -142,6 +140,62 @@ func (s *RemoteSuite) TestFetch(c *C) {
})
}
+func (s *RemoteSuite) TestFetchToNewBranch(c *C) {
+ r := NewRemote(memory.NewStorage(), &config.RemoteConfig{
+ URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())},
+ })
+
+ s.testFetch(c, r, &FetchOptions{
+ RefSpecs: []config.RefSpec{
+ // qualified branch to unqualified branch
+ "refs/heads/master:foo",
+ // unqualified branch to unqualified branch
+ "+master:bar",
+ // unqualified tag to unqualified branch
+ config.RefSpec("tree-tag:tree-tag"),
+ // unqualified tag to qualified tag
+ config.RefSpec("+commit-tag:refs/tags/renamed-tag"),
+ },
+ }, []*plumbing.Reference{
+ plumbing.NewReferenceFromStrings("refs/heads/foo", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f"),
+ plumbing.NewReferenceFromStrings("refs/heads/bar", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f"),
+ plumbing.NewReferenceFromStrings("refs/heads/tree-tag", "152175bf7e5580299fa1f0ba41ef6474cc043b70"),
+ plumbing.NewReferenceFromStrings("refs/tags/tree-tag", "152175bf7e5580299fa1f0ba41ef6474cc043b70"),
+ plumbing.NewReferenceFromStrings("refs/tags/renamed-tag", "ad7897c0fb8e7d9a9ba41fa66072cf06095a6cfc"),
+ plumbing.NewReferenceFromStrings("refs/tags/commit-tag", "ad7897c0fb8e7d9a9ba41fa66072cf06095a6cfc"),
+ })
+}
+
+func (s *RemoteSuite) TestFetchToNewBranchWithAllTags(c *C) {
+ r := NewRemote(memory.NewStorage(), &config.RemoteConfig{
+ URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())},
+ })
+
+ s.testFetch(c, r, &FetchOptions{
+ Tags: AllTags,
+ RefSpecs: []config.RefSpec{
+ // qualified branch to unqualified branch
+ "+refs/heads/master:foo",
+ // unqualified branch to unqualified branch
+ "master:bar",
+ // unqualified tag to unqualified branch
+ config.RefSpec("+tree-tag:tree-tag"),
+ // unqualified tag to qualified tag
+ config.RefSpec("commit-tag:refs/tags/renamed-tag"),
+ },
+ }, []*plumbing.Reference{
+ plumbing.NewReferenceFromStrings("refs/heads/foo", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f"),
+ plumbing.NewReferenceFromStrings("refs/heads/bar", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f"),
+ plumbing.NewReferenceFromStrings("refs/heads/tree-tag", "152175bf7e5580299fa1f0ba41ef6474cc043b70"),
+ plumbing.NewReferenceFromStrings("refs/tags/tree-tag", "152175bf7e5580299fa1f0ba41ef6474cc043b70"),
+ plumbing.NewReferenceFromStrings("refs/tags/renamed-tag", "ad7897c0fb8e7d9a9ba41fa66072cf06095a6cfc"),
+ plumbing.NewReferenceFromStrings("refs/tags/commit-tag", "ad7897c0fb8e7d9a9ba41fa66072cf06095a6cfc"),
+ plumbing.NewReferenceFromStrings("refs/tags/annotated-tag", "b742a2a9fa0afcfa9a6fad080980fbc26b007c69"),
+ plumbing.NewReferenceFromStrings("refs/tags/blob-tag", "fe6cb94756faa81e5ed9240f9191b833db5f40ae"),
+ plumbing.NewReferenceFromStrings("refs/tags/lightweight-tag", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f"),
+ })
+}
+
func (s *RemoteSuite) TestFetchNonExistantReference(c *C) {
r := NewRemote(memory.NewStorage(), &config.RemoteConfig{
URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())},
@@ -1176,7 +1230,7 @@ func (s *RemoteSuite) TestGetHaves(c *C) {
),
}
- l, err := getHaves(localRefs, memory.NewStorage(), sto)
+ l, err := getHaves(localRefs, memory.NewStorage(), sto, 0)
c.Assert(err, IsNil)
c.Assert(l, HasLen, 2)
}
@@ -1387,7 +1441,7 @@ func (s *RemoteSuite) TestPushRequireRemoteRefs(c *C) {
}
func (s *RemoteSuite) TestCanPushShasToReference(c *C) {
- d, err := ioutil.TempDir("", "TestCanPushShasToReference")
+ d, err := os.MkdirTemp("", "TestCanPushShasToReference")
c.Assert(err, IsNil)
if err != nil {
return
@@ -1405,45 +1459,7 @@ func (s *RemoteSuite) TestCanPushShasToReference(c *C) {
c.Assert(err, IsNil)
c.Assert(repo, NotNil)
- fd, err := os.Create(filepath.Join(d, "repo", "README.md"))
- c.Assert(err, IsNil)
- if err != nil {
- return
- }
- _, err = fd.WriteString("# test repo")
- c.Assert(err, IsNil)
- if err != nil {
- return
- }
- err = fd.Close()
- c.Assert(err, IsNil)
- if err != nil {
- return
- }
-
- wt, err := repo.Worktree()
- c.Assert(err, IsNil)
- if err != nil {
- return
- }
-
- wt.Add("README.md")
- sha, err := wt.Commit("test commit", &CommitOptions{
- Author: &object.Signature{
- Name: "test",
- Email: "test@example.com",
- When: time.Now(),
- },
- Committer: &object.Signature{
- Name: "test",
- Email: "test@example.com",
- When: time.Now(),
- },
- })
- c.Assert(err, IsNil)
- if err != nil {
- return
- }
+ sha := CommitNewFile(c, repo, "README.md")
gitremote, err := repo.CreateRemote(&config.RemoteConfig{
Name: "local",
@@ -1473,3 +1489,69 @@ func (s *RemoteSuite) TestCanPushShasToReference(c *C) {
}
c.Assert(ref.Hash().String(), Equals, sha.String())
}
+
+func (s *RemoteSuite) TestFetchAfterShallowClone(c *C) {
+ tempDir, clean := s.TemporalDir()
+ defer clean()
+ remoteUrl := filepath.Join(tempDir, "remote")
+ repoDir := filepath.Join(tempDir, "repo")
+
+ // Create a new repo and add more than 1 commit (so we can have a shallow commit)
+ remote, err := PlainInit(remoteUrl, false)
+ c.Assert(err, IsNil)
+ c.Assert(remote, NotNil)
+
+ _ = CommitNewFile(c, remote, "File1")
+ _ = CommitNewFile(c, remote, "File2")
+
+ // Clone the repo with a depth of 1
+ repo, err := PlainClone(repoDir, false, &CloneOptions{
+ URL: remoteUrl,
+ Depth: 1,
+ Tags: NoTags,
+ SingleBranch: true,
+ ReferenceName: "master",
+ })
+ c.Assert(err, IsNil)
+
+ // Add new commits to the origin (more than 1 so that our next test hits a missing commit)
+ _ = CommitNewFile(c, remote, "File3")
+ sha4 := CommitNewFile(c, remote, "File4")
+
+ // Try fetch with depth of 1 again (note, we need to ensure no remote branch remains pointing at the old commit)
+ r, err := repo.Remote(DefaultRemoteName)
+ c.Assert(err, IsNil)
+ s.testFetch(c, r, &FetchOptions{
+ Depth: 2,
+ Tags: NoTags,
+
+ RefSpecs: []config.RefSpec{
+ "+refs/heads/master:refs/heads/master",
+ "+refs/heads/master:refs/remotes/origin/master",
+ },
+ }, []*plumbing.Reference{
+ plumbing.NewReferenceFromStrings("refs/heads/master", sha4.String()),
+ plumbing.NewReferenceFromStrings("refs/remotes/origin/master", sha4.String()),
+ plumbing.NewSymbolicReference("HEAD", "refs/heads/master"),
+ })
+
+ // Add another commit to the origin
+ sha5 := CommitNewFile(c, remote, "File5")
+
+ // Try fetch with depth of 2 this time (to reach a commit that we don't have locally)
+ r, err = repo.Remote(DefaultRemoteName)
+ c.Assert(err, IsNil)
+ s.testFetch(c, r, &FetchOptions{
+ Depth: 1,
+ Tags: NoTags,
+
+ RefSpecs: []config.RefSpec{
+ "+refs/heads/master:refs/heads/master",
+ "+refs/heads/master:refs/remotes/origin/master",
+ },
+ }, []*plumbing.Reference{
+ plumbing.NewReferenceFromStrings("refs/heads/master", sha5.String()),
+ plumbing.NewReferenceFromStrings("refs/remotes/origin/master", sha5.String()),
+ plumbing.NewSymbolicReference("HEAD", "refs/heads/master"),
+ })
+}
diff --git a/repository.go b/repository.go
index 33a9d69..dd822a5 100644
--- a/repository.go
+++ b/repository.go
@@ -7,7 +7,7 @@ import (
"encoding/hex"
"errors"
"fmt"
- stdioutil "io/ioutil"
+ "io"
"os"
"path"
"path/filepath"
@@ -71,14 +71,30 @@ type Repository struct {
wt billy.Filesystem
}
+type InitOptions struct {
+ // The default branch (e.g. "refs/heads/master")
+ DefaultBranch plumbing.ReferenceName
+}
+
// Init creates an empty git repository, based on the given Storer and worktree.
// The worktree Filesystem is optional, if nil a bare repository is created. If
// the given storer is not empty ErrRepositoryAlreadyExists is returned
func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {
+ options := InitOptions{
+ DefaultBranch: plumbing.Master,
+ }
+ return InitWithOptions(s, worktree, options)
+}
+
+func InitWithOptions(s storage.Storer, worktree billy.Filesystem, options InitOptions) (*Repository, error) {
if err := initStorer(s); err != nil {
return nil, err
}
+ if options.DefaultBranch == "" {
+ options.DefaultBranch = plumbing.Master
+ }
+
r := newRepository(s, worktree)
_, err := r.Reference(plumbing.HEAD, false)
switch err {
@@ -89,7 +105,7 @@ func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {
return nil, err
}
- h := plumbing.NewSymbolicReference(plumbing.HEAD, plumbing.Master)
+ h := plumbing.NewSymbolicReference(plumbing.HEAD, options.DefaultBranch)
if err := s.SetReference(h); err != nil {
return nil, err
}
@@ -367,7 +383,7 @@ func dotGitFileToOSFilesystem(path string, fs billy.Filesystem) (bfs billy.Files
}
defer ioutil.CheckClose(f, &err)
- b, err := stdioutil.ReadAll(f)
+ b, err := io.ReadAll(f)
if err != nil {
return nil, err
}
@@ -396,7 +412,7 @@ func dotGitCommonDirectory(fs billy.Filesystem) (commonDir billy.Filesystem, err
return nil, err
}
- b, err := stdioutil.ReadAll(f)
+ b, err := io.ReadAll(f)
if err != nil {
return nil, err
}
@@ -957,7 +973,6 @@ func (r *Repository) cloneRefSpec(o *CloneOptions) []config.RefSpec {
case o.SingleBranch && o.ReferenceName == plumbing.HEAD:
return []config.RefSpec{
config.RefSpec(fmt.Sprintf(refspecSingleBranchHEAD, o.RemoteName)),
- config.RefSpec(fmt.Sprintf(refspecSingleBranch, plumbing.Master.Short(), o.RemoteName)),
}
case o.SingleBranch:
return []config.RefSpec{
@@ -1019,21 +1034,9 @@ func (r *Repository) fetchAndUpdateReferences(
return nil, err
}
- var resolvedRef *plumbing.Reference
- // return error from checking the raw ref passed in
- var rawRefError error
- for _, rule := range append([]string{"%s"}, plumbing.RefRevParseRules...) {
- resolvedRef, err = storer.ResolveReference(remoteRefs, plumbing.ReferenceName(fmt.Sprintf(rule, ref)))
-
- if err == nil {
- break
- } else if rawRefError == nil {
- rawRefError = err
- }
- }
-
+ resolvedRef, err := expand_ref(remoteRefs, ref)
if err != nil {
- return nil, rawRefError
+ return nil, err
}
refsUpdated, err := r.updateReferences(remote.c.Fetch, resolvedRef)
@@ -1479,6 +1482,23 @@ func (r *Repository) Worktree() (*Worktree, error) {
return &Worktree{r: r, Filesystem: r.wt}, nil
}
+func expand_ref(s storer.ReferenceStorer, ref plumbing.ReferenceName) (*plumbing.Reference, error) {
+ // For improving troubleshooting, this preserves the error for the provided `ref`,
+ // and returns the error for that specific ref in case all parse rules fails.
+ var ret error
+ for _, rule := range plumbing.RefRevParseRules {
+ resolvedRef, err := storer.ResolveReference(s, plumbing.ReferenceName(fmt.Sprintf(rule, ref)))
+
+ if err == nil {
+ return resolvedRef, nil
+ } else if ret == nil {
+ ret = err
+ }
+ }
+
+ return nil, ret
+}
+
// ResolveRevision resolves revision to corresponding hash. It will always
// resolve to a commit hash, not a tree or annotated tag.
//
@@ -1508,13 +1528,9 @@ func (r *Repository) ResolveRevision(in plumbing.Revision) (*plumbing.Hash, erro
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)))
-
- if err == nil {
- tryHashes = append(tryHashes, ref.Hash())
- break
- }
+ ref, err := expand_ref(r.Storer, plumbing.ReferenceName(revisionRef))
+ if err == nil {
+ tryHashes = append(tryHashes, ref.Hash())
}
// in ambiguous cases, `git rev-parse` will emit a warning, but
diff --git a/repository_test.go b/repository_test.go
index 79a884b..d18816f 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -52,6 +51,54 @@ func (s *RepositorySuite) TestInit(c *C) {
cfg, err := r.Config()
c.Assert(err, IsNil)
c.Assert(cfg.Core.IsBare, Equals, false)
+
+ // check the HEAD to see what the default branch is
+ createCommit(c, r)
+ ref, err := r.Head()
+ c.Assert(err, IsNil)
+ c.Assert(ref.Name().String(), Equals, plumbing.Master.String())
+}
+
+func (s *RepositorySuite) TestInitWithOptions(c *C) {
+ r, err := InitWithOptions(memory.NewStorage(), memfs.New(), InitOptions{
+ DefaultBranch: "refs/heads/foo",
+ })
+ c.Assert(err, IsNil)
+ c.Assert(r, NotNil)
+ createCommit(c, r)
+
+ ref, err := r.Head()
+ c.Assert(err, IsNil)
+ c.Assert(ref.Name().String(), Equals, "refs/heads/foo")
+
+}
+
+func createCommit(c *C, r *Repository) {
+ // Create a commit so there is a HEAD to check
+ wt, err := r.Worktree()
+ c.Assert(err, IsNil)
+
+ rm, err := wt.Filesystem.Create("foo.txt")
+ c.Assert(err, IsNil)
+
+ _, err = rm.Write([]byte("foo text"))
+ c.Assert(err, IsNil)
+
+ _, err = wt.Add("foo.txt")
+ c.Assert(err, IsNil)
+
+ author := object.Signature{
+ Name: "go-git",
+ Email: "go-git@fake.local",
+ When: time.Now(),
+ }
+ _, err = wt.Commit("test commit message", &CommitOptions{
+ All: true,
+ Author: &author,
+ Committer: &author,
+ })
+ c.Assert(err, IsNil)
+
}
func (s *RepositorySuite) TestInitNonStandardDotGit(c *C) {
@@ -60,17 +107,18 @@ func (s *RepositorySuite) TestInitNonStandardDotGit(c *C) {
fs := osfs.New(dir)
dot, _ := fs.Chroot("storage")
- storage := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
+ st := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
wt, _ := fs.Chroot("worktree")
- r, err := Init(storage, wt)
+ r, err := Init(st, wt)
c.Assert(err, IsNil)
c.Assert(r, NotNil)
f, err := fs.Open(fs.Join("worktree", ".git"))
c.Assert(err, IsNil)
+ defer func() { _ = f.Close() }()
- all, err := ioutil.ReadAll(f)
+ all, err := io.ReadAll(f)
c.Assert(err, IsNil)
c.Assert(string(all), Equals, fmt.Sprintf("gitdir: %s\n", filepath.Join("..", "storage")))
@@ -85,9 +133,9 @@ func (s *RepositorySuite) TestInitStandardDotGit(c *C) {
fs := osfs.New(dir)
dot, _ := fs.Chroot(".git")
- storage := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
+ st := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
- r, err := Init(storage, fs)
+ r, err := Init(st, fs)
c.Assert(err, IsNil)
c.Assert(r, NotNil)
@@ -1108,6 +1156,49 @@ func (s *RepositorySuite) testCloneSingleBranchAndNonHEADReference(c *C, ref str
c.Assert(branch.Hash().String(), Equals, "e8d3ffab552895c19b9fcf7aa264d277cde33881")
}
+func (s *RepositorySuite) TestCloneSingleBranchHEADMain(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+
+ head, err := r.Head()
+ c.Assert(err, Equals, plumbing.ErrReferenceNotFound)
+ c.Assert(head, IsNil)
+
+ err = r.clone(context.Background(), &CloneOptions{
+ URL: s.GetLocalRepositoryURL(fixtures.ByTag("no-master-head").One()),
+ SingleBranch: true,
+ })
+
+ c.Assert(err, IsNil)
+
+ remotes, err := r.Remotes()
+ c.Assert(err, IsNil)
+ c.Assert(remotes, HasLen, 1)
+
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["main"].Name, Equals, "main")
+ c.Assert(cfg.Branches["main"].Remote, Equals, "origin")
+ c.Assert(cfg.Branches["main"].Merge, Equals, plumbing.ReferenceName("refs/heads/main"))
+
+ head, err = r.Reference(plumbing.HEAD, false)
+ c.Assert(err, IsNil)
+ c.Assert(head, NotNil)
+ c.Assert(head.Type(), Equals, plumbing.SymbolicReference)
+ c.Assert(head.Target().String(), Equals, "refs/heads/main")
+
+ branch, err := r.Reference(head.Target(), false)
+ c.Assert(err, IsNil)
+ c.Assert(branch, NotNil)
+ c.Assert(branch.Hash().String(), Equals, "786dafbd351e587da1ae97e5fb9fbdf868b4a28f")
+
+ branch, err = r.Reference("refs/remotes/origin/HEAD", false)
+ c.Assert(err, IsNil)
+ c.Assert(branch, NotNil)
+ c.Assert(branch.Type(), Equals, plumbing.HashReference)
+ c.Assert(branch.Hash().String(), Equals, "786dafbd351e587da1ae97e5fb9fbdf868b4a28f")
+}
+
func (s *RepositorySuite) TestCloneSingleBranch(c *C) {
r, _ := Init(memory.NewStorage(), nil)
@@ -1143,12 +1234,6 @@ func (s *RepositorySuite) TestCloneSingleBranch(c *C) {
c.Assert(err, IsNil)
c.Assert(branch, NotNil)
c.Assert(branch.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
-
- branch, err = r.Reference("refs/remotes/origin/master", false)
- c.Assert(err, IsNil)
- c.Assert(branch, NotNil)
- c.Assert(branch.Type(), Equals, plumbing.HashReference)
- c.Assert(branch.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
}
func (s *RepositorySuite) TestCloneSingleTag(c *C) {
@@ -3046,14 +3131,14 @@ func BenchmarkObjects(b *testing.B) {
b.Run(f.URL, func(b *testing.B) {
fs := f.DotGit()
- storer := filesystem.NewStorage(fs, cache.NewObjectLRUDefault())
+ st := filesystem.NewStorage(fs, cache.NewObjectLRUDefault())
worktree, err := fs.Chroot(filepath.Dir(fs.Root()))
if err != nil {
b.Fatal(err)
}
- repo, err := Open(storer, worktree)
+ repo, err := Open(st, worktree)
if err != nil {
b.Fatal(err)
}
@@ -3083,7 +3168,7 @@ func BenchmarkObjects(b *testing.B) {
func BenchmarkPlainClone(b *testing.B) {
for i := 0; i < b.N; i++ {
- t, err := ioutil.TempDir("", "")
+ t, err := os.MkdirTemp("", "")
if err != nil {
b.Fatal(err)
}
diff --git a/storage/filesystem/dotgit/dotgit.go b/storage/filesystem/dotgit/dotgit.go
index 5bde37f..19d7026 100644
--- a/storage/filesystem/dotgit/dotgit.go
+++ b/storage/filesystem/dotgit/dotgit.go
@@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
- stdioutil "io/ioutil"
"os"
"path/filepath"
"sort"
@@ -647,7 +646,7 @@ func (d *DotGit) ObjectDelete(h plumbing.Hash) error {
}
func (d *DotGit) readReferenceFrom(rd io.Reader, name string) (ref *plumbing.Reference, err error) {
- b, err := stdioutil.ReadAll(rd)
+ b, err := io.ReadAll(rd)
if err != nil {
return nil, err
}
diff --git a/storage/filesystem/dotgit/dotgit_test.go b/storage/filesystem/dotgit/dotgit_test.go
index 63c9eb0..6a339d1 100644
--- a/storage/filesystem/dotgit/dotgit_test.go
+++ b/storage/filesystem/dotgit/dotgit_test.go
@@ -4,7 +4,6 @@ import (
"bufio"
"encoding/hex"
"io"
- "io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -374,7 +373,7 @@ func (s *SuiteDotGit) TestConfigWriteAndConfig(c *C) {
f, err = dir.Config()
c.Assert(err, IsNil)
- cnt, err := ioutil.ReadAll(f)
+ cnt, err := io.ReadAll(f)
c.Assert(err, IsNil)
c.Assert(string(cnt), Equals, "foo")
@@ -404,7 +403,7 @@ func (s *SuiteDotGit) TestIndexWriteAndIndex(c *C) {
f, err = dir.Index()
c.Assert(err, IsNil)
- cnt, err := ioutil.ReadAll(f)
+ cnt, err := io.ReadAll(f)
c.Assert(err, IsNil)
c.Assert(string(cnt), Equals, "foo")
@@ -434,7 +433,7 @@ func (s *SuiteDotGit) TestShallowWriteAndShallow(c *C) {
f, err = dir.Shallow()
c.Assert(err, IsNil)
- cnt, err := ioutil.ReadAll(f)
+ cnt, err := io.ReadAll(f)
c.Assert(err, IsNil)
c.Assert(string(cnt), Equals, "foo")
diff --git a/storage/filesystem/object_test.go b/storage/filesystem/object_test.go
index b5f137f..251077a 100644
--- a/storage/filesystem/object_test.go
+++ b/storage/filesystem/object_test.go
@@ -4,7 +4,6 @@ import (
"encoding/hex"
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"testing"
@@ -510,7 +509,7 @@ func BenchmarkPackfileIterReadContent(b *testing.B) {
b.Fatal(err)
}
- if _, err := ioutil.ReadAll(r); err != nil {
+ if _, err := io.ReadAll(r); err != nil {
b.Fatal(err)
}
diff --git a/storage/test/storage_suite.go b/storage/test/storage_suite.go
index 2c00e75..ee67fc7 100644
--- a/storage/test/storage_suite.go
+++ b/storage/test/storage_suite.go
@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
@@ -502,12 +501,12 @@ func objectEquals(a plumbing.EncodedObject, b plumbing.EncodedObject) error {
return fmt.Errorf("can't get reader on b: %q", err)
}
- ca, err := ioutil.ReadAll(ra)
+ ca, err := io.ReadAll(ra)
if err != nil {
return fmt.Errorf("error reading a: %q", err)
}
- cb, err := ioutil.ReadAll(rb)
+ cb, err := io.ReadAll(rb)
if err != nil {
return fmt.Errorf("error reading b: %q", err)
}
diff --git a/submodule.go b/submodule.go
index b0c4169..84f020d 100644
--- a/submodule.go
+++ b/submodule.go
@@ -5,13 +5,13 @@ import (
"context"
"errors"
"fmt"
- "net/url"
"path"
"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/go-git/go-git/v5/plumbing/transport"
)
var (
@@ -133,29 +133,29 @@ func (s *Submodule) Repository() (*Repository, error) {
return nil, err
}
- moduleURL, err := url.Parse(s.c.URL)
+ moduleEndpoint, err := transport.NewEndpoint(s.c.URL)
if err != nil {
return nil, err
}
- if !path.IsAbs(moduleURL.Path) {
+ if !path.IsAbs(moduleEndpoint.Path) && moduleEndpoint.Protocol == "file" {
remotes, err := s.w.r.Remotes()
if err != nil {
return nil, err
}
- rootURL, err := url.Parse(remotes[0].c.URLs[0])
+ rootEndpoint, err := transport.NewEndpoint(remotes[0].c.URLs[0])
if err != nil {
return nil, err
}
- rootURL.Path = path.Join(rootURL.Path, moduleURL.Path)
- *moduleURL = *rootURL
+ rootEndpoint.Path = path.Join(rootEndpoint.Path, moduleEndpoint.Path)
+ *moduleEndpoint = *rootEndpoint
}
_, err = r.CreateRemote(&config.RemoteConfig{
Name: DefaultRemoteName,
- URLs: []string{moduleURL.String()},
+ URLs: []string{moduleEndpoint.String()},
})
return r, err
diff --git a/submodule_test.go b/submodule_test.go
index a8a0681..0e88391 100644
--- a/submodule_test.go
+++ b/submodule_test.go
@@ -2,11 +2,13 @@ package git
import (
"context"
- "os"
"path/filepath"
"testing"
+ "github.com/go-git/go-billy/v5/memfs"
+ "github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/storage/memory"
fixtures "github.com/go-git/go-git-fixtures/v4"
. "gopkg.in/check.v1"
@@ -15,7 +17,7 @@ import (
type SubmoduleSuite struct {
BaseSuite
Worktree *Worktree
- path string
+ clean func()
}
var _ = Suite(&SubmoduleSuite{})
@@ -23,8 +25,8 @@ var _ = Suite(&SubmoduleSuite{})
func (s *SubmoduleSuite) SetUpTest(c *C) {
path := fixtures.ByTag("submodule").One().Worktree().Root()
- dir, clean := s.TemporalDir()
- defer clean()
+ var dir string
+ dir, s.clean = s.TemporalDir()
r, err := PlainClone(filepath.Join(dir, "worktree"), false, &CloneOptions{
URL: path,
@@ -35,13 +37,10 @@ func (s *SubmoduleSuite) SetUpTest(c *C) {
s.Repository = r
s.Worktree, err = r.Worktree()
c.Assert(err, IsNil)
-
- s.path = dir
}
-func (s *SubmoduleSuite) TearDownTest(c *C) {
- err := os.RemoveAll(s.path)
- c.Assert(err, IsNil)
+func (s *SubmoduleSuite) TearDownTest(_ *C) {
+ s.clean()
}
func (s *SubmoduleSuite) TestInit(c *C) {
@@ -198,7 +197,7 @@ func (s *SubmoduleSuite) TestSubmodulesInit(c *C) {
func (s *SubmoduleSuite) TestGitSubmodulesSymlink(c *C) {
f, err := s.Worktree.Filesystem.Create("badfile")
c.Assert(err, IsNil)
- defer f.Close()
+ defer func() { _ = f.Close() }()
err = s.Worktree.Filesystem.Remove(gitmodulesFile)
c.Assert(err, IsNil)
@@ -262,3 +261,26 @@ func (s *SubmoduleSuite) TestSubmodulesFetchDepth(c *C) {
c.Assert(commitCount, Equals, 1)
}
+
+func (s *SubmoduleSuite) TestSubmoduleParseScp(c *C) {
+ repo := &Repository{
+ Storer: memory.NewStorage(),
+ wt: memfs.New(),
+ }
+ worktree := &Worktree{
+ Filesystem: memfs.New(),
+ r: repo,
+ }
+ submodule := &Submodule{
+ initialized: true,
+ c: nil,
+ w: worktree,
+ }
+
+ submodule.c = &config.Submodule{
+ URL: "git@github.com:username/submodule_repo",
+ }
+
+ _, err := submodule.Repository()
+ c.Assert(err, IsNil)
+}
diff --git a/utils/ioutil/common_test.go b/utils/ioutil/common_test.go
index 27bfa62..e3c9d69 100644
--- a/utils/ioutil/common_test.go
+++ b/utils/ioutil/common_test.go
@@ -3,7 +3,7 @@ package ioutil
import (
"bytes"
"context"
- "io/ioutil"
+ "io"
"strings"
"testing"
@@ -38,7 +38,7 @@ func (s *CommonSuite) TestNonEmptyReader_NonEmpty(c *C) {
c.Assert(err, IsNil)
c.Assert(r, NotNil)
- read, err := ioutil.ReadAll(r)
+ read, err := io.ReadAll(r)
c.Assert(err, IsNil)
c.Assert(string(read), Equals, "1")
}
@@ -48,7 +48,7 @@ func (s *CommonSuite) TestNewReadCloser(c *C) {
closer := &closer{}
r := NewReadCloser(buf, closer)
- read, err := ioutil.ReadAll(r)
+ read, err := io.ReadAll(r)
c.Assert(err, IsNil)
c.Assert(string(read), Equals, "1")
@@ -160,7 +160,7 @@ func ExampleCheckClose() {
// CheckClose is commonly used with named return values
f := func() (err error) {
// Get a io.ReadCloser
- r := ioutil.NopCloser(strings.NewReader("foo"))
+ r := io.NopCloser(strings.NewReader("foo"))
// defer CheckClose call with an io.Closer and pointer to error
defer CheckClose(r, &err)
diff --git a/worktree.go b/worktree.go
index 7d2f3b4..595dcea 100644
--- a/worktree.go
+++ b/worktree.go
@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
- stdioutil "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -569,7 +568,7 @@ func (w *Worktree) checkoutFileSymlink(f *object.File) (err error) {
defer ioutil.CheckClose(from, &err)
- bytes, err := stdioutil.ReadAll(from)
+ bytes, err := io.ReadAll(from)
if err != nil {
return
}
@@ -718,7 +717,7 @@ func (w *Worktree) readGitmodulesFile() (*config.Modules, error) {
}
defer f.Close()
- input, err := stdioutil.ReadAll(f)
+ input, err := io.ReadAll(f)
if err != nil {
return nil, err
}
diff --git a/worktree_test.go b/worktree_test.go
index 4f55844..ea55ac6 100644
--- a/worktree_test.go
+++ b/worktree_test.go
@@ -5,7 +5,6 @@ import (
"context"
"errors"
"io"
- "io/ioutil"
"os"
"path/filepath"
"regexp"
@@ -81,7 +80,7 @@ func (s *WorktreeSuite) TestPullFastForward(c *C) {
w, err := server.Worktree()
c.Assert(err, IsNil)
- err = ioutil.WriteFile(filepath.Join(path, "foo"), []byte("foo"), 0755)
+ err = os.WriteFile(filepath.Join(path, "foo"), []byte("foo"), 0755)
c.Assert(err, IsNil)
hash, err := w.Commit("foo", &CommitOptions{Author: defaultSignature()})
c.Assert(err, IsNil)
@@ -118,14 +117,14 @@ func (s *WorktreeSuite) TestPullNonFastForward(c *C) {
w, err := server.Worktree()
c.Assert(err, IsNil)
- err = ioutil.WriteFile(filepath.Join(path, "foo"), []byte("foo"), 0755)
+ err = os.WriteFile(filepath.Join(path, "foo"), []byte("foo"), 0755)
c.Assert(err, IsNil)
_, err = w.Commit("foo", &CommitOptions{Author: defaultSignature()})
c.Assert(err, IsNil)
w, err = r.Worktree()
c.Assert(err, IsNil)
- err = ioutil.WriteFile(filepath.Join(path, "bar"), []byte("bar"), 0755)
+ err = os.WriteFile(filepath.Join(path, "bar"), []byte("bar"), 0755)
c.Assert(err, IsNil)
_, err = w.Commit("bar", &CommitOptions{Author: defaultSignature()})
c.Assert(err, IsNil)
@@ -287,7 +286,7 @@ func (s *WorktreeSuite) TestPullAlreadyUptodate(c *C) {
w, err := r.Worktree()
c.Assert(err, IsNil)
- err = ioutil.WriteFile(filepath.Join(path, "bar"), []byte("bar"), 0755)
+ err = os.WriteFile(filepath.Join(path, "bar"), []byte("bar"), 0755)
c.Assert(err, IsNil)
_, err = w.Commit("bar", &CommitOptions{Author: defaultSignature()})
c.Assert(err, IsNil)
@@ -315,7 +314,7 @@ func (s *WorktreeSuite) TestCheckout(c *C) {
ch, err := fs.Open("CHANGELOG")
c.Assert(err, IsNil)
- content, err := ioutil.ReadAll(ch)
+ content, err := io.ReadAll(ch)
c.Assert(err, IsNil)
c.Assert(string(content), Equals, "Initial changelog\n")