@@ -61,7 +61,7 @@ type CheckoutBranch struct {
61
61
}
62
62
63
63
func (c * CheckoutBranch ) Checkout (ctx context.Context , path , url string , opts * git.AuthOptions ) (* git.Commit , error ) {
64
- repo , err := git2go . Clone (url , path , & git2go.CloneOptions {
64
+ repo , err := safeClone (url , path , & git2go.CloneOptions {
65
65
FetchOptions : git2go.FetchOptions {
66
66
DownloadTags : git2go .DownloadTagsNone ,
67
67
RemoteCallbacks : RemoteCallbacks (ctx , opts ),
@@ -94,7 +94,7 @@ type CheckoutTag struct {
94
94
}
95
95
96
96
func (c * CheckoutTag ) Checkout (ctx context.Context , path , url string , opts * git.AuthOptions ) (* git.Commit , error ) {
97
- repo , err := git2go . Clone (url , path , & git2go.CloneOptions {
97
+ repo , err := safeClone (url , path , & git2go.CloneOptions {
98
98
FetchOptions : git2go.FetchOptions {
99
99
DownloadTags : git2go .DownloadTagsAll ,
100
100
RemoteCallbacks : RemoteCallbacks (ctx , opts ),
@@ -118,7 +118,7 @@ type CheckoutCommit struct {
118
118
}
119
119
120
120
func (c * CheckoutCommit ) Checkout (ctx context.Context , path , url string , opts * git.AuthOptions ) (* git.Commit , error ) {
121
- repo , err := git2go . Clone (url , path , & git2go.CloneOptions {
121
+ repo , err := safeClone (url , path , & git2go.CloneOptions {
122
122
FetchOptions : git2go.FetchOptions {
123
123
DownloadTags : git2go .DownloadTagsNone ,
124
124
RemoteCallbacks : RemoteCallbacks (ctx , opts ),
@@ -150,7 +150,7 @@ func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, opts *g
150
150
return nil , fmt .Errorf ("semver parse error: %w" , err )
151
151
}
152
152
153
- repo , err := git2go . Clone (url , path , & git2go.CloneOptions {
153
+ repo , err := safeClone (url , path , & git2go.CloneOptions {
154
154
FetchOptions : git2go.FetchOptions {
155
155
DownloadTags : git2go .DownloadTagsAll ,
156
156
RemoteCallbacks : RemoteCallbacks (ctx , opts ),
@@ -239,6 +239,19 @@ func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, opts *g
239
239
return buildCommit (cc , "refs/tags/" + t ), nil
240
240
}
241
241
242
+ // safeClone wraps git2go calls with panic recovering logic, ensuring
243
+ // a predictable execution path for callers.
244
+ func safeClone (url , path string , cloneOpts * git2go.CloneOptions ) (repo * git2go.Repository , err error ) {
245
+ defer func () {
246
+ if r := recover (); r != nil {
247
+ err = fmt .Errorf ("recovered from git2go panic: %v" , r )
248
+ }
249
+ }()
250
+
251
+ repo , err = git2go .Clone (url , path , cloneOpts )
252
+ return
253
+ }
254
+
242
255
// checkoutDetachedDwim attempts to perform a detached HEAD checkout by first DWIMing the short name
243
256
// to get a concrete reference, and then calling checkoutDetachedHEAD.
244
257
func checkoutDetachedDwim (repo * git2go.Repository , name string ) (* git2go.Commit , error ) {
0 commit comments