in snapshot/cli/cli.go [216:302]
func (c *createGitBundleCommand) run(db snapshot.DB, _ *cobra.Command, _ []string) error {
if c.basis == "" || c.ref == "" {
return fmt.Errorf("Create bundle command requires a basis and reference")
}
validOutput := false
for _, o := range outputTypes {
if o == c.outputType {
validOutput = true
break
}
}
if !validOutput {
return fmt.Errorf("Output type must be one of: %q", outputTypes)
}
wd, err := os.Getwd()
if err != nil {
return fmt.Errorf("cannot get working directory: wd")
}
ingestRepo, err := repo.NewRepository(wd)
if err != nil {
return fmt.Errorf("not a valid repo dir: %v, %v", wd, err)
}
gdb, ok := db.(*gitdb.DB)
if !ok {
return fmt.Errorf("create bundle requires a gitdb.DB snapshot.DB")
}
td, err := ioutil.TempDir("", "")
if err != nil {
return fmt.Errorf("Couldn't create temp dir: %v", err)
}
defer func() {
os.RemoveAll(td)
}()
// Don't use commit sha as bundle name as it could collide with other bundles.
// Use the rev-list for the given basis/ref to generate a unique sha
// Use this non-commit sha as bundleKey for a snapshot, but still parse
// commit sha of provided ref to use as snapshot sha.
// TODO (dgassaway): this would be better off in a proper library package
revList := fmt.Sprintf("%s..%s", c.basis, c.ref)
revData, err := ingestRepo.Run("rev-list", revList)
if err != nil {
return fmt.Errorf("Couldn't get rev-list for %s: %v", revList, err)
}
log.Infof("Using rev-list for %s:\n%s\n", revList, revData)
commit, err := ingestRepo.Run("rev-parse", c.ref)
if err != nil {
return fmt.Errorf("Couldn't rev-parse ref %s: %v", c.ref, err)
}
commit = strings.TrimSpace(commit)
// Add ref name to the rev-list we are bundling - otherwise we can create collisions
// where a bundle with the same commit content but different ref name can get the same sha1
revData += c.ref
revSha1 := fmt.Sprintf("%x", sha1.Sum([]byte(revData)))
bundleFilename := path.Join(td, fmt.Sprintf("bs-%s.bundle", revSha1))
if _, err := ingestRepo.Run("-c",
"core.packobjectedgesonlyshallow=0",
"bundle",
"create",
bundleFilename,
revList); err != nil {
return err
}
ttlP := &store.TTLValue{TTL: time.Now().Add(c.ttld), TTLKey: store.DefaultTTLKey}
location, err := gdb.UploadFile(bundleFilename, ttlP)
if err != nil {
return err
}
if c.outputType == outputTypeLocation {
fmt.Println(location)
} else if c.outputType == outputTypeSnapshotID {
// Create a bundlestoreSnapshot to be able to return a valid snapshot ID
bs := gitdb.CreateBundlestoreSnapshot(commit, gitdb.KindGitCommitSnapshot, revSha1, gdb.StreamName())
fmt.Println(bs.ID())
}
return nil
}