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