Skip to content

Merge v6-transport, fix upload-requests atomic logic, and update tests #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
e4685fb
plumbing: transport/git, reduce delay when waiting for daemon on test…
onee-only Apr 28, 2025
74b27f0
plumbing: transport/http: make sure http server is closed after each …
onee-only Apr 28, 2025
8459466
plumbing: packp, add error types for unpack status and command status
aymanbagabas Apr 27, 2025
7ac58fd
plumbing: pktline, improve error messages
aymanbagabas Apr 28, 2025
faec86f
plumbing: transport, add tests for report-status and send-pack
aymanbagabas Apr 28, 2025
256f784
repository: adopt variadic options pattern for Init and PlainInit
davidalpert Feb 16, 2025
d2c3797
Merge pull request #1533 from onee-only/v6-transport-minor-improvements
pjbgf May 24, 2025
40d7f0e
git: worktree, Add validation for sparse dir existence. Fixes #1500
onee-only Apr 28, 2025
dfd10fe
git: worktree, Remove ResetSparsely and add option to disable validat…
onee-only Apr 28, 2025
9bc562e
git: worktree, Add a test for treeContainsDirs.
onee-only May 24, 2025
ac74dc2
git: remote, replace NoMatchingRefSpecError with ErrRemoteRefNotFound
CLBRITTON2 May 29, 2025
ca74b26
Merge pull request #1556 from CLBRITTON2/v6-transport
pjbgf May 29, 2025
2badfb4
Merge pull request #1531 from onee-only/add-sparse-reset-validation
pjbgf May 29, 2025
f511680
plumbing: pktline, wrap errors
aymanbagabas May 31, 2025
cc39e9f
plumbing: transport, test, remove unnecessary comments
aymanbagabas May 31, 2025
ee31137
backend: http, make backend more idiomatic
aymanbagabas May 31, 2025
2797501
Merge pull request #1536 from aymanbagabas/v6-transport-report-status…
pjbgf Jun 2, 2025
495bc80
Merge pull request #1557 from aymanbagabas/backend-http
pjbgf Jun 3, 2025
df10a55
Merge pull request #1462 from davidalpert/395-v6-repository-options
pjbgf Jun 3, 2025
a4f298e
plumbing: format/config, Add ErrInvalidObjectFormat
pjbgf Nov 10, 2023
a28c4d4
plumbing: hash, Add SHA1 and SHA256 constants
pjbgf Nov 10, 2023
3ccc874
plumbing: hash, Add ErrUnsupportedHashFunction
pjbgf Nov 10, 2023
f3411df
plumbing: hash, Add hash.FromObjectFormat
pjbgf Nov 10, 2023
6e0dd1e
plumbing: Add ObjectHasher and ImmutableHash
pjbgf Nov 10, 2023
f7bcbfa
plumbing: Rename hash constants
pjbgf Dec 31, 2024
ce37c5b
plumbing: hash, Move immutable hash to plumbing
pjbgf Dec 31, 2024
27e3866
utils: Support new Hash format
pjbgf Apr 20, 2025
5e3685e
plumbing: protocol, Support new Hash format
pjbgf Apr 20, 2025
500bbf1
storage: filesystem, Support new Hash format
pjbgf Apr 21, 2025
7de3e20
plumbing: format/packfile, Support new Hash format
pjbgf Apr 21, 2025
94880d2
utils: binary, Remove ReadHash
pjbgf Apr 21, 2025
ee7e345
build: Remove sha256-specific test
pjbgf Apr 23, 2025
ed15d0b
plumbing: Add ObjectID to replace Hash
pjbgf Apr 23, 2025
cc609e4
plumbing: format, Support new Hash format
pjbgf Apr 23, 2025
fcad8fb
plumbing: object, Support new Hash format
pjbgf Apr 23, 2025
fa3fb77
plumbing: protocol, Support new Hash format
pjbgf Apr 23, 2025
c1790f5
plumbing: hash, Bump module to v6
pjbgf Apr 23, 2025
665119d
_examples: Change blame example to open repo
pjbgf Apr 23, 2025
96a80f6
plumbing: transport/http, Set object size for NewMemoryIndex()
pjbgf Apr 23, 2025
619cabe
git: Support new Hash format
pjbgf Apr 23, 2025
93d9045
*: Simplify ObjectID creation
pjbgf Apr 26, 2025
6e7e572
plumbing: Use empty format for sha1
pjbgf Apr 26, 2025
cbb802c
plumbing: format/commitgraph, Fix issues with ObjectID
pjbgf Apr 26, 2025
e9cea3b
plumbing: config, use an int for ObjectFormat
aymanbagabas Apr 26, 2025
db63721
plumbing: combine hasher implementation based on object format
aymanbagabas Apr 26, 2025
49ace15
plumbing: remove unused HexSize
aymanbagabas Apr 26, 2025
d677269
git: use standard library hashes for client side crypto
aymanbagabas Apr 26, 2025
67b3c10
plumbing: format/packfile, Align hash formats
pjbgf Apr 27, 2025
6bc2df1
*: Set sha1cd as default implementation
pjbgf Apr 27, 2025
af89cec
plumbing: format/commitgraph, Refactor tests
pjbgf Apr 27, 2025
7dfd841
plumbing: Improve ObjectID documentation
pjbgf Jun 3, 2025
8ed10b1
plumbing: hash, Remove references to sha256 conditional build
pjbgf Jun 3, 2025
6d619b3
plumbing: format, Highlight API changes needed for sha256 support
pjbgf Jun 3, 2025
856aa92
Merge pull request #1527 from pjbgf/sha256-open
pjbgf Jun 4, 2025
c1d167a
plumbing: Introduce a first-parent git log traversal option (#1486)
MoralCode May 24, 2025
aa09c63
git: worktree, Don't delete local untracked files when resetting work…
pjbgf Jun 4, 2025
0f1415a
build: Bump dependencies
pjbgf Jun 4, 2025
e118d66
docs: Add reference to v6-transport in CONTRIBUTING.md
pjbgf Jun 4, 2025
158b374
Merge pull request #1564 from pjbgf/main-readiness
pjbgf Jun 5, 2025
c54cd93
git: Bump go-billy dependency to fix memfs modtime issue.
onee-only Jun 9, 2025
473d987
git: Remove go-git-fixtures@v4 dependency.
onee-only Jun 9, 2025
d6cff1c
git: repository, Ensure commondir is closed.
onee-only Jun 9, 2025
0ba2095
Merge pull request #1569 from onee-only/remove-go-git-fixtures-v4
pjbgf Jun 9, 2025
009149b
Merge branch 'v6-transport' into v6-transport-fix-tests
aymanbagabas Jun 10, 2025
9e56143
plumbing: transport, fix update-requests atomic capability check
aymanbagabas Jun 10, 2025
585d900
plumbing: transport, correct tests for update-requests capabilities and
aymanbagabas Jun 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/git.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ jobs:
- name: Test
run: make test-coverage

- name: Test SHA256
run: make test-sha256

- name: Build go-git with CGO disabled
run: go build ./...
env:
Expand Down
7 changes: 5 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ In order for a PR to be accepted it needs to pass a list of requirements:
### Branches

The development branch is `main`, where all development takes place.
All new features and bug fixes should target it. This was formely known as `v6-exp`,
as it contains all the changes for `v6` - the next major release.
All new features and bug fixes should target it. This was formely known
as `v6-exp` or `v6-transport`. This branch contains all the changes for
`v6` - the next major release.
From time to time this branch will contain breaking changes, as the API
for `v6` is being refined.

The `releases/v5.x` branch is the branch for changes to the `v5` version,
which is now in maintaince mode. To avoid having to divert efforts from `v6`,
Expand Down
6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ test:
$(GOTEST) -race ./...
$(GOTEST) -v _examples/common_test.go _examples/common.go --examples

TEMP_REPO := $(shell mktemp)
test-sha256:
$(GOCMD) run -tags sha256 _examples/sha256/main.go $(TEMP_REPO)
cd $(TEMP_REPO) && git fsck
rm -rf $(TEMP_REPO)

test-coverage:
@echo "running against `git version`"; \
echo "" > $(COVERAGE_REPORT); \
Expand Down
17 changes: 3 additions & 14 deletions _examples/blame/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,13 @@ import (

// Basic example of how to blame a repository.
func main() {
CheckArgs("<url>", "<file_to_blame>")
CheckArgs("<path>", "<file_to_blame>")
url := os.Args[1]
path := os.Args[2]

tmp, err := os.MkdirTemp("", "go-git-blame-*")
CheckIfError(err)

defer os.RemoveAll(tmp)

// Clone the given repository.
Info("git clone %s %s", url, tmp)
r, err := git.PlainClone(
tmp,
&git.CloneOptions{
URL: url,
Tags: git.NoTags,
},
)
Info("git open %s", url)
r, err := git.PlainOpen(url)
CheckIfError(err)

// Retrieve the branch's HEAD, to then get the HEAD commit.
Expand Down
2 changes: 1 addition & 1 deletion _examples/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var examplesTest = flag.Bool("examples", false, "run the examples tests")
var defaultURL = "https://github.com/git-fixtures/basic.git"

var args = map[string][]string{
"blame": {defaultURL, "CHANGELOG"},
"blame": {cloneRepository(defaultURL, tempFolder()), "CHANGELOG"},
"branch": {defaultURL, tempFolder()},
"checkout": {defaultURL, tempFolder(), "35e85108805c84807bc66a02d91535e1e24b38b9"},
"checkout-branch": {defaultURL, tempFolder(), "branch"},
Expand Down
2 changes: 1 addition & 1 deletion _examples/remotes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
func main() {
// Create a new repository
Info("git init")
r, err := git.Init(memory.NewStorage(), nil)
r, err := git.Init(memory.NewStorage())
CheckIfError(err)

// Add a new remote, with the default fetch refspec
Expand Down
2 changes: 1 addition & 1 deletion _examples/sha256/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func main() {
os.RemoveAll(directory)

// Init a new repository using the ObjectFormat SHA256.
r, err := git.PlainInitWithOptions(directory, &git.PlainInitOptions{ObjectFormat: config.SHA256})
r, err := git.PlainInit(directory, false, git.WithObjectFormat(config.SHA256))
CheckIfError(err)

w, err := r.Worktree()
Expand Down
91 changes: 48 additions & 43 deletions backend/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ var services = []service{
{regexp.MustCompile("(.*?)/git-receive-pack$"), http.MethodPost, serviceRpc, transport.ReceivePackService},
}

// BackendOptions represents a set of options for the Git HTTP handler.
type BackendOptions struct {
// Backend represents a Git HTTP handler.
type Backend struct {
// Loader is used to load repositories from the given endpoint. If nil,
// [Transport.DefaultLoader] is used.
Loader transport.Loader
// ErrorLog is the logger used to log errors. If nil, no errors are logged.
ErrorLog *log.Logger
// Prefix is a path prefix that will be stripped from the URL path before
Expand All @@ -63,55 +66,57 @@ type BackendOptions struct {
// repositories that wish to be server using the Dumb-HTTP protocol must update
// the server info files. This can be done by using
// [transport.UpdateServerInfo] before serving the repository.
func NewBackend(loader transport.Loader, opts *BackendOptions) http.HandlerFunc {
func NewBackend(loader transport.Loader) *Backend {
if loader == nil {
loader = transport.DefaultLoader
}
if opts == nil {
opts = &BackendOptions{}
return &Backend{
Loader: loader,
}
return func(w http.ResponseWriter, r *http.Request) {
urlPath := r.URL.Path
urlPath = strings.TrimPrefix(urlPath, opts.Prefix)
for _, s := range services {
if m := s.pattern.FindStringSubmatch(urlPath); m != nil {
if r.Method != s.method {
renderStatusError(w, http.StatusMethodNotAllowed)
return
}

repo := strings.TrimPrefix(m[1], "/")
file := strings.Replace(urlPath, repo+"/", "", 1)
ep, err := transport.NewEndpoint(repo)
if err != nil {
logf(opts.ErrorLog, "error creating endpoint: %v", err)
renderStatusError(w, http.StatusBadRequest)
return
}

st, err := loader.Load(ep)
if err != nil {
logf(opts.ErrorLog, "error loading repository: %v", err)
renderStatusError(w, http.StatusNotFound)
return
}

ctx := r.Context()
ctx = context.WithValue(ctx, contextKey("errorLog"), opts.ErrorLog)
ctx = context.WithValue(ctx, contextKey("repo"), m[1])
ctx = context.WithValue(ctx, contextKey("file"), file)
ctx = context.WithValue(ctx, contextKey("service"), s.svc)
ctx = context.WithValue(ctx, contextKey("storer"), st)
ctx = context.WithValue(ctx, contextKey("endpoint"), ep)

s.handler(w, r.WithContext(ctx))
}

// ServeHTTP implements the [http.Handler] interface.
func (b *Backend) ServeHTTP(w http.ResponseWriter, r *http.Request) {
urlPath := r.URL.Path
urlPath = strings.TrimPrefix(urlPath, b.Prefix)
for _, s := range services {
if m := s.pattern.FindStringSubmatch(urlPath); m != nil {
if r.Method != s.method {
renderStatusError(w, http.StatusMethodNotAllowed)
return
}
}

// If no service matched, return 404.
renderStatusError(w, http.StatusNotFound)
repo := strings.TrimPrefix(m[1], "/")
file := strings.Replace(urlPath, repo+"/", "", 1)
ep, err := transport.NewEndpoint(repo)
if err != nil {
logf(b.ErrorLog, "error creating endpoint: %v", err)
renderStatusError(w, http.StatusBadRequest)
return
}

st, err := b.Loader.Load(ep)
if err != nil {
logf(b.ErrorLog, "error loading repository: %v", err)
renderStatusError(w, http.StatusNotFound)
return
}

ctx := r.Context()
ctx = context.WithValue(ctx, contextKey("errorLog"), b.ErrorLog)
ctx = context.WithValue(ctx, contextKey("repo"), m[1])
ctx = context.WithValue(ctx, contextKey("file"), file)
ctx = context.WithValue(ctx, contextKey("service"), s.svc)
ctx = context.WithValue(ctx, contextKey("storer"), st)
ctx = context.WithValue(ctx, contextKey("endpoint"), ep)

s.handler(w, r.WithContext(ctx))
return
}
}

// If no service matched, return 404.
renderStatusError(w, http.StatusNotFound)
}

// logf logs the given message to the error log if it is set.
Expand Down
4 changes: 2 additions & 2 deletions backend/http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (f *fixturesLoader) Load(ep *transport.Endpoint) (storage.Storer, error) {
}

func TestNilLoaderBackend(t *testing.T) {
h := NewBackend(nil, nil)
h := NewBackend(nil)
req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
h.ServeHTTP(w, req)
Expand All @@ -53,7 +53,7 @@ e8d3ffab552895c19b9fcf7aa264d277cde33881 refs/remotes/origin/branch
00486ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/remotes/origin/master
003e6ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/tags/v1.0.0
0000`
h := NewBackend(&fixturesLoader{t}, nil)
h := NewBackend(&fixturesLoader{t})

urlPath := "/basic.git/info/refs"
if isSmart {
Expand Down
3 changes: 1 addition & 2 deletions blame_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import (
"github.com/go-git/go-git/v6/plumbing/object"
"github.com/stretchr/testify/suite"

fixtures "github.com/go-git/go-git-fixtures/v4"
fixtures "github.com/go-git/go-git-fixtures/v5"
)

type BlameSuite struct {
suite.Suite
BaseSuite
}

Expand Down
65 changes: 15 additions & 50 deletions common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,11 @@ import (
"github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-billy/v5/util"
fixtures "github.com/go-git/go-git-fixtures/v4"
fixtures "github.com/go-git/go-git-fixtures/v5"
)

type BaseFixtureSuite struct {
fixtures.Suite
}

type BaseSuite struct {
suite.Suite
BaseFixtureSuite
Repository *Repository

cache map[string]*Repository
Expand All @@ -49,25 +44,16 @@ func (s *BaseSuite) buildBasicRepository() {
// is tagged as worktree the filesystem from fixture is used, otherwise a new
// memfs filesystem is used as worktree.
func (s *BaseSuite) NewRepository(f *fixtures.Fixture) *Repository {
var worktree, dotgit billy.Filesystem
dotgit := f.DotGit()
worktree := memfs.New()
if f.Is("worktree") {
r, err := PlainOpen(f.Worktree().Root())
if err != nil {
panic(err)
}

return r
worktree = f.Worktree()
}

dotgit = f.DotGit()
worktree = memfs.New()

st := filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault())

r, err := Open(st, worktree)
if err != nil {
panic(err)
}
s.Require().NoError(err)

return r
}
Expand Down Expand Up @@ -109,19 +95,11 @@ func (s *BaseSuite) NewRepositoryFromPackfile(f *fixtures.Fixture) *Repository {
p := f.Packfile()
defer func() { _ = p.Close() }()

if err := packfile.UpdateObjectStorage(storer, p); err != nil {
panic(err)
}

err := storer.SetReference(plumbing.NewHashReference(plumbing.HEAD, plumbing.NewHash(f.Head)))
if err != nil {
panic(err)
}
s.Require().NoError(packfile.UpdateObjectStorage(storer, p))
s.Require().NoError(storer.SetReference(plumbing.NewHashReference(plumbing.HEAD, plumbing.NewHash(f.Head))))

r, err := Open(storer, memfs.New())
if err != nil {
panic(err)
}
s.Require().NoError(err)

s.cache[h] = r
return r
Expand All @@ -133,20 +111,16 @@ func (s *BaseSuite) GetBasicLocalRepositoryURL() string {
}

func (s *BaseSuite) GetLocalRepositoryURL(f *fixtures.Fixture) string {
return f.DotGit().Root()
return f.DotGit(fixtures.WithTargetDir(s.T().TempDir)).Root()
}

func (s *BaseSuite) TemporalHomeDir() (path string, clean func()) {
home, err := os.UserHomeDir()
if err != nil {
panic(err)
}
s.Require().NoError(err)

fs := osfs.New(home)
relPath, err := util.TempDir(fs, "", "")
if err != nil {
panic(err)
}
s.Require().NoError(err)

path = fs.Join(fs.Root(), relPath)
clean = func() {
Expand All @@ -157,23 +131,14 @@ func (s *BaseSuite) TemporalHomeDir() (path string, clean func()) {
}

func (s *BaseSuite) TemporalFilesystem() (fs billy.Filesystem) {
// TODO: Use s.T().TempDir() here, but it fails. Investigate why.
tmpDir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
fs = osfs.New(tmpDir)
fs = osfs.New(s.T().TempDir())
path, err := util.TempDir(fs, "", "")
if err != nil {
panic(err)
}
s.Require().NoError(err)

fs, err = fs.Chroot(path)
if err != nil {
panic(err)
}
s.Require().NoError(err)

return
return fs
}

type SuiteCommon struct {
Expand Down
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ func (c *Config) marshalExtensions() {
// ignore them otherwise.
if c.Core.RepositoryFormatVersion == format.Version_1 {
s := c.Raw.Section(extensionsSection)
s.SetOption(objectFormat, string(c.Extensions.ObjectFormat))
s.SetOption(objectFormat, c.Extensions.ObjectFormat.String())
}
}

Expand Down
7 changes: 7 additions & 0 deletions crypto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package git

import (
_ "crypto/sha256" // Register Go's SHA256 implementation.

_ "github.com/pjbgf/sha1cd" // Register sha1cd implementation.
)
Loading
Loading