bug: store the referenced media in their own git tree under /media, as per the doc I wrote myself

This commit is contained in:
Michael Muré 2018-08-05 15:23:51 +02:00
parent 597b0ea0d2
commit 90fb85e067
No known key found for this signature in database
GPG Key ID: A4457C029293126F
2 changed files with 50 additions and 18 deletions

View File

@ -3,15 +3,17 @@ package bug
import (
"errors"
"fmt"
"strings"
"github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util"
"strings"
)
const bugsRefPattern = "refs/bugs/"
const bugsRemoteRefPattern = "refs/remotes/%s/bugs/"
const opsEntryName = "ops"
const rootEntryName = "root"
const mediaEntryName = "media"
const idLength = 40
const humanIdLength = 7
@ -28,8 +30,11 @@ type Bug struct {
// TODO: need a way to order bugs, probably a Lamport clock
// all the commited operations
packs []OperationPack
// a temporary pack of operations used for convenience to pile up new operations
// before a commit
staging OperationPack
}
@ -252,6 +257,7 @@ func (bug *Bug) IsValid() bool {
return true
}
// Append an operation into the staging area, to be commited later
func (bug *Bug) Append(op Operation) {
bug.staging.Append(op)
}
@ -272,7 +278,7 @@ func (bug *Bug) Commit(repo repository.Repo) error {
bug.rootPack = hash
}
// Make a Git tree referencing this blob and all needed files
// Make a Git tree referencing this blob
tree := []repository.TreeEntry{
// the last pack of ops
{ObjectType: repository.Blob, Hash: hash, Name: opsEntryName},
@ -280,22 +286,23 @@ func (bug *Bug) Commit(repo repository.Repo) error {
{ObjectType: repository.Blob, Hash: bug.rootPack, Name: rootEntryName},
}
counter := 0
added := make(map[util.Hash]interface{})
for _, ops := range bug.staging.Operations {
for _, file := range ops.Files() {
if _, has := added[file]; !has {
tree = append(tree, repository.TreeEntry{
ObjectType: repository.Blob,
Hash: file,
Name: fmt.Sprintf("file%d", counter),
})
counter++
added[file] = struct{}{}
}
// Also reference if any all the files required by the ops
// Git will check that they actually exist in the storage and will make sure
// to push/pull them as needed.
mediaTree := makeMediaTree(bug.staging)
if len(mediaTree) > 0 {
mediaTreeHash, err := repo.StoreTree(mediaTree)
if err != nil {
return err
}
tree = append(tree, repository.TreeEntry{
ObjectType: repository.Tree,
Hash: mediaTreeHash,
Name: mediaEntryName,
})
}
// Store the tree
hash, err = repo.StoreTree(tree)
if err != nil {
return err
@ -320,6 +327,8 @@ func (bug *Bug) Commit(repo repository.Repo) error {
}
// Create or update the Git reference for this bug
// When pushing later, the remote will ensure that this ref update
// is fast-forward, that is no data has been overwritten
ref := fmt.Sprintf("%s%s", bugsRefPattern, bug.id)
err = repo.UpdateRef(ref, hash)
@ -333,6 +342,30 @@ func (bug *Bug) Commit(repo repository.Repo) error {
return nil
}
func makeMediaTree(pack OperationPack) []repository.TreeEntry {
var tree []repository.TreeEntry
counter := 0
added := make(map[util.Hash]interface{})
for _, ops := range pack.Operations {
for _, file := range ops.Files() {
if _, has := added[file]; !has {
tree = append(tree, repository.TreeEntry{
ObjectType: repository.Blob,
Hash: file,
// The name is not important here, we only need to
// reference the blob.
Name: fmt.Sprintf("file%d", counter),
})
counter++
added[file] = struct{}{}
}
}
}
return tree
}
// Merge a different version of the same bug by rebasing operations of this bug
// that are not present in the other on top of the chain of operations of the
// other version.

View File

@ -2,9 +2,10 @@ package bug
import (
"fmt"
"github.com/MichaelMure/git-bug/repository"
"io"
"strings"
"github.com/MichaelMure/git-bug/repository"
)
const MsgMergeNew = "new"
@ -139,5 +140,3 @@ func MergeAll(repo repository.Repo, remote string) <-chan MergeResult {
return out
}