Skip to content

internal: servers, add git server implementation#2014

Merged
pjbgf merged 6 commits into
go-git:mainfrom
aymanbagabas:git-server
May 6, 2026
Merged

internal: servers, add git server implementation#2014
pjbgf merged 6 commits into
go-git:mainfrom
aymanbagabas:git-server

Conversation

@aymanbagabas

@aymanbagabas aymanbagabas commented Apr 24, 2026

Copy link
Copy Markdown
Member

This adds a new Git TCP server implementation based on the existing backend package. All the tests that use the internal/server.All() for testing now will also use a git daemon git:// TCP server in addition to the existing HTTP server.

I assume this can eventually grow to offer a full git-daemon implementation that can replace go-git/cli/server/git

@aymanbagabas aymanbagabas requested a review from pjbgf April 24, 2026 19:32
@aymanbagabas aymanbagabas force-pushed the git-server branch 2 times, most recently from 80016a4 to 2e441dd Compare April 27, 2026 15:18
This adds a new Git TCP server implementation based on the existing
backend package.

Signed-off-by: Ayman Bagabas <ayman.bagabas@gmail.com>
Signed-off-by: Ayman Bagabas <ayman.bagabas@gmail.com>
Signed-off-by: Ayman Bagabas <ayman.bagabas@gmail.com>
pjbgf added 2 commits May 1, 2026 14:17
Reject repeated Start calls for the git and HTTP test servers while preserving one-shot server lifecycle state.

Assisted-By: Codex GPT 5.5  <noreply@openai.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
Move common server coverage into an internal/server suite that runs against both git and HTTP implementations.

Assisted-By: Codex GPT 5.5  <noreply@openai.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
Copilot AI review requested due to automatic review settings May 1, 2026 13:18
pjbgf
pjbgf previously approved these changes May 1, 2026

@pjbgf pjbgf left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aymanbagabas thanks for working on this. 🙇

I added two additional commits:

  1. Enforce safe flows (e.g. can't call Start() on a started server) for both git and http implementation.
  2. Moved some of the tests into a suite to exercise across all implementations.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an in-process git:// (TCP) server implementation under internal/server/git, integrates it into the server helper set, and expands test coverage so suites using internal/server.All() can exercise both HTTP and Git transports.

Changes:

  • Introduce a new internal/server/git TCP server built on the existing backend package.
  • Update internal/server.All() to include the new git server alongside HTTP.
  • Adjust packp.GitProtoRequest validation/tests and add/extend server tests for both transports.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
plumbing/protocol/packp/gitproto_test.go Updates encoding validation test case coverage for GitProtoRequest.
plumbing/protocol/packp/gitproto.go Modifies GitProtoRequest validation rules (pathname no longer validated).
internal/server/servers_test.go Adds a suite to run common server behavior tests across HTTP and git:// implementations.
internal/server/servers.go Extends All() to include the new git:// server implementation.
internal/server/http/http.go Adds start-state tracking and locking around HTTP server start/endpoint/close behavior.
internal/server/git/git_test.go Adds integration tests for the git:// server (archive, timeouts, max connections).
internal/server/git/git.go Implements the git:// TCP server, connection tracking, and deadline management.
Comments suppressed due to low confidence (1)

plumbing/protocol/packp/gitproto_test.go:45

  • This test now duplicates TestEncodeEmptyGitProtoRequest (both encode a zero-value GitProtoRequest and only assert a non-nil error). It no longer covers the previously distinct invalid case (non-empty RequestCommand with missing/empty Pathname), so the suite loses meaningful coverage. Consider restoring a separate assertion for the missing-pathname case (especially if pathname validation is reinstated).
func TestEncodeInvalidGitProtoRequest(t *testing.T) {
	t.Parallel()
	var buf bytes.Buffer
	p := GitProtoRequest{}
	err := p.Encode(&buf)
	if err == nil {
		t.Fatal("expected error")
	}
}

Comment thread internal/server/git/git.go Outdated
Comment thread internal/server/servers.go Outdated
Comment thread internal/server/git/git_test.go Outdated
Comment thread internal/server/git/git_test.go
Comment on lines 31 to 37
// validate validates the request.
func (g *GitProtoRequest) validate() error {
if g.RequestCommand == "" {
return fmt.Errorf("%w: empty request command", ErrInvalidGitProtoRequest)
}

if g.Pathname == "" {
return fmt.Errorf("%w: empty pathname", ErrInvalidGitProtoRequest)
}

return nil

Copilot AI May 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitProtoRequest.Encode always writes a " \x00" line, but validate() no longer rejects an empty Pathname. That allows encoding a syntactically invalid git:// request ("command \x00"), which can mask caller bugs (e.g., URL with empty path) and diverge from the documented pack-protocol transport format. Consider restoring the empty-pathname validation (and/or tightening Decode to reject an empty pathname as well).

Copilot uses AI. Check for mistakes.
Comment thread internal/server/git/git.go Outdated
The cancel func stored in s.conns was tied to a discarded context, so
nothing it gated actually cancelled backend.Serve. Wire a single
per-connection context through addConn/removeConn/cancelConn so that
timeouts, Close, and connection removal all abort the backend handler.

InitTimeout was recomputed from time.Now() on every updateDeadline
call, letting a slow client trickling bytes keep extending the
handshake deadline indefinitely (slowloris). Compute and store an
absolute initDeadline once at accept time.

Tighten the related tests: assert that the rejected MaxConnections
client sees EOF rather than returning early on any Connect error, and
make the Timeout test deterministic by inducing an idle period instead
of racing handshake+GetRemoteRefs against a 100ms budget.

Assisted-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
Entire-Checkpoint: ee43feb8a5f3

@pjbgf pjbgf left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aymanbagabas thanks for working on this. 🙇

@pjbgf pjbgf merged commit 9bca9e0 into go-git:main May 6, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants