1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
// Package repository contains helper methods for working with a Git repo.
package repository
import (
"bytes"
"strings"
"github.com/MichaelMure/git-bug/util/git"
"github.com/MichaelMure/git-bug/util/lamport"
)
// RepoCommon represent the common function the we want all the repo to implement
type RepoCommon interface {
// GetPath returns the path to the repo.
GetPath() string
// GetUserName returns the name the the user has used to configure git
GetUserName() (string, error)
// GetUserEmail returns the email address that the user has used to configure git.
GetUserEmail() (string, error)
// GetCoreEditor returns the name of the editor that the user has used to configure git.
GetCoreEditor() (string, error)
// StoreConfig store a single key/value pair in the config of the repo
StoreConfig(key string, value string) error
// ReadConfigs read all key/value pair matching the key prefix
ReadConfigs(keyPrefix string) (map[string]string, error)
}
// Repo represents a source code repository.
type Repo interface {
RepoCommon
// FetchRefs fetch git refs from a remote
FetchRefs(remote string, refSpec string) (string, error)
// PushRefs push git refs to a remote
PushRefs(remote string, refSpec string) (string, error)
// StoreData will store arbitrary data and return the corresponding hash
StoreData(data []byte) (git.Hash, error)
// ReadData will attempt to read arbitrary data from the given hash
ReadData(hash git.Hash) ([]byte, error)
// StoreTree will store a mapping key-->Hash as a Git tree
StoreTree(mapping []TreeEntry) (git.Hash, error)
// StoreCommit will store a Git commit with the given Git tree
StoreCommit(treeHash git.Hash) (git.Hash, error)
// StoreCommit will store a Git commit with the given Git tree
StoreCommitWithParent(treeHash git.Hash, parent git.Hash) (git.Hash, error)
// UpdateRef will create or update a Git reference
UpdateRef(ref string, hash git.Hash) error
// ListRefs will return a list of Git ref matching the given refspec
ListRefs(refspec string) ([]string, error)
// RefExist will check if a reference exist in Git
RefExist(ref string) (bool, error)
// CopyRef will create a new reference with the same value as another one
CopyRef(source string, dest string) error
// ListCommits will return the list of tree hashes of a ref, in chronological order
ListCommits(ref string) ([]git.Hash, error)
// ListEntries will return the list of entries in a Git tree
ListEntries(hash git.Hash) ([]TreeEntry, error)
// FindCommonAncestor will return the last common ancestor of two chain of commit
FindCommonAncestor(hash1 git.Hash, hash2 git.Hash) (git.Hash, error)
// GetTreeHash return the git tree hash referenced in a commit
GetTreeHash(commit git.Hash) (git.Hash, error)
}
type ClockedRepo interface {
Repo
// LoadClocks read the clocks values from the on-disk repo
LoadClocks() error
// WriteClocks write the clocks values into the repo
WriteClocks() error
// CreateTimeIncrement increment the creation clock and return the new value.
CreateTimeIncrement() (lamport.Time, error)
// EditTimeIncrement increment the edit clock and return the new value.
EditTimeIncrement() (lamport.Time, error)
// CreateWitness witness another create time and increment the corresponding
// clock if needed.
CreateWitness(time lamport.Time) error
// EditWitness witness another edition time and increment the corresponding
// clock if needed.
EditWitness(time lamport.Time) error
}
func prepareTreeEntries(entries []TreeEntry) bytes.Buffer {
var buffer bytes.Buffer
for _, entry := range entries {
buffer.WriteString(entry.Format())
}
return buffer
}
func readTreeEntries(s string) ([]TreeEntry, error) {
split := strings.Split(s, "\n")
casted := make([]TreeEntry, len(split))
for i, line := range split {
if line == "" {
continue
}
entry, err := ParseTreeEntry(line)
if err != nil {
return nil, err
}
casted[i] = entry
}
return casted, nil
}
|