Skip to content

Commit 5358b71

Browse files
committed
concurrent blaming, skip merge commits
1 parent 1b7b8a8 commit 5358b71

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

cmd/commands/todos.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package commands
22

33
import (
4+
"fmt"
45
"os"
56
"path/filepath"
67
"time"
@@ -10,6 +11,7 @@ import (
1011
"github.com/briandowns/spinner"
1112
"github.com/spf13/cobra"
1213
"gopkg.in/src-d/go-git.v4"
14+
"gopkg.in/src-d/go-git.v4/plumbing/object"
1315
)
1416

1517
func init() {
@@ -54,14 +56,12 @@ var todosCmd = &cobra.Command{
5456
// handleError(err)
5557

5658
t := todos.NewToDos(comments)
57-
err = t.FindBlame(r, commit)
58-
handleError(err)
5959

60-
// for i, todo := range t { // TODO: can we do this concurrently
61-
// todo.FindBlame(r, commit)
62-
// s.Suffix = fmt.Sprintf(" (%d/%d) %s: %s", i, len(t), filepath.Base(todo.FilePath), todo.String)
63-
// // time.Sleep(100 * time.Millisecond)
64-
// }
60+
err = t.FindBlame(r, commit, func(commit *object.Commit, remaining int) {
61+
total := len(t)
62+
s.Suffix = fmt.Sprintf(" (%d/%d) %s: %s", total-remaining, total, commit.Hash, commit.Author.When)
63+
})
64+
handleError(err)
6565

6666
s.Stop()
6767
todos.WriteTodos(t, os.Stdout)

pkg/todos/todos.go

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package todos
33
import (
44
"regexp"
55
"strings"
6+
"sync"
67

78
"github.com/augmentable-dev/tickgit/pkg/comments"
89
"github.com/dustin/go-humanize"
@@ -67,11 +68,12 @@ func (t *ToDo) existsInCommit(commit *object.Commit) (bool, error) {
6768
if err != nil {
6869
return false, err
6970
}
70-
return strings.Contains(c, t.Comment.String()), nil
71+
contains := strings.Contains(c, t.Comment.String())
72+
return contains, nil
7173
}
7274

7375
// FindBlame sets the blame information on each todo in a set of todos
74-
func (t *ToDos) FindBlame(repo *git.Repository, from *object.Commit) error {
76+
func (t *ToDos) FindBlame(repo *git.Repository, from *object.Commit, cb func(*object.Commit, int)) error {
7577
commitIter, err := repo.Log(&git.LogOptions{
7678
From: from.Hash,
7779
})
@@ -86,18 +88,32 @@ func (t *ToDos) FindBlame(repo *git.Repository, from *object.Commit) error {
8688
if len(remainingTodos) == 0 {
8789
return storer.ErrStop
8890
}
91+
if commit.NumParents() > 1 {
92+
return nil
93+
}
8994
newRemainingTodos := make(ToDos, 0)
95+
errs := make(chan error)
96+
var wg sync.WaitGroup
97+
var mux sync.Mutex
9098
for _, todo := range remainingTodos {
91-
exists, err := todo.existsInCommit(commit)
92-
if err != nil {
93-
return err
94-
}
95-
if !exists { // if the todo doesn't exist in this commit, it was added in the previous commit (previous wrt the iterator, more recent in time)
96-
todo.Commit = prevCommit
97-
} else { // if the todo does exist in this commit, add it to the new list of remaining todos
98-
newRemainingTodos = append(newRemainingTodos, todo)
99-
}
99+
wg.Add(1)
100+
go func(todo *ToDo, commit *object.Commit, errs chan error) {
101+
defer wg.Done()
102+
mux.Lock()
103+
exists, err := todo.existsInCommit(commit)
104+
if err != nil {
105+
errs <- err
106+
}
107+
mux.Unlock()
108+
if !exists { // if the todo doesn't exist in this commit, it was added in the previous commit (previous wrt the iterator, more recent in time)
109+
todo.Commit = prevCommit
110+
} else { // if the todo does exist in this commit, add it to the new list of remaining todos
111+
newRemainingTodos = append(newRemainingTodos, todo)
112+
}
113+
}(todo, commit, errs)
100114
}
115+
wg.Wait()
116+
cb(commit, len(newRemainingTodos))
101117
prevCommit = commit
102118
remainingTodos = newRemainingTodos
103119
return nil

0 commit comments

Comments
 (0)