aboutsummaryrefslogtreecommitdiffstats
path: root/bug
diff options
context:
space:
mode:
Diffstat (limited to 'bug')
-rw-r--r--bug/bug.go63
-rw-r--r--bug/bug_actions.go5
2 files changed, 50 insertions, 18 deletions
diff --git a/bug/bug.go b/bug/bug.go
index 61f58c78..d4eafdf2 100644
--- a/bug/bug.go
+++ b/bug/bug.go
@@ -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.
diff --git a/bug/bug_actions.go b/bug/bug_actions.go
index 85123e1c..b2bc8b7d 100644
--- a/bug/bug_actions.go
+++ b/bug/bug_actions.go
@@ -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
}
-
-