git/libgit2: set CheckoutForce on branch strategy

In the recent update from libgit2 1.1.x to 1.3.x, something seems to
have changed upstream. Resulting in the clone of a branch ending up
with a semi-bare file system state (in other words: without any files
present in the directory).

This commit patches the clone behavior to set the `CheckoutForce`
strategy as `CheckoutOption`, which mitigates the issue.

In addition, test cases have been added to ensure we do not run into
this again by asserting the state of the branch after cloning.

Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
Hidde Beydals 2022-02-22 13:53:13 +01:00
parent b65cf9d535
commit 15c064abdf
3 changed files with 22 additions and 2 deletions

View File

@ -58,17 +58,20 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
branch string branch string
filesCreated map[string]string
expectedCommit string expectedCommit string
expectedErr string expectedErr string
}{ }{
{ {
name: "Default branch", name: "Default branch",
branch: "master", branch: "master",
filesCreated: map[string]string{"branch": "init"},
expectedCommit: firstCommit.String(), expectedCommit: firstCommit.String(),
}, },
{ {
name: "Other branch", name: "Other branch",
branch: "test", branch: "test",
filesCreated: map[string]string{"branch": "second"},
expectedCommit: secondCommit.String(), expectedCommit: secondCommit.String(),
}, },
{ {
@ -90,12 +93,18 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
cc, err := branch.Checkout(context.TODO(), tmpDir, path, nil) cc, err := branch.Checkout(context.TODO(), tmpDir, path, nil)
if tt.expectedErr != "" { if tt.expectedErr != "" {
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(ContainSubstring(tt.expectedErr)) g.Expect(err.Error()).To(ContainSubstring(tt.expectedErr))
g.Expect(cc).To(BeNil()) g.Expect(cc).To(BeNil())
return return
} }
g.Expect(err).To(BeNil()) g.Expect(err).ToNot(HaveOccurred())
g.Expect(cc.String()).To(Equal(tt.branch + "/" + tt.expectedCommit)) g.Expect(cc.String()).To(Equal(tt.branch + "/" + tt.expectedCommit))
for k, v := range tt.filesCreated {
g.Expect(filepath.Join(tmpDir, k)).To(BeARegularFile())
g.Expect(os.ReadFile(filepath.Join(tmpDir, k))).To(BeEquivalentTo(v))
}
}) })
} }
} }

View File

@ -66,6 +66,9 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
RemoteCallbacks: RemoteCallbacks(ctx, opts), RemoteCallbacks: RemoteCallbacks(ctx, opts),
ProxyOptions: git2go.ProxyOptions{Type: git2go.ProxyTypeAuto}, ProxyOptions: git2go.ProxyOptions{Type: git2go.ProxyTypeAuto},
}, },
CheckoutOptions: git2go.CheckoutOptions{
Strategy: git2go.CheckoutForce,
},
CheckoutBranch: c.Branch, CheckoutBranch: c.Branch,
}) })
if err != nil { if err != nil {
@ -79,7 +82,7 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
defer head.Free() defer head.Free()
cc, err := repo.LookupCommit(head.Target()) cc, err := repo.LookupCommit(head.Target())
if err != nil { if err != nil {
return nil, fmt.Errorf("could not find commit '%s' in branch '%s': %w", head.Target(), c.Branch, err) return nil, fmt.Errorf("failed to lookup HEAD commit '%s' for branch '%s': %w", head.Target(), c.Branch, err)
} }
defer cc.Free() defer cc.Free()
return buildCommit(cc, "refs/heads/"+c.Branch), nil return buildCommit(cc, "refs/heads/"+c.Branch), nil

View File

@ -73,17 +73,20 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
branch string branch string
filesCreated map[string]string
expectedCommit string expectedCommit string
expectedErr string expectedErr string
}{ }{
{ {
name: "Default branch", name: "Default branch",
branch: defaultBranch, branch: defaultBranch,
filesCreated: map[string]string{"branch": "second"},
expectedCommit: secondCommit.String(), expectedCommit: secondCommit.String(),
}, },
{ {
name: "Other branch", name: "Other branch",
branch: "test", branch: "test",
filesCreated: map[string]string{"branch": "init"},
expectedCommit: firstCommit.String(), expectedCommit: firstCommit.String(),
}, },
{ {
@ -112,6 +115,11 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
} }
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
g.Expect(cc.String()).To(Equal(tt.branch + "/" + tt.expectedCommit)) g.Expect(cc.String()).To(Equal(tt.branch + "/" + tt.expectedCommit))
for k, v := range tt.filesCreated {
g.Expect(filepath.Join(tmpDir, k)).To(BeARegularFile())
g.Expect(os.ReadFile(filepath.Join(tmpDir, k))).To(BeEquivalentTo(v))
}
}) })
} }
} }