Optimize retrieving from git repositories

Instead of cloning from a remote git repository for each branch,
revision or tag separately, the git resolver locally clones only once
the remote git repository and then creates further local clones from
this local copy of the remote repository.

First, optimization, of course, is execution speed, because cloning
local repository is much faster than remote repository. Furthermore,
because git uses hard-linking when a clone of local repository is
created, the second optimization is in space consumption.

For example, if we have one project that uses
https://github.com/harrah/xsbt.git#v0.11.1 and second project that
uses https://github.com/harrah/xsbt.git#v0.11.2, in previous git
resolver implementation it would require two separate clones of the
remote git repository at https://github.com/harrah/xsbt.git. But, the
new git resolver requires only one clone of the remote git repository
and two local clones which take no space because of hard-linking.
This commit is contained in:
Sanjin Sehic 2011-12-19 10:43:42 +01:00 committed by Mark Harrah
parent 942427bfa3
commit 77626f5232
2 changed files with 18 additions and 5 deletions

View File

@ -51,19 +51,27 @@ object Resolvers
run(Some(in), "git", "checkout", "-q", branch)
}
def retrieveLocalCopy(at: URI, into: File) =
def normalized(uri: URI) = uri.copy(scheme = "git")
def retrieveLocalCopy(at: URI, into: File) = creates(into) {clone(at.withoutFragment.toASCIIString, into)}
def retrieveBranch(branch: String, from: File, into: File) =
{
creates(into) {
clone(at.withoutFragment.toASCIIString, into)
if (at.hasFragment)
checkout(branch = at.getFragment, in = into)
clone(at = from.getAbsolutePath, into = into)
checkout(branch, in = into)
}
}
val uri = info.uri
val staging = info.staging
Some {
() =>
retrieveLocalCopy(at = uri, into = uniqueSubdirectoryFor(uri, in = info.staging))
val localCopy = retrieveLocalCopy(at = uri, into = uniqueSubdirectoryFor(normalized(uri.withoutFragment), in = staging))
if (uri.hasFragment)
retrieveBranch(branch = uri.getFragment, from = localCopy, into = uniqueSubdirectoryFor(normalized(uri), in = staging))
else
localCopy
}
}

View File

@ -8,6 +8,11 @@ import java.net.URI
class RichURI(uri: URI)
{
def copy(scheme: String = uri.getScheme, userInfo: String = uri.getUserInfo,
host: String = uri.getHost, port: Int = uri.getPort, path: String = uri.getPath,
query: String = uri.getQuery, fragment: String = uri.getFragment) =
new URI(scheme, userInfo, host, port, path, query, fragment)
def hasFragment = uri.getFragment ne null
def withoutFragment =