diff --git a/services/repository/contributors_graph.go b/services/repository/contributors_graph.go index b91d64e3b7..41c9c4f8ab 100644 --- a/services/repository/contributors_graph.go +++ b/services/repository/contributors_graph.go @@ -153,6 +153,7 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int date := strings.TrimSpace(scanner.Text()) var coAuthors []*api.CommitUser + emailSet := map[string]bool{} for scanner.Scan() { line := scanner.Text() if line == "" { @@ -163,6 +164,10 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int if err != nil { continue } + if _, exists := emailSet[coAuthorEmail]; exists { + continue + } + emailSet[coAuthorEmail] = true coAuthor := &api.CommitUser{ Identity: api.Identity{Name: coAuthorName, Email: coAuthorEmail}, Date: date, diff --git a/services/repository/contributors_graph_test.go b/services/repository/contributors_graph_test.go index 77e412df3e..b2df72fbfc 100644 --- a/services/repository/contributors_graph_test.go +++ b/services/repository/contributors_graph_test.go @@ -172,4 +172,88 @@ func TestRepository_ContributorsGraph(t *testing.T) { }, }, data["total"]) }) + t.Run("generate contributor stats with commit that has duplicate co-authored lines", func(t *testing.T) { + mockCache, err := cache.NewStringCache(setting.Cache{}) + assert.NoError(t, err) + generateContributorStats(nil, mockCache, "key", repo, "branch-with-duplicated-co-author-entries") + var data map[string]*ContributorData + exist, _ := mockCache.GetJSON("key", &data) + assert.True(t, exist) + var keys []string + for k := range data { + keys = append(keys, k) + } + slices.Sort(keys) + assert.EqualValues(t, []string{ + "ethantkoenig@gmail.com", + "fizzbuzz@example.com", + "foobar@example.com", + "jimmy.praet@telenet.be", + "jon@allspice.io", + "total", + }, keys) + + // make sure we can see the author of the commit + assert.EqualValues(t, &ContributorData{ + Name: "Foo Bar", + AvatarLink: "https://secure.gravatar.com/avatar/0d4907cea9d97688aa7a5e722d742f71?d=identicon", + TotalCommits: 1, + Weeks: map[int64]*WeekData{ + 1715472000000: { + Week: 1715472000000, // sunday 2024-05-12 + Additions: 1, + Deletions: 0, + Commits: 1, + }, + }, + }, data["foobar@example.com"]) + + // make sure that we can also see the co-author and that we don't see duplicated additions/deletions/commits + assert.EqualValues(t, &ContributorData{ + Name: "Fizz Buzz", + AvatarLink: "https://secure.gravatar.com/avatar/474e3516254f43b2337011c4ac4de421?d=identicon", + TotalCommits: 1, + Weeks: map[int64]*WeekData{ + 1715472000000: { + Week: 1715472000000, // sunday 2024-05-12 + Additions: 1, + Deletions: 0, + Commits: 1, + }, + }, + }, data["fizzbuzz@example.com"]) + + // let's also make sure we don't duplicate the additions/deletions/commits counts in the overall stats that week + assert.EqualValues(t, &ContributorData{ + Name: "Total", + AvatarLink: "", + TotalCommits: 4, + Weeks: map[int64]*WeekData{ + 1715472000000: { + Week: 1715472000000, // sunday 2024-05-12 + Additions: 1, + Deletions: 0, + Commits: 1, + }, + 1511654400000: { + Week: 1511654400000, // sunday 2017-11-26 + Additions: 3, + Deletions: 0, + Commits: 1, + }, + 1607817600000: { + Week: 1607817600000, // sunday 2020-12-13 + Additions: 10, + Deletions: 0, + Commits: 1, + }, + 1624752000000: { + Week: 1624752000000, // sunday 2021-06-27 + Additions: 2, + Deletions: 0, + Commits: 1, + }, + }, + }, data["total"]) + }) } diff --git a/tests/gitea-repositories-meta/user2/repo2.git/objects/79/a64f10ca2ea21fa2a94102751f0dd9f2c15ce8 b/tests/gitea-repositories-meta/user2/repo2.git/objects/79/a64f10ca2ea21fa2a94102751f0dd9f2c15ce8 new file mode 100644 index 0000000000..ccc9a3fcb2 --- /dev/null +++ b/tests/gitea-repositories-meta/user2/repo2.git/objects/79/a64f10ca2ea21fa2a94102751f0dd9f2c15ce8 @@ -0,0 +1 @@ +x͎J0]) tHO # k7MnbcJȀʅ{7s|RaƻZ)fI#] &n(M$/NIڀ6Z`k}9 1grOLH#9 Amv