@@ -135,31 +135,52 @@ func RefBlame(ctx *context.Context) {
135
135
blameParts = append (blameParts , * blamePart )
136
136
}
137
137
138
+ // PREVIOUS BLAME LINK RESOLVER
139
+ //
140
+ // we look for the SHAs of the blameParts parent commit. so we..
141
+ // 1 resolve the blamePart commit to
142
+ // 2 look up its parent
143
+ // 3 validate that the parent commit holds the current treepath
144
+ // 4 store the parent SHA if successful
145
+ // and as blameParts can reference the same commits multiple
146
+ // times, we cache the work locally
138
147
commitNames := make (map [string ]models.UserCommit )
139
148
previousCommits := make (map [string ]string )
140
149
commits := list .New ()
150
+ commitCache := map [string ]* git.Commit {}
151
+ commitCache [commitID ] = commit
141
152
142
153
for _ , part := range blameParts {
143
154
sha := part .Sha
144
155
if _ , ok := commitNames [sha ]; ok {
145
156
continue
146
157
}
147
158
148
- commit , err := ctx .Repo .GitRepo .GetCommit (sha )
149
- if err != nil {
150
- if git .IsErrNotExist (err ) {
151
- ctx .NotFound ("Repo.GitRepo.GetCommit" , err )
152
- } else {
153
- ctx .ServerError ("Repo.GitRepo.GetCommit" , err )
159
+ commit , ok := commitCache [sha ]
160
+ if ! ok {
161
+ commit , err = ctx .Repo .GitRepo .GetCommit (sha )
162
+ if err != nil {
163
+ if git .IsErrNotExist (err ) {
164
+ ctx .NotFound ("Repo.GitRepo.GetCommit" , err )
165
+ } else {
166
+ ctx .ServerError ("Repo.GitRepo.GetCommit" , err )
167
+ }
168
+ return
154
169
}
155
- return
170
+ commitCache [ sha ] = commit
156
171
}
157
172
158
- // Get previous closest commit sha from the commit
159
- previousCommit , err := commit .Parent (0 )
160
- if err == nil {
161
- // Verify the commit
162
- if haz , _ := commit .HasPreviousCommit (previousCommit .ID ); haz {
173
+ // populate parent
174
+ if commit .ParentCount () > 0 {
175
+ psha := commit .Parents [0 ]
176
+ previousCommit , ok := commitCache [psha .String ()]
177
+ if ! ok {
178
+ previousCommit , _ = commit .Parent (0 )
179
+ if previousCommit != nil {
180
+ commitCache [psha .String ()] = previousCommit
181
+ }
182
+ }
183
+ if previousCommit != nil {
163
184
if haz1 , _ := previousCommit .HasFile (ctx .Repo .TreePath ); haz1 {
164
185
previousCommits [commit .ID .String ()] = previousCommit .ID .String ()
165
186
}
@@ -171,6 +192,7 @@ func RefBlame(ctx *context.Context) {
171
192
commitNames [commit .ID .String ()] = models.UserCommit {}
172
193
}
173
194
195
+ // populate commit email adresses to later look up avatars.
174
196
commits = models .ValidateCommitsWithEmails (commits )
175
197
176
198
for e := commits .Front (); e != nil ; e = e .Next () {
0 commit comments