repo.go

  1package git
  2
  3import (
  4	"path/filepath"
  5
  6	"github.com/gogs/git-module"
  7)
  8
  9var (
 10	DiffMaxFiles     = 1000
 11	DiffMaxFileLines = 1000
 12	DiffMaxLineChars = 1000
 13)
 14
 15// Repository is a wrapper around git.Repository with helper methods.
 16type Repository struct {
 17	*git.Repository
 18	Path string
 19}
 20
 21// Clone clones a repository.
 22func Clone(src, dst string, opts ...git.CloneOptions) error {
 23	return git.Clone(src, dst, opts...)
 24}
 25
 26// Init initializes and opens a new git repository.
 27func Init(path string, bare bool) (*Repository, error) {
 28	err := git.Init(path, git.InitOptions{Bare: bare})
 29	if err != nil {
 30		return nil, err
 31	}
 32	return Open(path)
 33}
 34
 35// Open opens a git repository at the given path.
 36func Open(path string) (*Repository, error) {
 37	repo, err := git.Open(path)
 38	if err != nil {
 39		return nil, err
 40	}
 41	return &Repository{
 42		Repository: repo,
 43		Path:       path,
 44	}, nil
 45}
 46
 47// Name returns the name of the repository.
 48func (r *Repository) Name() string {
 49	return filepath.Base(r.Path)
 50}
 51
 52// HEAD returns the HEAD reference for a repository.
 53func (r *Repository) HEAD() (*Reference, error) {
 54	rn, err := r.SymbolicRef()
 55	if err != nil {
 56		return nil, err
 57	}
 58	hash, err := r.ShowRefVerify(rn)
 59	if err != nil {
 60		return nil, err
 61	}
 62	return &Reference{
 63		Reference: &git.Reference{
 64			ID:      hash,
 65			Refspec: rn,
 66		},
 67		Hash: Hash(hash),
 68		path: r.Path,
 69	}, nil
 70}
 71
 72// References returns the references for a repository.
 73func (r *Repository) References() ([]*Reference, error) {
 74	refs, err := r.ShowRef()
 75	if err != nil {
 76		return nil, err
 77	}
 78	rrefs := make([]*Reference, 0, len(refs))
 79	for _, ref := range refs {
 80		rrefs = append(rrefs, &Reference{
 81			Reference: ref,
 82			Hash:      Hash(ref.ID),
 83			path:      r.Path,
 84		})
 85	}
 86	return rrefs, nil
 87}
 88
 89// Tree returns the tree for the given reference.
 90func (r *Repository) Tree(ref *Reference) (*Tree, error) {
 91	if ref == nil {
 92		rref, err := r.HEAD()
 93		if err != nil {
 94			return nil, err
 95		}
 96		ref = rref
 97	}
 98	tree, err := r.LsTree(ref.Hash.String())
 99	if err != nil {
100		return nil, err
101	}
102	return &Tree{
103		Tree: tree,
104		Path: "",
105	}, nil
106}
107
108// TreePath returns the tree for the given path.
109func (r *Repository) TreePath(ref *Reference, path string) (*Tree, error) {
110	path = filepath.Clean(path)
111	if path == "." {
112		path = ""
113	}
114	if path == "" {
115		return r.Tree(ref)
116	}
117	t, err := r.Tree(ref)
118	if err != nil {
119		return nil, err
120	}
121	return t.SubTree(path)
122}
123
124// Diff returns the diff for the given commit.
125func (r *Repository) Diff(commit *Commit) (*Diff, error) {
126	ddiff, err := r.Repository.Diff(commit.Hash.String(), DiffMaxFiles, DiffMaxFileLines, DiffMaxLineChars)
127	if err != nil {
128		return nil, err
129	}
130	files := make([]*DiffFile, 0, len(ddiff.Files))
131	for _, df := range ddiff.Files {
132		sections := make([]*DiffSection, 0, len(df.Sections))
133		for _, ds := range df.Sections {
134			sections = append(sections, &DiffSection{
135				DiffSection: ds,
136			})
137		}
138		files = append(files, &DiffFile{
139			DiffFile: df,
140			Sections: sections,
141		})
142	}
143	diff := &Diff{
144		Diff:  ddiff,
145		Files: files,
146	}
147	return diff, nil
148}
149
150// Patch returns the patch for the given reference.
151func (r *Repository) Patch(commit *Commit) (string, error) {
152	diff, err := r.Diff(commit)
153	if err != nil {
154		return "", err
155	}
156	return diff.Patch(), err
157}
158
159// CountCommits returns the number of commits in the repository.
160func (r *Repository) CountCommits(ref *Reference) (int64, error) {
161	return r.Repository.RevListCount([]string{ref.Name().String()})
162}
163
164// CommitsByPage returns the commits for a given page and size.
165func (r *Repository) CommitsByPage(ref *Reference, page, size int) (Commits, error) {
166	cs, err := r.Repository.CommitsByPage(ref.Name().String(), page, size)
167	if err != nil {
168		return nil, err
169	}
170	commits := make(Commits, len(cs))
171	for i, c := range cs {
172		commits[i] = &Commit{
173			Commit: c,
174			Hash:   Hash(c.ID.String()),
175		}
176	}
177	return commits, nil
178}
179
180// UpdateServerInfo updates the repository server info.
181func (r *Repository) UpdateServerInfo() error {
182	cmd := git.NewCommand("update-server-info")
183	_, err := cmd.RunInDir(r.Path)
184	return err
185}