in snapshot/git/gitdb/bundlestore.go [204:265]
func (s *bundlestoreSnapshot) Download(db *DB) error {
log.Infof("Downloading sha: %s", s.SHA())
if err := db.shaPresent(s.SHA()); err == nil {
log.Infof("We already have sha: %s, returning from Download()", s.SHA())
return nil
}
dlDir, filename, err := s.downloadBundle(db)
if dlDir != "" {
defer os.RemoveAll(dlDir)
}
if err != nil {
log.Info("Unable to download bundle: ", err)
return err
}
// unbundle optimistically
// this will succeed if we have all of the prerequisite objects
if _, err = db.dataRepo.Run("bundle", "unbundle", filename); err == nil {
log.Infof("Unbundling got the sha: %s, returning from Download()", s.SHA())
return db.shaPresent(s.sha)
}
// we couldn't unbundle
// see if it's because we're missing prereqs
lacksCommitsStr := "error: Repository lacks these prerequisite commits:"
exitError, ok := err.(*exec.ExitError)
if ok && exitError == nil || ok && !strings.Contains(string(exitError.Stderr), lacksCommitsStr) {
log.Info("Can't find sha: ", s.SHA(), " and prereqs aren't the problem, returning err: ", err.Error())
return err
} else if !ok {
log.Info("Error of unexpected type while unbundling, returning err:", err.Error())
return err
}
if db.bundles.cfg.AllowStreamUpdate {
// we are missing prereqs, so let's try updating the stream that's the basis of the bundle
// this likely happened because:
// we're in a worker that started at time T1, when master pointed at commit C1
// at time T2, a commit C2 was created in our stream
// at time T3, a user ingested a git commit C3 whose ancestor is C2
// GitDB in their scoot-snapshot-db picked a merge-base of C2, because T3-T2 was sufficiently
// large (say, a half hour) that it's reasonable to assume its easy to get.
// Now we've got the bundle for C3, which depends on C2, but we only have C1, so we have to
// update our stream.
if err := db.stream.updateStream(s.streamName, db); err != nil {
log.Infof("Couldn't download sha: %s, updateStream returned error: %s", s.SHA(), err.Error())
return err
}
if _, err := db.dataRepo.Run("bundle", "unbundle", filename); err != nil {
// if we still can't unbundle, then the bundle might be corrupt or the
// prereqs might not be in the stream, or maybe the git server is serving us
// stale data.
log.Infof("Couldn't download sha: %s, the final unbundling attempt returned error: %s", s.SHA(), err.Error())
return err
}
}
return db.shaPresent(s.sha)
}