| Index: sdk/lib/_internal/pub/lib/src/source/git.dart
|
| diff --git a/sdk/lib/_internal/pub/lib/src/source/git.dart b/sdk/lib/_internal/pub/lib/src/source/git.dart
|
| index 2981ebe42f6f8a27073a5f7c9fc61a853bb8e370..afec7bf0a70e15388184b967b7ae6c3611c9640a 100644
|
| --- a/sdk/lib/_internal/pub/lib/src/source/git.dart
|
| +++ b/sdk/lib/_internal/pub/lib/src/source/git.dart
|
| @@ -45,7 +45,7 @@ class GitSource extends Source {
|
| }
|
|
|
| ensureDir(path.join(systemCacheRoot, 'cache'));
|
| - return _ensureRepoCache(id);
|
| + return _ensureRevision(id);
|
| }).then((_) => systemCacheDirectory(id)).then((path) {
|
| revisionCachePath = path;
|
| if (entryExists(revisionCachePath)) return null;
|
| @@ -61,7 +61,7 @@ class GitSource extends Source {
|
|
|
| /// Returns the path to the revision-specific cache of [id].
|
| Future<String> systemCacheDirectory(PackageId id) {
|
| - return _revisionAt(id).then((rev) {
|
| + return _ensureRevision(id).then((rev) {
|
| var revisionCacheName = '${id.name}-$rev';
|
| return path.join(systemCacheRoot, revisionCacheName);
|
| });
|
| @@ -107,7 +107,7 @@ class GitSource extends Source {
|
|
|
| /// Attaches a specific commit to [id] to disambiguate it.
|
| Future<PackageId> resolveId(PackageId id) {
|
| - return _revisionAt(id).then((revision) {
|
| + return _ensureRevision(id).then((revision) {
|
| var description = {'url': _getUrl(id), 'ref': _getRef(id)};
|
| description['resolved-ref'] = revision;
|
| return new PackageId(id.name, name, id.version, description);
|
| @@ -117,22 +117,50 @@ class GitSource extends Source {
|
| // TODO(keertip): Implement getCachedPackages().
|
|
|
| /// Ensure that the canonical clone of the repository referred to by [id] (the
|
| - /// one in `<system cache>/git/cache`) exists and is up-to-date. Returns a
|
| - /// future that completes once this is finished and throws an exception if it
|
| - /// fails.
|
| - Future _ensureRepoCache(PackageId id) {
|
| + /// one in `<system cache>/git/cache`) exists and contains the revision
|
| + /// referred to by [id].
|
| + ///
|
| + /// Returns a future that completes to the hash of the revision identified by
|
| + /// [id].
|
| + Future<String> _ensureRevision(PackageId id) {
|
| return syncFuture(() {
|
| var path = _repoCachePath(id);
|
| - if (!entryExists(path)) return _clone(_getUrl(id), path, mirror: true);
|
| - return git.run(["fetch"], workingDir: path).then((result) => null);
|
| + if (!entryExists(path)) {
|
| + return _clone(_getUrl(id), path, mirror: true)
|
| + .then((_) => _revParse(id));
|
| + }
|
| +
|
| + // If [id] didn't come from a lockfile, it may be using a symbolic
|
| + // reference. We want to get the latest version of that reference.
|
| + var description = id.description;
|
| + if (description is! Map || !description.containsKey('resolved-ref')) {
|
| + return _updateRepoCache(id).then((_) => _revParse(id));
|
| + }
|
| +
|
| + // If [id] did come from a lockfile, then we want to avoid running "git
|
| + // fetch" if possible to avoid networking time and errors. See if the
|
| + // revision exists in the repo cache before updating it.
|
| + return _revParse(id).catchError((error) {
|
| + if (error is! GitException) throw error;
|
| + return _updateRepoCache(id).then((_) => _revParse(id));
|
| + });
|
| });
|
| }
|
|
|
| - /// Returns a future that completes to the revision hash of [id].
|
| - Future<String> _revisionAt(PackageId id) {
|
| - return _ensureRepoCache(id).then((_) =>
|
| - git.run(["rev-parse", _getEffectiveRef(id)],
|
| - workingDir: _repoCachePath(id)).then((result) => result[0]));
|
| + /// Runs "git fetch" in the canonical clone of the repository referred to by
|
| + /// [id].
|
| + ///
|
| + /// This assumes that the canonical clone already exists.
|
| + Future _updateRepoCache(PackageId id) =>
|
| + git.run(["fetch"], workingDir: _repoCachePath(id));
|
| +
|
| + /// Runs "git rev-parse" in the canonical clone of the repository referred to
|
| + /// by [id] on the effective ref of [id].
|
| + ///
|
| + /// This assumes that the canonical clone already exists.
|
| + Future<String> _revParse(PackageId id) {
|
| + return git.run(["rev-parse", _getEffectiveRef(id)],
|
| + workingDir: _repoCachePath(id)).then((result) => result.first);
|
| }
|
|
|
| /// Clones the repo at the URI [from] to the path [to] on the local
|
|
|