-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
'Hidden' refs, such as 'refs/pull/1004/head' may cause confusion if reported upon. GitHub, for example, will display a banner saying that the commit doesn't belong to the repository. This parse the output of 'git log --source' and converts it to a human-readable format, IF the ref is 'hidden'.
- Loading branch information
Showing
12 changed files
with
627 additions
and
488 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,7 +108,9 @@ func (d *Diff) finalize() error { return d.contentWriter.CloseForWriting() } | |
|
||
// Commit contains commit header info and diffs. | ||
type Commit struct { | ||
Hash string | ||
Hash string | ||
// The source of a commit, if it doesn't exist in the repository's history. | ||
Source string | ||
Author string | ||
Committer string | ||
Date time.Time | ||
|
@@ -231,19 +233,23 @@ func (c *Parser) RepoPath( | |
) (chan *Diff, error) { | ||
args := []string{ | ||
"-C", source, | ||
"--no-replace-objects", | ||
"log", | ||
"--patch", // https://git-scm.com/docs/git-log#Documentation/git-log.txt---patch | ||
"--full-history", | ||
"--date=format:%a %b %d %H:%M:%S %Y %z", | ||
"--pretty=fuller", // https://git-scm.com/docs/git-log#_pretty_formats | ||
"--notes", // https://git-scm.com/docs/git-log#Documentation/git-log.txt---notesltrefgt | ||
"--source", // https://git-scm.com/docs/git-log#Documentation/git-log.txt---source | ||
} | ||
if abbreviatedLog { | ||
// https://git-scm.com/docs/git-log#Documentation/git-log.txt---diff-filterACDMRTUXB82308203 | ||
args = append(args, "--diff-filter=AM") | ||
} | ||
if head != "" { | ||
args = append(args, head) | ||
} else { | ||
// https://git-scm.com/docs/git-log#Documentation/git-log.txt---all | ||
args = append(args, "--all") | ||
} | ||
for _, glob := range excludedGlobs { | ||
|
@@ -332,10 +338,9 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, diffChan chan | |
outReader := bufio.NewReader(stdOut) | ||
var ( | ||
currentCommit *Commit | ||
|
||
totalLogSize int | ||
totalLogSize int | ||
latestState = Initial | ||
) | ||
var latestState = Initial | ||
|
||
diff := func(c *Commit, opts ...diffOption) *Diff { | ||
opts = append(opts, withCustomContentWriter(bufferwriter.New())) | ||
|
@@ -395,10 +400,18 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, diffChan chan | |
// Create a new currentDiff and currentCommit | ||
currentCommit = &Commit{Message: strings.Builder{}} | ||
currentDiff = diff(currentCommit) | ||
// Check that the commit line contains a hash and set it. | ||
if len(line) >= 47 { | ||
currentCommit.Hash = string(line[7:47]) | ||
|
||
hash, ref := parseCommitLine(line) | ||
if hash == nil || ref == nil { | ||
ctx.Logger().Error( | ||
fmt.Errorf(`expected line to match 'commit <hash> <ref>', got "%s"`, line), | ||
"Failed to parse CommitLine") | ||
latestState = ParseFailure | ||
continue | ||
} | ||
|
||
currentCommit.Hash = string(hash) | ||
currentCommit.Source = parseSourceRef(ref) | ||
case isMergeLine(isStaged, latestState, line): | ||
latestState = MergeLine | ||
case isAuthorLine(isStaged, latestState, line): | ||
|
@@ -614,6 +627,47 @@ func isCommitLine(isStaged bool, latestState ParseState, line []byte) bool { | |
return false | ||
} | ||
|
||
func parseCommitLine(line []byte) (hash []byte, ref []byte) { | ||
// Check that the commit line contains a 40-character hash and set it. | ||
// `commit e5575cd6f2d21d3a1a604287c7bf4a7eab2266e0\n` | ||
if len(line) >= 47 { | ||
hash = line[7:47] | ||
} | ||
|
||
// Check if the commit line includes branch references. | ||
// `commit 2dbbb28727c7c2954438666dafba57bb8c714d3b refs/heads/fix/github-enterprise-gist\n` | ||
if len(line) > 48 { | ||
ref = line[48 : len(line)-1] | ||
} | ||
|
||
return | ||
} | ||
|
||
// ParseCommitSource s | ||
// https://git-scm.com/docs/git-log#Documentation/git-log.txt---source | ||
func parseSourceRef(ref []byte) string { | ||
// We don't care about 'normal' refs. | ||
if bytes.HasPrefix(ref, []byte("refs/heads/")) || bytes.HasPrefix(ref, []byte("refs/tags/")) { | ||
return "" | ||
} | ||
|
||
// Handle GitHub pull requests. | ||
// e.g., `refs/pull/238/head` or `refs/pull/1234/merge` | ||
if after, ok := bytes.CutPrefix(ref, []byte("refs/pull/")); ok { | ||
prNumber := after[:bytes.Index(after, []byte("/"))] | ||
return "Pull request #" + string(prNumber) | ||
} | ||
|
||
// Handle GitLab merge requests | ||
// e.g., `refs/merge-requests/238/head` or `refs/merge-requests/1234/merge` | ||
if after, ok := bytes.CutPrefix(ref, []byte("refs/merge-requests/")); ok { | ||
mrNumber := after[:bytes.Index(after, []byte("/"))] | ||
return "Merge request #" + string(mrNumber) | ||
} | ||
|
||
return fmt.Sprintf("%s (hidden ref)", string(ref)) | ||
} | ||
|
||
// Author: Bill Rich <[email protected]> | ||
func isAuthorLine(isStaged bool, latestState ParseState, line []byte) bool { | ||
if isStaged || !(latestState == CommitLine || latestState == MergeLine) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.