go-git: `empty git-upload-pack given` errors since v5.4.0

We are extensive consumers of this library and besides the issue reported in #323, we have seen an increase of empty git-upload-pack given errors reported by our users since we upgraded from v5.3.0 to v5.4.x.

The error seems unrelated to the Git v2 protocol as reported in #64 or #157, given users that previously were able to perform operations on their e.g. GitHub repository using v5.3.0 are now no longer able to do so using v5.4.x.

~Diving into the changelog nothing directly related seems to have changed, except for some plumbing changes in #246.~

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 10
  • Comments: 34 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Yes, but limiting depth is super useful and I need it. If I don’t specify depth my program is way slower.

Same here with version v5.5.1, downgrade to v5.3.0 and it works

@ydcool , @talwat , I am solving the issue by not specifying depth.

Still getting this error when going a clone with a depth specified, then running git pull without depth on v5.9

Got same issue. I have to downgrade to v5.3.0, what’s the progress now?

Same here.

@taigrr The version v5.8.0 was released last week and should contain the fix.

I wasn’t specifying Depth on the Pull(), but was on the initial Clone() and get this error on any subsequent Pull().

If I remove specifying Depth on the Clone(), the Pull()s work fine.

This is not ideal for me since my service is useless until the initial clone is complete and making it shallower reduces that time. The repo I’m working with has a very long (and mostly irrelevant) history, so I was trying to limit that initial transfer. I just need the last couple weeks of changes at a given point in time.

The issue started with https://github.com/go-git/go-git/commit/320db9af8ba8b0046e833013504eb07c61a3573c

Works before

$ go get github.com/go-git/go-git/v5@db2bc57350561c4368a8d32c42476699b48d2a09
go get: downgraded github.com/go-git/go-git/v5 v5.3.1-0.20210512203949-320db9af8ba8 => v5.3.1-0.20210503000431-db2bc5735056
$ laszlo@laszlo-XPS-13-9370:~/projects/empty-uploadpack$ go test
PASS
ok  	github.com/laszlocph/empty-upload-pack	1.847s

Fails afterwards:

$laszlo@laszlo-XPS-13-9370:~/projects/empty-uploadpack$ go get github.com/go-git/go-git/v5@320db9af8ba8b0046e833013504eb07c61a3573c
go get: upgraded github.com/go-git/go-git/v5 v5.3.1-0.20210503000431-db2bc5735056 => v5.3.1-0.20210512203949-320db9af8ba8
$ laszlo@laszlo-XPS-13-9370:~/projects/empty-uploadpack$ go test
--- FAIL: Test_emptyUploadPack (1.50s)
    uploadpack_test.go:41: empty git-upload-pack given
FAIL
exit status 1
FAIL	github.com/laszlocph/empty-upload-pack	1.509s

Using Version 5.8.0

Hey, I think there may still be an issue here. It appears that this fails if I don’t specify a Depth in the Pull function. If I run the command line git pull within a shallow cloned directory, the pull succeeds.

The reason this is valuable is that specifying Depth will cause the Pull to fail if the the number of commits between the local HEAD and the remote HEAD is greater than the depth. This happens because git cannot determine that the fetched commits are descendants of the local branch. Command line git appears to pull enough commits to determine the ancestry, which was the behavior I was hoping would exist here. However, when I run without the Depth specified, I run into the same empty git-upload-pack given error.

Let me know if I’m misunderstanding something.

The following script reproduces the issue by panic’ing on the error from Pull:

package main

import (
	"os"
	"strings"

	gogit "github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing/transport/http"
)

func main() {
	t := os.Getenv("GITHUB_API_TOKEN")

	auth := &http.BasicAuth{
		Username: "username",
		Password: strings.TrimSuffix(t, "\n"),
	}

	cloneOptions := gogit.CloneOptions{
		Auth:         auth,
		URL:          "xxx",
		SingleBranch: true,
		Depth:        1,
	}

	d, err := os.MkdirTemp("", "")
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(d)
	repo, err := gogit.PlainClone(d, false, &cloneOptions)
	if err != nil {
		panic(err)
	}
	w, err := repo.Worktree()
	if err != nil {
		panic(err)
	}
	err = w.Pull(&gogit.PullOptions{
		Auth: auth,
	})
	if err != nil && err != gogit.NoErrAlreadyUpToDate {
		panic(err)
	}
}

These changes did end up fixing the issue I was having in one of my repos.

Any chance we could get a new version tagged release so we can go get -u ?

Thanks in advance, go-git team.

This issue is still persistent with v5.6.1. Downgraded to v5.3.0 which seems to work for now. Though, this is not ideal since the update path is blocked through this issue.

Edit: Depth is not set in my case.

This issue has remained present and active for a while now, and the best solution I found is to just use os.Exec.