@@ -30,6 +30,7 @@ import (
3030 "github.com/codeclysm/extract/v3"
3131 "github.com/sirupsen/logrus"
3232 "gopkg.in/src-d/go-git.v4"
33+ "gopkg.in/src-d/go-git.v4/plumbing"
3334)
3435
3536type alreadyInstalledError struct {}
@@ -190,7 +191,7 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
190191 return fmt .Errorf (tr ("User directory not set" ))
191192 }
192193
193- libraryName , err := parseGitURL (gitURL )
194+ libraryName , ref , err := parseGitURL (gitURL )
194195 if err != nil {
195196 logrus .
196197 WithError (err ).
@@ -218,9 +219,13 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
218219 WithField ("git url" , gitURL ).
219220 Trace ("Installing library" )
220221
221- _ , err = git .PlainClone (installPath .String (), false , & git.CloneOptions {
222+ depth := 1
223+ if ref != "" {
224+ depth = 0
225+ }
226+ repo , err := git .PlainClone (installPath .String (), false , & git.CloneOptions {
222227 URL : gitURL ,
223- Depth : 1 ,
228+ Depth : depth ,
224229 Progress : os .Stdout ,
225230 })
226231 if err != nil {
@@ -230,6 +235,25 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
230235 return err
231236 }
232237
238+ if ref != "" {
239+ if h , err := repo .ResolveRevision (ref ); err != nil {
240+ logrus .
241+ WithError (err ).
242+ Warnf ("Resolving revision %s" , ref )
243+ return err
244+ } else if w , err := repo .Worktree (); err != nil {
245+ logrus .
246+ WithError (err ).
247+ Warn ("Finding worktree" )
248+ return err
249+ } else if err := w .Checkout (& git.CheckoutOptions {Hash : plumbing .NewHash (h .String ())}); err != nil {
250+ logrus .
251+ WithError (err ).
252+ Warnf ("Checking out %s" , h )
253+ return err
254+ }
255+ }
256+
233257 if err := validateLibrary (installPath ); err != nil {
234258 // Clean up installation directory since this is not a valid library
235259 installPath .RemoveAll ()
@@ -243,8 +267,9 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
243267
244268// parseGitURL tries to recover a library name from a git URL.
245269// Returns an error in case the URL is not a valid git URL.
246- func parseGitURL (gitURL string ) (string , error ) {
270+ func parseGitURL (gitURL string ) (string , plumbing. Revision , error ) {
247271 var res string
272+ var rev plumbing.Revision
248273 if strings .HasPrefix (gitURL , "git@" ) {
249274 // We can't parse these as URLs
250275 i := strings .LastIndex (gitURL , "/" )
@@ -254,10 +279,11 @@ func parseGitURL(gitURL string) (string, error) {
254279 } else if parsed , err := url .Parse (gitURL ); parsed .String () != "" && err == nil {
255280 i := strings .LastIndex (parsed .Path , "/" )
256281 res = strings .TrimSuffix (parsed .Path [i + 1 :], ".git" )
282+ rev = plumbing .Revision (parsed .Fragment )
257283 } else {
258- return "" , fmt .Errorf (tr ("invalid git url" ))
284+ return "" , "" , fmt .Errorf (tr ("invalid git url" ))
259285 }
260- return res , nil
286+ return res , rev , nil
261287}
262288
263289// validateLibrary verifies the dir contains a valid library, meaning it has either
0 commit comments