@@ -11,8 +11,7 @@ import (
1111 "os"
1212
1313 "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"
1615)
1716
1817// BlamePart represents block of blame - continuous lines with one sha
@@ -30,12 +29,13 @@ type BlameReader struct {
3029 bufferedReader * bufio.Reader
3130 done chan error
3231 lastSha * string
33- ignoreRevsFile * string
32+ ignoreRevsFile string
3433 objectFormat ObjectFormat
34+ cleanupFuncs []func ()
3535}
3636
3737func (r * BlameReader ) UsesIgnoreRevs () bool {
38- return r .ignoreRevsFile != nil
38+ return r .ignoreRevsFile != ""
3939}
4040
4141// NextPart returns next part of blame (sequential code lines with the same commit)
@@ -123,36 +123,37 @@ func (r *BlameReader) Close() error {
123123 r .bufferedReader = nil
124124 _ = r .reader .Close ()
125125 _ = 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+ }
128130 }
129131 return err
130132}
131133
132134// CreateBlameReader creates reader for given repository, commit and file
133135func 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
137139 }
138140
139141 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 )
150151 }
151- return nil , err
152152 }
153153
154- done := make ( chan error , 1 )
154+ cmd . AddDynamicArguments ( commit . ID . String ()). AddDashesAndList ( file )
155155
156+ done := make (chan error , 1 )
156157 go func () {
157158 stderr := bytes.Buffer {}
158159 // 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
170171 }()
171172
172173 bufferedReader := bufio .NewReader (reader )
173-
174174 return & BlameReader {
175175 output : stdout ,
176176 reader : reader ,
177177 bufferedReader : bufferedReader ,
178178 done : done ,
179- ignoreRevsFile : ignoreRevsFile ,
179+ ignoreRevsFile : ignoreRevsFileName ,
180180 objectFormat : objectFormat ,
181+ cleanupFuncs : []func (){ignoreRevsFileCleanup },
181182 }, nil
182183}
183184
184- func tryCreateBlameIgnoreRevsFile (commit * Commit ) * string {
185+ func tryCreateBlameIgnoreRevsFile (commit * Commit ) ( string , func ()) {
185186 entry , err := commit .GetTreeEntryByPath (".git-blame-ignore-revs" )
186187 if err != nil {
187- return nil
188+ log .Error ("Unable to get .git-blame-ignore-revs file: GetTreeEntryByPath: %v" , err )
189+ return "" , nil
188190 }
189191
190192 r , err := entry .Blob ().DataAsync ()
191193 if err != nil {
192- return nil
194+ log .Error ("Unable to get .git-blame-ignore-revs file data: DataAsync: %v" , err )
195+ return "" , nil
193196 }
194197 defer r .Close ()
195198
196- f , err := temp . CreateTemp ( "gitea_git -blame-ignore-revs" )
199+ f , cleanup , err := setting . AppDataTempDir ( "git-repo-content" ). CreateTempFileRandom ( "git -blame-ignore-revs" )
197200 if err != nil {
198- return nil
201+ log .Error ("Unable to get .git-blame-ignore-revs file data: CreateTempFileRandom: %v" , err )
202+ return "" , nil
199203 }
200-
204+ filename := f . Name ()
201205 _ , err = io .Copy (f , r )
202206 _ = f .Close ()
203207 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
206211 }
207212
208- return util . ToPointer ( f . Name ())
213+ return filename , cleanup
209214}
0 commit comments