forked from owenthereal/ccat
/
repository.go
149 lines (120 loc) · 5.15 KB
/
repository.go
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
137
138
139
140
141
142
143
144
145
146
147
148
149
package vcs
import (
"errors"
"github.com/jingweno/ccat/Godeps/_workspace/src/golang.org/x/tools/godoc/vfs"
)
// A Repository is a VCS repository.
type Repository interface {
// ResolveRevision returns the revision that the given revision
// specifier resolves to, or a non-nil error if there is no such
// revision.
//
// Implementations may choose to return ErrRevisionNotFound in all
// cases where the revision is not found, or more specific errors
// (such as ErrCommitNotFound) if spec can be partially resolved
// or determined to be a certain kind of revision specifier.
ResolveRevision(spec string) (CommitID, error)
// ResolveTag returns the tag with the given name, or
// ErrTagNotFound if no such tag exists.
ResolveTag(name string) (CommitID, error)
// ResolveBranch returns the branch with the given name, or
// ErrBranchNotFound if no such branch exists.
ResolveBranch(name string) (CommitID, error)
// Branches returns a list of all branches in the repository.
Branches(BranchesOptions) ([]*Branch, error)
// Tags returns a list of all tags in the repository.
Tags() ([]*Tag, error)
// GetCommit returns the commit with the given commit ID, or
// ErrCommitNotFound if no such commit exists.
GetCommit(CommitID) (*Commit, error)
// Commits returns all commits matching the options, as well as
// the total number of commits (the count of which is not subject
// to the N/Skip options).
Commits(CommitsOptions) (commits []*Commit, total uint, err error)
// FileSystem opens the repository file tree at a given commit ID.
//
// Implementations may choose to check that the commit exists
// before FileSystem returns or to defer the check until
// operations are performed on the filesystem. (For example, an
// implementation proxying a remote filesystem may not want to
// incur the round-trip to check that the commit exists.)
FileSystem(at CommitID) (vfs.FileSystem, error)
}
// A Blamer is a repository that can blame portions of a file.
type Blamer interface {
BlameFile(path string, opt *BlameOptions) ([]*Hunk, error)
}
// BlameOptions configures a blame.
type BlameOptions struct {
NewestCommit CommitID `json:",omitempty" url:",omitempty"`
OldestCommit CommitID `json:",omitempty" url:",omitempty"` // or "" for the root commit
StartLine int `json:",omitempty" url:",omitempty"` // 1-indexed start byte (or 0 for beginning of file)
EndLine int `json:",omitempty" url:",omitempty"` // 1-indexed end byte (or 0 for end of file)
}
// A Hunk is a contiguous portion of a file associated with a commit.
type Hunk struct {
StartLine int // 1-indexed start line number
EndLine int // 1-indexed end line number
StartByte int // 0-indexed start byte position (inclusive)
EndByte int // 0-indexed end byte position (exclusive)
CommitID
Author Signature
}
// A Differ is a repository that can compute diffs between two
// commits.
type Differ interface {
// Diff shows changes between two commits. If base or head do not
// exist, an error is returned.
Diff(base, head CommitID, opt *DiffOptions) (*Diff, error)
}
// A CrossRepoDiffer is a repository that can compute diffs with
// respect to a commit in a different repository.
type CrossRepoDiffer interface {
// CrossRepoDiff shows changes between two commits in different
// repositories. If base or head do not exist, an error is
// returned.
CrossRepoDiff(base CommitID, headRepo Repository, head CommitID, opt *DiffOptions) (*Diff, error)
}
var (
ErrBranchNotFound = errors.New("branch not found")
ErrCommitNotFound = errors.New("commit not found")
ErrRevisionNotFound = errors.New("revision not found")
ErrTagNotFound = errors.New("tag not found")
)
type CommitID string
// Marshal implements proto.Marshaler.
func (c CommitID) Marshal() ([]byte, error) {
return []byte(c), nil
}
// Unmarshal implements proto.Unmarshaler.
func (c *CommitID) Unmarshal(data []byte) error {
*c = CommitID(data)
return nil
}
// CommitsOptions specifies limits on the list of commits returned by
// (Repository).Commits.
type CommitsOptions struct {
Head CommitID // include all commits reachable from this commit (required)
Base CommitID // exlude all commits reachable from this commit (optional, like `git log Base..Head`)
N uint // limit the number of returned commits to this many (0 means no limit)
Skip uint // skip this many commits at the beginning
}
// DiffOptions configures a diff.
type DiffOptions struct {
Paths []string // constrain diff to these pathspecs
DetectRenames bool
OrigPrefix, NewPrefix string // prefixes for orig and new filenames (e.g., "a/", "b/")
ExcludeReachableFromBoth bool // like "<rev1>...<rev2>" (see `git rev-parse --help`)
}
// A Diff represents changes between two commits.
type Diff struct {
Raw string // the raw diff output
}
type Branches []*Branch
func (p Branches) Len() int { return len(p) }
func (p Branches) Less(i, j int) bool { return p[i].Name < p[j].Name }
func (p Branches) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Tags []*Tag
func (p Tags) Len() int { return len(p) }
func (p Tags) Less(i, j int) bool { return p[i].Name < p[j].Name }
func (p Tags) Swap(i, j int) { p[i], p[j] = p[j], p[i] }