Skip to content

Instantly share code, notes, and snippets.

@kaihendry
Created September 30, 2022 04:59
Show Gist options
  • Save kaihendry/748b57905d35403751be2f4aac6cd40f to your computer and use it in GitHub Desktop.
Save kaihendry/748b57905d35403751be2f4aac6cd40f to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"log"
"sync"
"time"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
)
type Commit struct {
hash string
author string
date time.Time
total int
runningTotal int
}
func main() {
repoPath := "."
flag.Parse()
if flag.Arg(0) != "" {
repoPath = flag.Arg(0)
}
r, err := git.PlainOpen(repoPath)
if err != nil {
log.Fatal(err)
}
ref, err := r.Head()
if err != nil {
log.Fatal(err)
}
// ... retrieves the commit history
cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
if err != nil {
log.Fatal(err)
}
// git rev-list HEAD --count
count := 0
err = cIter.ForEach(func(c *object.Commit) error {
count++
return nil
})
if err != nil {
log.Fatal(err)
}
log.Printf("Total commits: %d", count)
cIter, err = r.Log(&git.LogOptions{From: ref.Hash()})
if err != nil {
log.Fatal(err)
}
commits := make([]Commit, count)
log.Printf("Commits: %d", len(commits))
// LOOK HERE
// WORKS WITH 1 WORKER, FAILS WITH 2 OR MORE
semaphore := make(chan bool, 1)
wg := sync.WaitGroup{}
countIndex := 0
err = cIter.ForEach(func(c *object.Commit) error {
wg.Add(1)
semaphore <- true
go func(c *object.Commit, countIndex int) {
defer func() {
<-semaphore
wg.Done()
}()
fStats, err := c.Stats()
total := 0
if err != nil {
log.Fatal(err)
}
for _, fStat := range fStats {
// log.Println(fStat.Name, fStat.Addition, fStat.Deletion)
total += fStat.Addition - fStat.Deletion
}
commits[countIndex] = Commit{
hash: c.Hash.String()[:7],
author: c.Author.Name,
total: total,
date: c.Author.When,
}
}(c, countIndex)
countIndex++
return nil
})
if err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment