Skip to content
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

Unable to clone/push to an empty repo #986

Open
Darylddd opened this issue Jan 6, 2024 · 7 comments
Open

Unable to clone/push to an empty repo #986

Darylddd opened this issue Jan 6, 2024 · 7 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@Darylddd
Copy link

Darylddd commented Jan 6, 2024

If it is a new repo, there is only the HEAD file in .git, and the reference corresponding to HEAD cannot be found.

@Darylddd
Copy link
Author

Darylddd commented Jan 6, 2024

$ go run main.go https://github.com/Darylddd/EmptyRepo.git ./new/
git clone https://github.com/Darylddd/EmptyRepo.git ./new/ --recursive
error: remote repository is empty
exit status 1

@Darylddd
Copy link
Author

Darylddd commented Jan 6, 2024

And also for a empty remote repo, if push something, it also occurs an error. Repository push failed, error: remote repository is empty

@Darylddd Darylddd changed the title unable to clone an empty repo unable to clone/push to an empty repo Jan 6, 2024
@Darylddd Darylddd changed the title unable to clone/push to an empty repo Unable to clone/push to an empty repo Jan 6, 2024
@pjbgf pjbgf added bug Something isn't working help wanted Extra attention is needed labels Jan 17, 2024
@onee-only
Copy link
Contributor

And also for a empty remote repo, if push something, it also occurs an error. Repository push failed, error: remote repository is empty

I can't reproduce this issue. Could you give me an example code?

@pjbgf
Copy link
Member

pjbgf commented Apr 11, 2024

AFAIK the clone part is intentional, and the ErrEmptyRemoteRepository is returned so callers can then check for that error and act accordingly. I don't think we want to change that part.

@Darylddd please share a code snippet so that it is easier to reproduce the error trying to push to an empty repository.

@onee-only
Copy link
Contributor

AFAIK the clone part is intentional, and the ErrEmptyRemoteRepository is returned so callers can then check for that error and act accordingly. I don't think we want to change that part.

I've looked through about half of the projects for how they use ErrEmptyRemoteRepository in their code.
Most of them were just ignoring it or initializing a new repo.

Including the project you referenced, most of projects uses PlainInit and (*Repository).CreateRemote to create a repo.
But those are already executed inside Clone or PlainClone at here and here before the error is returned.
I'm guessing returning error from clone could make people think everything failed and do redundant work again.

So I think hiding ErrEmptyRemoteRepository inside it and supporting (*Repository).IsEmpty or returning isEmpty bool value, etc... could be good idea.

Another issue with returning error is when we pull or fetch from empty repo.

This is git command line behavior.

$ git pull origin
Your configuration specifies to merge with the ref 'refs/heads/main'
from the remote, but no such ref was fetched.
$ git fetch origin # no output. possibly no-op.

This is go-git code snippet.

package main

import (
	"fmt"

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

func main() {
	// opening an empty repo
	r, err := git.PlainOpen("./empty")
	if err != nil {
		panic(err)
	}

	err = r.Fetch(&git.FetchOptions{})
	if err != nil {
		if err == transport.ErrEmptyRemoteRepository {
			fmt.Println("remote repository empty")
		}
	}

	wt, err := r.Worktree()
	if err != nil {
		panic(err)
	}

	err = wt.Pull(&git.PullOptions{})
	if err != nil {
		if err == transport.ErrEmptyRemoteRepository {
			fmt.Println("remote repository empty")
		}
	}
}
$ go run main.go
remote repository empty
remote repository empty

I think this kind of is inconsistency between go-git and git if you think we have to match behavior between those two.

@pjbgf
Copy link
Member

pjbgf commented Apr 14, 2024

I think this kind of is inconsistency between go-git and git if you think we have to match behavior between those two.

This behaviour is by design and is meant to be documented as per #909. As nicely pointed out by Hidde:

To elaborate a bit more on this: when you would clone an empty repository there are is little information available about what to do next, e.g. what should the default branch be?

While git has potentially configuration files for this (i.e. ~/.gitconfig). Programmatically, it is not desired to assume to look for these (by default). Which makes it more desirable to detect this error, and initialize the repository and first branch yourself based on the applicable configuration, than to make certain assumptions (which may result in other unwanted behavior in the end).

Not all applications that rely on go-git are the same. Some of them require a repository not to be empty in order to do what they need to do (e.g. repository analysis), those would handle the error and short-circuit their logic. Others would validate the error and initialise a new repository.

In the future, we could look into making it easier to support the second use case with minimal amount of code needed. But that is beyond the scope of this issue and would be an enhancement request on its own right.

@onee-only
Copy link
Contributor

onee-only commented Apr 14, 2024

You have the point. I didn't know there were discussion about this. Thanks for answering!

Then we'll only need to check if push fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants