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

[PRETEST]: Added support for bare repo in clone function of git module #419

Merged
merged 9 commits into from
Aug 12, 2024
Prev Previous commit
Next Next commit
Fixed CI failure
Signed-off-by: Manoramsharma <img_2020037@iiitm.ac.in>
Manoramsharma committed Aug 1, 2024
commit 56aae17f29f87d6bba54b5d14d82740b01149de9
70 changes: 0 additions & 70 deletions pkg/git/git.go
Original file line number Diff line number Diff line change
@@ -110,72 +110,6 @@ func (cloneOpts *CloneOptions) Validate() error {
return nil
}

// CheckoutFromBare checks out the specified reference from a bare repository
// func (cloneOpts *CloneOptions) CheckoutFromBare() error {
// if !cloneOpts.Bare {
// return errors.New("repository is not bare")
// }

// repo, err := git.PlainOpen(cloneOpts.LocalPath)
// if err != nil {
// return err
// }

// worktree, err := repo.Worktree()
// if err != nil {
// return err
// }

// checkoutOpts := &git.CheckoutOptions{
// Force: true,
// }

// if cloneOpts.Branch != "" {
// checkoutOpts.Branch = plumbing.NewBranchReferenceName(cloneOpts.Branch)
// } else if cloneOpts.Tag != "" {
// checkoutOpts.Branch = plumbing.NewTagReferenceName(cloneOpts.Tag)
// } else if cloneOpts.Commit != "" {
// hash := plumbing.NewHash(cloneOpts.Commit)
// checkoutOpts.Hash = hash
// }

// return worktree.Checkout(checkoutOpts)
// }
//
// Clone clones a git repository
func (cloneOpts *CloneOptions) cloneBare() (*git.Repository, error) {
args := []string{"clone", "--bare"}
if cloneOpts.Commit != "" {
args = append(args, "--no-checkout")
}
args = append(args, cloneOpts.RepoURL, cloneOpts.LocalPath)

cmd := exec.Command("git", args...)
cmd.Stdout = cloneOpts.Writer
cmd.Stderr = cloneOpts.Writer

if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("failed to clone bare repository: %w", err)
}

repo, err := git.PlainOpen(cloneOpts.LocalPath)
if err != nil {
return nil, err
}

if cloneOpts.Commit != "" {
cmd = exec.Command("git", "update-ref", "HEAD", cloneOpts.Commit)
cmd.Dir = cloneOpts.LocalPath
cmd.Stdout = cloneOpts.Writer
cmd.Stderr = cloneOpts.Writer
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("failed to update HEAD to specified commit: %w", err)
}
}

return repo, nil
}

// CheckoutFromBare checks out the specified reference from a bare repository
Copy link
Contributor

Choose a reason for hiding this comment

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

Why comment here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have left this function commented because I need review from @zong-zhe over the checkout implementation from bare, which I don't feel would be achieved something like that I did.

func (cloneOpts *CloneOptions) CheckoutFromBare() error {
Manoramsharma marked this conversation as resolved.
Show resolved Hide resolved
if !cloneOpts.Bare {
@@ -271,10 +205,6 @@ func CloneWithOpts(opts ...CloneOption) (*git.Repository, error) {
return nil, err
}

if cloneOpts.Bare {
return cloneOpts.cloneBare()
}

return cloneOpts.Clone()
}

92 changes: 26 additions & 66 deletions pkg/git/git_test.go
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ import (
"path/filepath"
"testing"

"gotest.tools/v3/assert"
"github.com/go-git/go-git/v5/plumbing"
"gotest.tools/v3/assert"
)

func TestWithGitOptions(t *testing.T) {
@@ -62,7 +62,7 @@ func TestCloneWithOptions(t *testing.T) {

repo, err := CloneWithOpts(
WithRepoURL("https://github.com/KusionStack/catalog.git"),
WithCommit("4e59d5852cd7"),
WithCommit("4e59d5852cd76542f9f0ec65e5773ca9f4e02462"),
WithWriter(&buf),
WithLocalPath(tmpdir),
)
@@ -85,7 +85,7 @@ func TestCloneWithOptions(t *testing.T) {

_, err = CloneWithOpts(
WithRepoURL("https://github.com/KusionStack/catalog.git"),
WithCommit("4e59d5852cd7"),
WithCommit("4e59d5852cd76542f9f0ec65e5773ca9f4e02462"),
WithWriter(&buf),
WithLocalPath(tmpdir),
WithBare(true), // Set the Bare flag to true
@@ -107,91 +107,51 @@ func TestCloneWithOptions(t *testing.T) {
})
}

func TestCloneWithOptionsBare(t *testing.T) {
func TestCheckoutFromBare(t *testing.T) {
var buf bytes.Buffer
tmpdir, err := os.MkdirTemp("", "git-bare")
tmpdir, err := os.MkdirTemp("", "git-bare-checkout")
assert.NilError(t, err)
defer func() {
rErr := os.RemoveAll(tmpdir)
assert.NilError(t, rErr)
}()


// First, clone a bare repository
repoURL := "https://github.com/KusionStack/catalog.git"
commitSHA := "4e59d5852cd76542f9f0ec65e5773ca9f4e02462"

repo, err := CloneWithOpts(
WithRepoURL("https://github.com/KusionStack/catalog.git"),
WithCommit(commitSHA),
WithRepoURL(repoURL),
WithWriter(&buf),
WithLocalPath(tmpdir),
WithBare(true),
)
if err != nil {
t.Fatalf("Failed to clone bare repository: %v\nBuffer contents:\n%s", err, buf.String())
}
assert.NilError(t, err, "Failed to clone bare repository: %s", buf.String())

// Verify that the repository is bare
config, err := repo.Config()
assert.NilError(t, err)
assert.Equal(t, config.Core.IsBare, true, "Expected repository to be bare")

// Verify that the repository is bare by checking for the absence of a .git directory
// and the presence of HEAD file in the root directory
_, err = os.Stat(filepath.Join(tmpdir, ".git"))
assert.Assert(t, os.IsNotExist(err), "Expected .git directory to not exist in a bare repo")
// Now, attempt to update HEAD to a specific commit
checkoutOpts := &CloneOptions{
RepoURL: repoURL,
LocalPath: tmpdir,
Commit: commitSHA,
Writer: &buf,
Bare: true,
}

_, err = os.Stat(filepath.Join(tmpdir, "HEAD"))
assert.NilError(t, err, "Expected HEAD file to exist in bare repo root")
err = checkoutOpts.CheckoutFromBare()
assert.NilError(t, err, "Failed to update HEAD in bare repository: %s", buf.String())

// Verify that HEAD points to the specified commit
head, err := repo.Head()
assert.NilError(t, err)
assert.Equal(t, head.Hash().String(), commitSHA, "Expected HEAD to point to the specified commit")
}

func TestCheckoutFromBare(t *testing.T) {
var buf bytes.Buffer
tmpdir, err := os.MkdirTemp("", "git-bare-checkout")
assert.NilError(t, err)
defer func() {
rErr := os.RemoveAll(tmpdir)
assert.NilError(t, rErr)
}()

// First, clone a bare repository
repoURL := "https://github.com/KusionStack/catalog.git"
commitSHA := "4e59d5852cd76542f9f0ec65e5773ca9f4e02462"

repo, err := CloneWithOpts(
WithRepoURL(repoURL),
WithWriter(&buf),
WithLocalPath(tmpdir),
WithBare(true),
)
assert.NilError(t, err, "Failed to clone bare repository: %s", buf.String())

// Verify that the repository is bare
config, err := repo.Config()
assert.NilError(t, err)
assert.Equal(t, config.Core.IsBare, true, "Expected repository to be bare")

// Now, attempt to update HEAD to a specific commit
checkoutOpts := &CloneOptions{
RepoURL: repoURL,
LocalPath: tmpdir,
Commit: commitSHA,
Writer: &buf,
Bare: true,
}

err = checkoutOpts.CheckoutFromBare()
assert.NilError(t, err, "Failed to update HEAD in bare repository: %s", buf.String())

// Verify that HEAD points to the specified commit
head, err := repo.Head()
assert.NilError(t, err)
assert.Equal(t, head.Hash().String(), commitSHA, "Expected HEAD to point to the specified commit")

// For a bare repository, we can't check for working directory files
// Instead, we can verify that the commit exists in the repository
_, err = repo.CommitObject(plumbing.NewHash(commitSHA))
assert.NilError(t, err, "Expected commit to exist in the repository")
}
// For a bare repository, we can't check for working directory files
// Instead, we can verify that the commit exists in the repository
_, err = repo.CommitObject(plumbing.NewHash(commitSHA))
assert.NilError(t, err, "Expected commit to exist in the repository")
}