Merge pull request #494 from Masterminds/feat/lazy-concurrent-update-on-install

Glide install skips fetch when it is up to date
diff --git a/repo/installer.go b/repo/installer.go
index fee26c4..420ac27 100644
--- a/repo/installer.go
+++ b/repo/installer.go
@@ -111,8 +111,8 @@
 
 	msg.Info("Downloading dependencies. Please wait...")
 
-	ConcurrentUpdate(newConf.Imports, cwd, i, newConf)
-	ConcurrentUpdate(newConf.DevImports, cwd, i, newConf)
+	LazyConcurrentUpdate(newConf.Imports, cwd, i, newConf)
+	LazyConcurrentUpdate(newConf.DevImports, cwd, i, newConf)
 	return newConf, nil
 }
 
@@ -302,6 +302,43 @@
 	return conf.Imports
 }
 
+// LazyConcurrentUpdate updates only deps that are not already checkout out at the right version.
+//
+// This is only safe when updating from a lock file.
+func LazyConcurrentUpdate(deps []*cfg.Dependency, cwd string, i *Installer, c *cfg.Config) error {
+
+	newDeps := []*cfg.Dependency{}
+	for _, dep := range deps {
+		destPath := filepath.Join(i.VendorPath(), dep.Name)
+
+		// Get a VCS object for this directory
+		repo, err := dep.GetRepo(destPath)
+		if err != nil {
+			newDeps = append(newDeps, dep)
+			continue
+		}
+
+		ver, err := repo.Version()
+		if err != nil {
+			newDeps = append(newDeps, dep)
+			continue
+		}
+
+		if ver == dep.Reference {
+			msg.Info("--> Found desired version %s %s!", dep.Name, dep.Reference)
+			continue
+		}
+
+		msg.Debug("--> Queue %s for update (%s != %s).", dep.Name, ver, dep.Reference)
+		newDeps = append(newDeps, dep)
+	}
+	if len(newDeps) > 0 {
+		return ConcurrentUpdate(newDeps, cwd, i, c)
+	}
+
+	return nil
+}
+
 // ConcurrentUpdate takes a list of dependencies and updates in parallel.
 func ConcurrentUpdate(deps []*cfg.Dependency, cwd string, i *Installer, c *cfg.Config) error {
 	done := make(chan struct{}, concurrentWorkers)
diff --git a/repo/vcs.go b/repo/vcs.go
index 31bed50..3f5f80d 100644
--- a/repo/vcs.go
+++ b/repo/vcs.go
@@ -203,14 +203,14 @@
 		}
 
 		ver := dep.Reference
-		// Referenes in Git can begin with a ^ which is similar to semver.
+		// References in Git can begin with a ^ which is similar to semver.
 		// If there is a ^ prefix we assume it's a semver constraint rather than
 		// part of the git/VCS commit id.
 		if repo.IsReference(ver) && !strings.HasPrefix(ver, "^") {
 			msg.Info("--> Setting version for %s to %s.\n", dep.Name, ver)
 		} else {
 
-			// Create the constraing first to make sure it's valid before
+			// Create the constraint first to make sure it's valid before
 			// working on the repo.
 			constraint, err := semver.NewConstraint(ver)