Reduce time required for cloning remote bases

This commit changes git/cloner.go from cloning the whole history
and then checking out the desired ref to a implementation that
only downloads the history for the desired ref.

It does so by first initializing an empty repository, setting the
source repository as a remote, fetching just the desired ref and
then hard resetting the empty local repo to that ref.

This reduces the time it takes to build the multibases example
as a remote base at ref v2.0.3 from an avg of 8s with the
current implementation to an avg of 2s out of 10 runs each, by
drastically decreasing the data transferred.

The improvement should increase as repositories grow.
This commit is contained in:
Philipp Strube
2019-03-06 19:13:38 +01:00
parent a6f6514412
commit 4f429d6b86

View File

@@ -41,24 +41,61 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
}
cmd := exec.Command(
gitProgram,
"clone",
repoSpec.CloneSpec(),
"init",
repoSpec.cloneDir.String())
var out bytes.Buffer
cmd.Stdout = &out
err = cmd.Run()
if err != nil {
return errors.Wrapf(err, "trouble cloning %s", repoSpec.raw)
return errors.Wrapf(
err,
"trouble initializing empty git repo in %s",
repoSpec.cloneDir.String())
}
if repoSpec.ref == "" {
return nil
}
cmd = exec.Command(gitProgram, "checkout", repoSpec.ref)
cmd = exec.Command(
gitProgram,
"remote",
"add",
"origin",
repoSpec.CloneSpec())
cmd.Stdout = &out
cmd.Dir = repoSpec.cloneDir.String()
err = cmd.Run()
if err != nil {
return errors.Wrapf(
err, "trouble checking out href %s", repoSpec.ref)
err,
"trouble adding remote %s",
repoSpec.CloneSpec())
}
if repoSpec.ref == "" {
return nil
}
cmd = exec.Command(
gitProgram,
"fetch",
"--depth=1",
"origin",
repoSpec.ref)
cmd.Stdout = &out
cmd.Dir = repoSpec.cloneDir.String()
err = cmd.Run()
if err != nil {
return errors.Wrapf(err, "trouble fetching %s", repoSpec.ref)
}
cmd = exec.Command(
gitProgram,
"reset",
"--hard",
"FETCH_HEAD")
cmd.Stdout = &out
cmd.Dir = repoSpec.cloneDir.String()
err = cmd.Run()
if err != nil {
return errors.Wrapf(
err, "trouble hard resetting empty repository to %s", repoSpec.ref)
}
return nil
}