@@ -15,14 +15,9 @@ import (
1515
1616 "code.gitea.io/gitea/modules/process"
1717
18- "github.com/mcuadros /go-version"
18+ "github.com/hashicorp /go-version"
1919)
2020
21- // Version return this package's current version
22- func Version () string {
23- return "0.4.2"
24- }
25-
2621var (
2722 // Debug enables verbose logging on everything.
2823 // This should be false in case Gogs starts in SSH mode.
3934 // DefaultContext is the default context to run git commands in
4035 DefaultContext = context .Background ()
4136
42- gitVersion string
37+ gitVersion * version.Version
38+
39+ // will be checked on Init
40+ goVersionLessThan115 = true
4341)
4442
4543func log (format string , args ... interface {}) {
@@ -55,31 +53,43 @@ func log(format string, args ...interface{}) {
5553 }
5654}
5755
58- // BinVersion returns current Git version from shell.
59- func BinVersion () (string , error ) {
60- if len (gitVersion ) > 0 {
61- return gitVersion , nil
56+ // LocalVersion returns current Git version from shell.
57+ func LocalVersion () (* version.Version , error ) {
58+ if err := LoadGitVersion (); err != nil {
59+ return nil , err
60+ }
61+ return gitVersion , nil
62+ }
63+
64+ // LoadGitVersion returns current Git version from shell.
65+ func LoadGitVersion () error {
66+ // doesn't need RWMutex because its exec by Init()
67+ if gitVersion != nil {
68+ return nil
6269 }
6370
6471 stdout , err := NewCommand ("version" ).Run ()
6572 if err != nil {
66- return "" , err
73+ return err
6774 }
6875
6976 fields := strings .Fields (stdout )
7077 if len (fields ) < 3 {
71- return "" , fmt .Errorf ("not enough output: %s" , stdout )
78+ return fmt .Errorf ("not enough output: %s" , stdout )
7279 }
7380
81+ var versionString string
82+
7483 // Handle special case on Windows.
7584 i := strings .Index (fields [2 ], "windows" )
7685 if i >= 1 {
77- gitVersion = fields [2 ][:i - 1 ]
78- return gitVersion , nil
86+ versionString = fields [2 ][:i - 1 ]
87+ } else {
88+ versionString = fields [2 ]
7989 }
8090
81- gitVersion = fields [ 2 ]
82- return gitVersion , nil
91+ gitVersion , err = version . NewVersion ( versionString )
92+ return err
8393}
8494
8595// SetExecutablePath changes the path of git executable and checks the file permission and version.
@@ -94,11 +104,17 @@ func SetExecutablePath(path string) error {
94104 }
95105 GitExecutable = absPath
96106
97- gitVersion , err := BinVersion ()
107+ err = LoadGitVersion ()
98108 if err != nil {
99109 return fmt .Errorf ("Git version missing: %v" , err )
100110 }
101- if version .Compare (gitVersion , GitVersionRequired , "<" ) {
111+
112+ versionRequired , err := version .NewVersion (GitVersionRequired )
113+ if err != nil {
114+ return err
115+ }
116+
117+ if gitVersion .LessThan (versionRequired ) {
102118 return fmt .Errorf ("Git version not supported. Requires version > %v" , GitVersionRequired )
103119 }
104120
@@ -108,6 +124,20 @@ func SetExecutablePath(path string) error {
108124// Init initializes git module
109125func Init (ctx context.Context ) error {
110126 DefaultContext = ctx
127+
128+ // Save current git version on init to gitVersion otherwise it would require an RWMutex
129+ if err := LoadGitVersion (); err != nil {
130+ return err
131+ }
132+
133+ // Save if the go version used to compile gitea is greater or equal 1.15
134+ runtimeVersion , err := version .NewVersion (strings .TrimPrefix (runtime .Version (), "go" ))
135+ if err != nil {
136+ return err
137+ }
138+ version115 , _ := version .NewVersion ("1.15" )
139+ goVersionLessThan115 = runtimeVersion .LessThan (version115 )
140+
111141 // Git requires setting user.name and user.email in order to commit changes - if they're not set just add some defaults
112142 for configKey ,
defaultValue := range map [
string ]
string {
"user.name" :
"Gitea" ,
"user.email" :
"[email protected] " } {
113143 if err := checkAndSetConfig (configKey , defaultValue , false ); err != nil {
@@ -120,13 +150,13 @@ func Init(ctx context.Context) error {
120150 return err
121151 }
122152
123- if version . Compare ( gitVersion , " 2.10", ">=" ) {
153+ if CheckGitVersionConstraint ( ">= 2.10") == nil {
124154 if err := checkAndSetConfig ("receive.advertisePushOptions" , "true" , true ); err != nil {
125155 return err
126156 }
127157 }
128158
129- if version . Compare ( gitVersion , " 2.18", ">=" ) {
159+ if CheckGitVersionConstraint ( ">= 2.18") == nil {
130160 if err := checkAndSetConfig ("core.commitGraph" , "true" , true ); err != nil {
131161 return err
132162 }
@@ -143,6 +173,21 @@ func Init(ctx context.Context) error {
143173 return nil
144174}
145175
176+ // CheckGitVersionConstraint check version constrain against local installed git version
177+ func CheckGitVersionConstraint (constraint string ) error {
178+ if err := LoadGitVersion (); err != nil {
179+ return err
180+ }
181+ check , err := version .NewConstraint (constraint )
182+ if err != nil {
183+ return err
184+ }
185+ if ! check .Check (gitVersion ) {
186+ return fmt .Errorf ("installed git binary %s does not satisfy version constraint %s" , gitVersion .Original (), constraint )
187+ }
188+ return nil
189+ }
190+
146191func checkAndSetConfig (key , defaultValue string , forceToDefault bool ) error {
147192 stdout , stderr , err := process .GetManager ().Exec ("git.Init(get setting)" , GitExecutable , "config" , "--get" , key )
148193 if err != nil {
0 commit comments