git-module

git clone git://git.lin.moe/fork/git-module.git

 1package git
 2
 3import (
 4	"bytes"
 5	"context"
 6)
 7
 8// BlameOptions contains optional arguments for blaming a file.
 9// Docs: https://git-scm.com/docs/git-blame
10type BlameOptions struct {
11	CommandOptions
12}
13
14// Blame returns blame results of the file with the given revision of the
15// repository.
16func (r *Repository) Blame(ctx context.Context, rev, file string, opts ...BlameOptions) (*Blame, error) {
17	var opt BlameOptions
18	if len(opts) > 0 {
19		opt = opts[0]
20	}
21
22	args := []string{"blame", "-l", "-s", rev, "--", file}
23	stdout, err := exec(ctx, r.path, args, opt.Envs)
24	if err != nil {
25		return nil, err
26	}
27
28	lines := bytes.Split(stdout, []byte{'\n'})
29	blame := &Blame{
30		lines: make([]*Commit, 0, len(lines)),
31	}
32	for _, line := range lines {
33		if len(line) < 40 {
34			break
35		}
36		id := line[:40]
37
38		// Earliest commit is indicated by a leading "^"
39		if id[0] == '^' {
40			id = id[1:]
41		}
42		commit, err := r.CatFileCommit(ctx, string(id)) //nolint
43		if err != nil {
44			return nil, err
45		}
46		blame.lines = append(blame.lines, commit)
47	}
48	return blame, nil
49}