@@ -28,8 +28,8 @@ type PushCommit struct {
2828
2929// PushCommits represents list of commits in a push operation.
3030type PushCommits struct {
31- Len int
3231 Commits []* PushCommit
32+ HeadCommit * PushCommit
3333 CompareURL string
3434
3535 avatars map [string ]string
@@ -44,67 +44,88 @@ func NewPushCommits() *PushCommits {
4444 }
4545}
4646
47- // ToAPIPayloadCommits converts a PushCommits object to
48- // api.PayloadCommit format.
49- func (pc * PushCommits ) ToAPIPayloadCommits (repoPath , repoLink string ) ([]* api.PayloadCommit , error ) {
50- commits := make ([]* api.PayloadCommit , len (pc .Commits ))
51-
52- if pc .emailUsers == nil {
53- pc .emailUsers = make (map [string ]* models.User )
54- }
47+ // toAPIPayloadCommit converts a single PushCommit to an api.PayloadCommit object.
48+ func (pc * PushCommits ) toAPIPayloadCommit (repoPath , repoLink string , commit * PushCommit ) (* api.PayloadCommit , error ) {
5549 var err error
56- for i , commit := range pc .Commits {
57- authorUsername := ""
58- author , ok := pc .emailUsers [commit .AuthorEmail ]
59- if ! ok {
60- author , err = models .GetUserByEmail (commit .AuthorEmail )
61- if err == nil {
62- authorUsername = author .Name
63- pc .emailUsers [commit .AuthorEmail ] = author
64- }
65- } else {
50+ authorUsername := ""
51+ author , ok := pc .emailUsers [commit .AuthorEmail ]
52+ if ! ok {
53+ author , err = models .GetUserByEmail (commit .AuthorEmail )
54+ if err == nil {
6655 authorUsername = author .Name
56+ pc .emailUsers [commit .AuthorEmail ] = author
6757 }
58+ } else {
59+ authorUsername = author .Name
60+ }
6861
69- committerUsername := ""
70- committer , ok := pc .emailUsers [commit .CommitterEmail ]
71- if ! ok {
72- committer , err = models .GetUserByEmail (commit .CommitterEmail )
73- if err == nil {
74- // TODO: check errors other than email not found.
75- committerUsername = committer .Name
76- pc .emailUsers [commit .CommitterEmail ] = committer
77- }
78- } else {
62+ committerUsername := ""
63+ committer , ok := pc .emailUsers [commit .CommitterEmail ]
64+ if ! ok {
65+ committer , err = models .GetUserByEmail (commit .CommitterEmail )
66+ if err == nil {
67+ // TODO: check errors other than email not found.
7968 committerUsername = committer .Name
69+ pc .emailUsers [commit .CommitterEmail ] = committer
8070 }
71+ } else {
72+ committerUsername = committer .Name
73+ }
8174
82- fileStatus , err := git .GetCommitFileStatus (repoPath , commit .Sha1 )
75+ fileStatus , err := git .GetCommitFileStatus (repoPath , commit .Sha1 )
76+ if err != nil {
77+ return nil , fmt .Errorf ("FileStatus [commit_sha1: %s]: %v" , commit .Sha1 , err )
78+ }
79+
80+ return & api.PayloadCommit {
81+ ID : commit .Sha1 ,
82+ Message : commit .Message ,
83+ URL : fmt .Sprintf ("%s/commit/%s" , repoLink , commit .Sha1 ),
84+ Author : & api.PayloadUser {
85+ Name : commit .AuthorName ,
86+ Email : commit .AuthorEmail ,
87+ UserName : authorUsername ,
88+ },
89+ Committer : & api.PayloadUser {
90+ Name : commit .CommitterName ,
91+ Email : commit .CommitterEmail ,
92+ UserName : committerUsername ,
93+ },
94+ Added : fileStatus .Added ,
95+ Removed : fileStatus .Removed ,
96+ Modified : fileStatus .Modified ,
97+ Timestamp : commit .Timestamp ,
98+ }, nil
99+ }
100+
101+ // ToAPIPayloadCommits converts a PushCommits object to api.PayloadCommit format.
102+ // It returns all converted commits and, if provided, the head commit or an error otherwise.
103+ func (pc * PushCommits ) ToAPIPayloadCommits (repoPath , repoLink string ) ([]* api.PayloadCommit , * api.PayloadCommit , error ) {
104+ commits := make ([]* api.PayloadCommit , len (pc .Commits ))
105+ var headCommit * api.PayloadCommit
106+
107+ if pc .emailUsers == nil {
108+ pc .emailUsers = make (map [string ]* models.User )
109+ }
110+ for i , commit := range pc .Commits {
111+ apiCommit , err := pc .toAPIPayloadCommit (repoPath , repoLink , commit )
83112 if err != nil {
84- return nil , fmt . Errorf ( "FileStatus [commit_sha1: %s]: %v" , commit . Sha1 , err )
113+ return nil , nil , err
85114 }
86115
87- commits [i ] = & api.PayloadCommit {
88- ID : commit .Sha1 ,
89- Message : commit .Message ,
90- URL : fmt .Sprintf ("%s/commit/%s" , repoLink , commit .Sha1 ),
91- Author : & api.PayloadUser {
92- Name : commit .AuthorName ,
93- Email : commit .AuthorEmail ,
94- UserName : authorUsername ,
95- },
96- Committer : & api.PayloadUser {
97- Name : commit .CommitterName ,
98- Email : commit .CommitterEmail ,
99- UserName : committerUsername ,
100- },
101- Added : fileStatus .Added ,
102- Removed : fileStatus .Removed ,
103- Modified : fileStatus .Modified ,
104- Timestamp : commit .Timestamp ,
116+ commits [i ] = apiCommit
117+ if pc .HeadCommit != nil && pc .HeadCommit .Sha1 == commits [i ].ID {
118+ headCommit = apiCommit
105119 }
106120 }
107- return commits , nil
121+ if pc .HeadCommit != nil && headCommit == nil {
122+ var err error
123+ headCommit , err = pc .toAPIPayloadCommit (repoPath , repoLink , pc .HeadCommit )
124+ if err != nil {
125+ return nil , nil , err
126+ }
127+ }
128+ return commits , headCommit , nil
108129}
109130
110131// AvatarLink tries to match user in database with e-mail
@@ -157,13 +178,9 @@ func CommitToPushCommit(commit *git.Commit) *PushCommit {
157178// ListToPushCommits transforms a list.List to PushCommits type.
158179func ListToPushCommits (l * list.List ) * PushCommits {
159180 var commits []* PushCommit
160- var actEmail string
161181 for e := l .Front (); e != nil ; e = e .Next () {
162- commit := e .Value .(* git.Commit )
163- if actEmail == "" {
164- actEmail = commit .Committer .Email
165- }
166- commits = append (commits , CommitToPushCommit (commit ))
182+ commit := CommitToPushCommit (e .Value .(* git.Commit ))
183+ commits = append (commits , commit )
167184 }
168- return & PushCommits {l . Len (), commits , "" , make (map [string ]string ), make (map [string ]* models.User )}
185+ return & PushCommits {commits , nil , "" , make (map [string ]string ), make (map [string ]* models.User )}
169186}
0 commit comments