@@ -20,16 +20,53 @@ package source
2020
2121import (
2222 "fmt"
23+ "path/filepath"
24+ "strings"
2325
2426 git2go "github.com/libgit2/git2go/v34"
2527)
2628
29+ const (
30+ // The error returned by libgit2 when the user is not the owner of the git repository.
31+ safeDirectoryNotFoundErrorMsg = "config value 'safe.directory' was not found"
32+ )
33+
34+ // isSafeDirectoryNotFoundError checks if the error is a safe.directory not found error.
35+ func isSafeDirectoryNotFoundError (err error ) bool {
36+ if err != nil {
37+ return strings .Contains (err .Error (), safeDirectoryNotFoundErrorMsg )
38+ }
39+
40+ return false
41+ }
42+
2743type git struct {}
2844
2945func (g * git ) Parse (workspace string ) (* Info , error ) {
3046 repo , err := git2go .OpenRepository (workspace )
3147 if err != nil {
32- return nil , fmt .Errorf ("failed to open repository at %s: %w" , workspace , err )
48+ // Try to set safe.directory manually if it is not found, and try to open repository again.
49+ if isSafeDirectoryNotFoundError (err ) {
50+ config , err := git2go .OpenDefault ()
51+ if err != nil {
52+ return nil , fmt .Errorf ("failed to open config: %w" , err )
53+ }
54+ defer config .Free ()
55+
56+ absWorkspace , err := filepath .Abs (workspace )
57+ if err != nil {
58+ return nil , fmt .Errorf ("failed to get absolute path of workspace: %w" , err )
59+ }
60+
61+ if err := config .SetString ("safe.directory" , absWorkspace ); err != nil {
62+ return nil , fmt .Errorf ("failed to set safe.directory: %w" , err )
63+ }
64+ }
65+
66+ repo , err = git2go .OpenRepository (workspace )
67+ if err != nil {
68+ return nil , fmt .Errorf ("failed to open repository at %s: %w" , workspace , err )
69+ }
3370 }
3471 defer repo .Free ()
3572
0 commit comments