@@ -26,13 +26,46 @@ var (
2626 Default = Build
2727)
2828
29- // getVersion returns the version from git tag or fallback
29+ // getVersion returns the version in format TAGVERSION-N[-dirty]
30+ // - TAGVERSION: latest git tag (e.g., v1.0.0)
31+ // - N: distance (commits ahead) from the tagged commit
32+ // - Append "-dirty" if there are unstaged changes
3033func getVersion () string {
31- v , err := sh .Output ("git" , "describe" , "--tags" , "--always" , "--dirty" )
34+ // Get the latest tag reachable from HEAD
35+ tag , err := sh .Output ("git" , "describe" , "--tags" , "--abbrev=0" )
3236 if err != nil {
33- return "0.0.0-dev"
37+ // No tags found, fallback to commit hash
38+ hash , hashErr := sh .Output ("git" , "rev-parse" , "--short" , "HEAD" )
39+ if hashErr != nil {
40+ return "0.0.0-dev"
41+ }
42+ // Check dirty status
43+ if isDirty () {
44+ return hash + "-dirty"
45+ }
46+ return hash
47+ }
48+
49+ // Get distance from the tag to HEAD (number of commits)
50+ dist , err := sh .Output ("git" , "rev-list" , "--count" , tag + "..HEAD" )
51+ if err != nil || dist == "" {
52+ // If tag is the current commit, distance is 0
53+ dist = "0"
3454 }
35- return v
55+
56+ // Build version string: TAG-DISTANCE[-dirty]
57+ version := fmt .Sprintf ("%s-%s" , tag , dist )
58+ if isDirty () {
59+ version += "-dirty"
60+ }
61+ return version
62+ }
63+
64+ // isDirty checks if there are any unstaged changes in the working directory
65+ func isDirty () bool {
66+ // Check modified but unstaged files
67+ out , err := sh .Output ("git" , "status" , "--porcelain" )
68+ return err == nil && strings .TrimSpace (out ) != ""
3669}
3770
3871// getLDFLAGS returns the linker flags
0 commit comments