@@ -11,8 +11,7 @@ import (
11
11
"os"
12
12
13
13
"code.gitea.io/gitea/modules/log"
14
- "code.gitea.io/gitea/modules/temp"
15
- "code.gitea.io/gitea/modules/util"
14
+ "code.gitea.io/gitea/modules/setting"
16
15
)
17
16
18
17
// BlamePart represents block of blame - continuous lines with one sha
@@ -30,12 +29,13 @@ type BlameReader struct {
30
29
bufferedReader * bufio.Reader
31
30
done chan error
32
31
lastSha * string
33
- ignoreRevsFile * string
32
+ ignoreRevsFile string
34
33
objectFormat ObjectFormat
34
+ cleanupFuncs []func ()
35
35
}
36
36
37
37
func (r * BlameReader ) UsesIgnoreRevs () bool {
38
- return r .ignoreRevsFile != nil
38
+ return r .ignoreRevsFile != ""
39
39
}
40
40
41
41
// NextPart returns next part of blame (sequential code lines with the same commit)
@@ -123,36 +123,37 @@ func (r *BlameReader) Close() error {
123
123
r .bufferedReader = nil
124
124
_ = r .reader .Close ()
125
125
_ = r .output .Close ()
126
- if r .ignoreRevsFile != nil {
127
- _ = util .Remove (* r .ignoreRevsFile )
126
+ for _ , cleanup := range r .cleanupFuncs {
127
+ if cleanup != nil {
128
+ cleanup ()
129
+ }
128
130
}
129
131
return err
130
132
}
131
133
132
134
// CreateBlameReader creates reader for given repository, commit and file
133
135
func CreateBlameReader (ctx context.Context , objectFormat ObjectFormat , repoPath string , commit * Commit , file string , bypassBlameIgnore bool ) (* BlameReader , error ) {
134
- var ignoreRevsFile * string
135
- if DefaultFeatures (). CheckVersionAtLeast ( "2.23" ) && ! bypassBlameIgnore {
136
- ignoreRevsFile = tryCreateBlameIgnoreRevsFile ( commit )
136
+ reader , stdout , err := os . Pipe ()
137
+ if err != nil {
138
+ return nil , err
137
139
}
138
140
139
141
cmd := NewCommandNoGlobals ("blame" , "--porcelain" )
140
- if ignoreRevsFile != nil {
141
- // Possible improvement: use --ignore-revs-file /dev/stdin on unix
142
- // There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
143
- cmd .AddOptionValues ("--ignore-revs-file" , * ignoreRevsFile )
144
- }
145
- cmd .AddDynamicArguments (commit .ID .String ()).AddDashesAndList (file )
146
- reader , stdout , err := os .Pipe ()
147
- if err != nil {
148
- if ignoreRevsFile != nil {
149
- _ = util .Remove (* ignoreRevsFile )
142
+
143
+ var ignoreRevsFileName string
144
+ var ignoreRevsFileCleanup func () // TODO: maybe it should check the returned err in a defer func to make sure the cleanup could always be executed correctly
145
+ if DefaultFeatures ().CheckVersionAtLeast ("2.23" ) && ! bypassBlameIgnore {
146
+ ignoreRevsFileName , ignoreRevsFileCleanup = tryCreateBlameIgnoreRevsFile (commit )
147
+ if ignoreRevsFileName != "" {
148
+ // Possible improvement: use --ignore-revs-file /dev/stdin on unix
149
+ // There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
150
+ cmd .AddOptionValues ("--ignore-revs-file" , ignoreRevsFileName )
150
151
}
151
- return nil , err
152
152
}
153
153
154
- done := make ( chan error , 1 )
154
+ cmd . AddDynamicArguments ( commit . ID . String ()). AddDashesAndList ( file )
155
155
156
+ done := make (chan error , 1 )
156
157
go func () {
157
158
stderr := bytes.Buffer {}
158
159
// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close"
@@ -170,40 +171,44 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
170
171
}()
171
172
172
173
bufferedReader := bufio .NewReader (reader )
173
-
174
174
return & BlameReader {
175
175
output : stdout ,
176
176
reader : reader ,
177
177
bufferedReader : bufferedReader ,
178
178
done : done ,
179
- ignoreRevsFile : ignoreRevsFile ,
179
+ ignoreRevsFile : ignoreRevsFileName ,
180
180
objectFormat : objectFormat ,
181
+ cleanupFuncs : []func (){ignoreRevsFileCleanup },
181
182
}, nil
182
183
}
183
184
184
- func tryCreateBlameIgnoreRevsFile (commit * Commit ) * string {
185
+ func tryCreateBlameIgnoreRevsFile (commit * Commit ) ( string , func ()) {
185
186
entry , err := commit .GetTreeEntryByPath (".git-blame-ignore-revs" )
186
187
if err != nil {
187
- return nil
188
+ log .Error ("Unable to get .git-blame-ignore-revs file: GetTreeEntryByPath: %v" , err )
189
+ return "" , nil
188
190
}
189
191
190
192
r , err := entry .Blob ().DataAsync ()
191
193
if err != nil {
192
- return nil
194
+ log .Error ("Unable to get .git-blame-ignore-revs file data: DataAsync: %v" , err )
195
+ return "" , nil
193
196
}
194
197
defer r .Close ()
195
198
196
- f , err := temp . CreateTemp ( "gitea_git -blame-ignore-revs" )
199
+ f , cleanup , err := setting . AppDataTempDir ( "git-repo-content" ). CreateTempFileRandom ( "git -blame-ignore-revs" )
197
200
if err != nil {
198
- return nil
201
+ log .Error ("Unable to get .git-blame-ignore-revs file data: CreateTempFileRandom: %v" , err )
202
+ return "" , nil
199
203
}
200
-
204
+ filename := f . Name ()
201
205
_ , err = io .Copy (f , r )
202
206
_ = f .Close ()
203
207
if err != nil {
204
- _ = util .Remove (f .Name ())
205
- return nil
208
+ cleanup ()
209
+ log .Error ("Unable to get .git-blame-ignore-revs file data: Copy: %v" , err )
210
+ return "" , nil
206
211
}
207
212
208
- return util . ToPointer ( f . Name ())
213
+ return filename , cleanup
209
214
}
0 commit comments