1
0
Fork 0
mirror of https://github.com/vbatts/git-validation.git synced 2024-11-29 03:25:39 +00:00
git-validation/git/commits.go
Vincent Batts ca8252252b
git: do not include merges in the commit range
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2017-03-21 10:13:01 -04:00

134 lines
3.6 KiB
Go

package git
import (
"os"
"os/exec"
"strings"
"github.com/Sirupsen/logrus"
)
// Commits returns a set of commits.
// If commitrange is a git still range 12345...54321, then it will be isolated set of commits.
// If commitrange is a single commit, all ancestor commits up through the hash provided.
func Commits(commitrange string) ([]CommitEntry, error) {
cmdArgs := []string{"git", "--no-pager", "log", `--no-merges`, `--pretty=format:%H`, commitrange}
if debug() {
logrus.Infof("[git] cmd: %q", strings.Join(cmdArgs, " "))
}
output, err := exec.Command(cmdArgs[0], cmdArgs[1:]...).Output()
if err != nil {
return nil, err
}
commitHashes := strings.Split(strings.TrimSpace(string(output)), "\n")
commits := make([]CommitEntry, len(commitHashes))
for i, commitHash := range commitHashes {
c, err := LogCommit(commitHash)
if err != nil {
return commits, err
}
commits[i] = *c
}
return commits, nil
}
// FieldNames are for the formating and rendering of the CommitEntry structs.
// Keys here are from git log pretty format "format:..."
var FieldNames = map[string]string{
"%h": "abbreviated_commit",
"%p": "abbreviated_parent",
"%t": "abbreviated_tree",
"%aD": "author_date",
"%aE": "author_email",
"%aN": "author_name",
"%b": "body",
"%H": "commit",
"%N": "commit_notes",
"%cD": "committer_date",
"%cE": "committer_email",
"%cN": "committer_name",
"%e": "encoding",
"%P": "parent",
"%D": "refs",
"%f": "sanitized_subject_line",
"%GS": "signer",
"%GK": "signer_key",
"%s": "subject",
"%G?": "verification_flag",
}
// Check warns if changes introduce whitespace errors.
// Returns non-zero if any issues are found.
func Check(commit string) ([]byte, error) {
cmd := exec.Command("git", "--no-pager", "show", "--check", commit)
if debug() {
logrus.Infof("[git] cmd: %q", strings.Join(cmd.Args, " "))
}
cmd.Stderr = os.Stderr
return cmd.Output()
}
// Show returns the diff of a commit.
//
// NOTE: This could be expensive for very large commits.
func Show(commit string) ([]byte, error) {
cmd := exec.Command("git", "--no-pager", "show", commit)
if debug() {
logrus.Infof("[git] cmd: %q", strings.Join(cmd.Args, " "))
}
cmd.Stderr = os.Stderr
return cmd.Output()
}
// CommitEntry represents a single commit's information from `git`.
// See also FieldNames
type CommitEntry map[string]string
// LogCommit assembles the full information on a commit from its commit hash
func LogCommit(commit string) (*CommitEntry, error) {
c := CommitEntry{}
for k, v := range FieldNames {
cmd := exec.Command("git", "--no-pager", "log", "-1", `--pretty=format:`+k+``, commit)
if debug() {
logrus.Infof("[git] cmd: %q", strings.Join(cmd.Args, " "))
}
cmd.Stderr = os.Stderr
out, err := cmd.Output()
if err != nil {
return nil, err
}
c[v] = strings.TrimSpace(string(out))
}
return &c, nil
}
func debug() bool {
return len(os.Getenv("DEBUG")) > 0
}
// FetchHeadCommit returns the hash of FETCH_HEAD
func FetchHeadCommit() (string, error) {
cmdArgs := []string{"git", "--no-pager", "rev-parse", "--verify", "FETCH_HEAD"}
if debug() {
logrus.Infof("[git] cmd: %q", strings.Join(cmdArgs, " "))
}
output, err := exec.Command(cmdArgs[0], cmdArgs[1:]...).Output()
if err != nil {
return "", err
}
return strings.TrimSpace(string(output)), nil
}
// HeadCommit returns the hash of HEAD
func HeadCommit() (string, error) {
cmdArgs := []string{"git", "--no-pager", "rev-parse", "--verify", "HEAD"}
if debug() {
logrus.Infof("[git] cmd: %q", strings.Join(cmdArgs, " "))
}
output, err := exec.Command(cmdArgs[0], cmdArgs[1:]...).Output()
if err != nil {
return "", err
}
return strings.TrimSpace(string(output)), nil
}