Skip to content

Commit 4a99201

Browse files
committed
git/version.go: replace sync.Mutex usage with sync.Once
We use a sync.Mutex to synchronize access to the string pointer `gitVersion`, which indicates the version of Git used by the system running Git LFS. Our basic usage of the sync.Mutex is not incorrect, but we can improve the readability by instead using a sync.Once. A sync.Once determines very quickly (and in an atomic, goroutine-safe fashion) whether or not _any_ function has been run, and if it hasn't, run it. By doing this, we can--at the first request--produce a value for the result of running 'git version', and then return it later to the caller. This has the following benefits: - If 'git version' has already been run, we do not need to hold the lock for the entire duration of the function. - If 'git version' has not already been run, we only run it once, retaining the existing behavior. Only one change, which is the introduction of the `gitVersionErr` variable. This is a consequence of executing the 'git version' call in a closure: since we're in a new stack frame, we can't return from our parent. Instead, we retain the value for all time, and return _it_, along with whatever value we got from running 'git version' in the first place.
1 parent fd35a47 commit 4a99201

1 file changed

Lines changed: 8 additions & 12 deletions

File tree

git/version.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,17 @@ import (
1010
)
1111

1212
var (
13-
gitVersion *string
14-
gitVersionMu sync.Mutex
13+
gitVersionOnce sync.Once
14+
gitVersion string
15+
gitVersionErr error
1516
)
1617

1718
func Version() (string, error) {
18-
gitVersionMu.Lock()
19-
defer gitVersionMu.Unlock()
20-
21-
if gitVersion == nil {
22-
v, err := subprocess.SimpleExec("git", "version")
23-
gitVersion = &v
24-
return v, err
25-
}
26-
27-
return *gitVersion, nil
19+
gitVersionOnce.Do(func() {
20+
gitVersion, gitVersionErr =
21+
subprocess.SimpleExec("git", "version")
22+
})
23+
return gitVersion, gitVersionErr
2824
}
2925

3026
// IsVersionAtLeast returns whether the git version is the one specified or higher

0 commit comments

Comments
 (0)