@@ -10,15 +10,13 @@ import (
10
10
"fmt"
11
11
"io"
12
12
"os"
13
- "os/exec"
14
13
"regexp"
15
14
"strings"
16
15
"time"
17
16
18
17
"code.gitea.io/gitea/models"
19
18
"code.gitea.io/gitea/modules/git"
20
19
"code.gitea.io/gitea/modules/log"
21
- "code.gitea.io/gitea/modules/process"
22
20
"code.gitea.io/gitea/modules/setting"
23
21
"code.gitea.io/gitea/services/gitdiff"
24
22
@@ -51,9 +49,8 @@ func (t *TemporaryUploadRepository) Close() {
51
49
52
50
// Clone the base repository to our path and set branch as the HEAD
53
51
func (t * TemporaryUploadRepository ) Clone (branch string ) error {
54
- if _ , stderr , err := process .GetManager ().ExecTimeout (5 * time .Minute ,
55
- fmt .Sprintf ("Clone (git clone -s --bare): %s" , t .basePath ),
56
- git .GitExecutable , "clone" , "-s" , "--bare" , "-b" , branch , t .repo .RepoPath (), t .basePath ); err != nil {
52
+ if _ , err := git .NewCommand ("clone" , "-s" , "--bare" , "-b" , branch , t .repo .RepoPath (), t .basePath ).Run (); err != nil {
53
+ stderr := err .Error ()
57
54
if matched , _ := regexp .MatchString (".*Remote branch .* not found in upstream origin.*" , stderr ); matched {
58
55
return git.ErrBranchNotExist {
59
56
Name : branch ,
@@ -79,11 +76,8 @@ func (t *TemporaryUploadRepository) Clone(branch string) error {
79
76
80
77
// SetDefaultIndex sets the git index to our HEAD
81
78
func (t * TemporaryUploadRepository ) SetDefaultIndex () error {
82
- if _ , stderr , err := process .GetManager ().ExecDir (5 * time .Minute ,
83
- t .basePath ,
84
- fmt .Sprintf ("SetDefaultIndex (git read-tree HEAD): %s" , t .basePath ),
85
- git .GitExecutable , "read-tree" , "HEAD" ); err != nil {
86
- return fmt .Errorf ("SetDefaultIndex: %v %s" , err , stderr )
79
+ if _ , err := git .NewCommand ("read-tree" , "HEAD" ).RunInDir (t .basePath ); err != nil {
80
+ return fmt .Errorf ("SetDefaultIndex: %v" , err )
87
81
}
88
82
return nil
89
83
}
@@ -93,33 +87,16 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro
93
87
stdOut := new (bytes.Buffer )
94
88
stdErr := new (bytes.Buffer )
95
89
96
- timeout := 5 * time .Minute
97
- ctx , cancel := context .WithTimeout (context .Background (), timeout )
98
- defer cancel ()
99
-
100
90
cmdArgs := []string {"ls-files" , "-z" , "--" }
101
91
for _ , arg := range filenames {
102
92
if arg != "" {
103
93
cmdArgs = append (cmdArgs , arg )
104
94
}
105
95
}
106
96
107
- cmd := exec .CommandContext (ctx , git .GitExecutable , cmdArgs ... )
108
- desc := fmt .Sprintf ("lsFiles: (git ls-files) %v" , cmdArgs )
109
- cmd .Dir = t .basePath
110
- cmd .Stdout = stdOut
111
- cmd .Stderr = stdErr
112
-
113
- if err := cmd .Start (); err != nil {
114
- return nil , fmt .Errorf ("exec(%s) failed: %v(%v)" , desc , err , ctx .Err ())
115
- }
116
-
117
- pid := process .GetManager ().Add (desc , cmd )
118
- err := cmd .Wait ()
119
- process .GetManager ().Remove (pid )
120
-
121
- if err != nil {
122
- err = fmt .Errorf ("exec(%d:%s) failed: %v(%v) stdout: %v stderr: %v" , pid , desc , err , ctx .Err (), stdOut , stdErr )
97
+ if err := git .NewCommand (cmdArgs ... ).RunInDirPipeline (t .basePath , stdOut , stdErr ); err != nil {
98
+ log .Error ("Unable to run git ls-files for temporary repo: %s (%s) Error: %v\n stdout: %s\n stderr: %s" , t .repo .FullName (), t .basePath , err , stdOut .String (), stdErr .String ())
99
+ err = fmt .Errorf ("Unable to run git ls-files for temporary repo of: %s Error: %v\n stdout: %s\n stderr: %s" , t .repo .FullName (), err , stdOut .String (), stdErr .String ())
123
100
return nil , err
124
101
}
125
102
@@ -128,7 +105,7 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro
128
105
filelist = append (filelist , string (line ))
129
106
}
130
107
131
- return filelist , err
108
+ return filelist , nil
132
109
}
133
110
134
111
// RemoveFilesFromIndex removes the given files from the index
@@ -144,90 +121,50 @@ func (t *TemporaryUploadRepository) RemoveFilesFromIndex(filenames ...string) er
144
121
}
145
122
}
146
123
147
- timeout := 5 * time .Minute
148
- ctx , cancel := context .WithTimeout (context .Background (), timeout )
149
- defer cancel ()
150
-
151
- cmdArgs := []string {"update-index" , "--remove" , "-z" , "--index-info" }
152
- cmd := exec .CommandContext (ctx , git .GitExecutable , cmdArgs ... )
153
- desc := fmt .Sprintf ("removeFilesFromIndex: (git update-index) %v" , filenames )
154
- cmd .Dir = t .basePath
155
- cmd .Stdout = stdOut
156
- cmd .Stderr = stdErr
157
- cmd .Stdin = bytes .NewReader (stdIn .Bytes ())
158
-
159
- if err := cmd .Start (); err != nil {
160
- return fmt .Errorf ("exec(%s) failed: %v(%v)" , desc , err , ctx .Err ())
161
- }
162
-
163
- pid := process .GetManager ().Add (desc , cmd )
164
- err := cmd .Wait ()
165
- process .GetManager ().Remove (pid )
166
-
167
- if err != nil {
168
- err = fmt .Errorf ("exec(%d:%s) failed: %v(%v) stdout: %v stderr: %v" , pid , desc , err , ctx .Err (), stdOut , stdErr )
124
+ if err := git .NewCommand ("update-index" , "--remove" , "-z" , "--index-info" ).RunInDirFullPipeline (t .basePath , stdOut , stdErr , stdIn ); err != nil {
125
+ log .Error ("Unable to update-index for temporary repo: %s (%s) Error: %v\n stdout: %s\n stderr: %s" , t .repo .FullName (), t .basePath , err , stdOut .String (), stdErr .String ())
126
+ return fmt .Errorf ("Unable to update-index for temporary repo: %s Error: %v\n stdout: %s\n stderr: %s" , t .repo .FullName (), err , stdOut .String (), stdErr .String ())
169
127
}
170
-
171
- return err
128
+ return nil
172
129
}
173
130
174
131
// HashObject writes the provided content to the object db and returns its hash
175
132
func (t * TemporaryUploadRepository ) HashObject (content io.Reader ) (string , error ) {
176
- timeout := 5 * time .Minute
177
- ctx , cancel := context .WithTimeout (context .Background (), timeout )
178
- defer cancel ()
179
-
180
- hashCmd := exec .CommandContext (ctx , git .GitExecutable , "hash-object" , "-w" , "--stdin" )
181
- hashCmd .Dir = t .basePath
182
- hashCmd .Stdin = content
183
- stdOutBuffer := new (bytes.Buffer )
184
- stdErrBuffer := new (bytes.Buffer )
185
- hashCmd .Stdout = stdOutBuffer
186
- hashCmd .Stderr = stdErrBuffer
187
- desc := fmt .Sprintf ("hashObject: (git hash-object)" )
188
- if err := hashCmd .Start (); err != nil {
189
- return "" , fmt .Errorf ("git hash-object: %s" , err )
190
- }
191
-
192
- pid := process .GetManager ().Add (desc , hashCmd )
193
- err := hashCmd .Wait ()
194
- process .GetManager ().Remove (pid )
133
+ stdOut := new (bytes.Buffer )
134
+ stdErr := new (bytes.Buffer )
195
135
196
- if err != nil {
197
- err = fmt . Errorf ( "exec(%d:%s) failed : %v(%v) stdout : %v stderr : %v " , pid , desc , err , ctx . Err (), stdOutBuffer , stdErrBuffer )
198
- return "" , err
136
+ if err := git . NewCommand ( "hash-object" , "-w" , "--stdin" ). RunInDirFullPipeline ( t . basePath , stdOut , stdErr , content ); err != nil {
137
+ log . Error ( "Unable to hash-object to temporary repo : %s (%s) Error : %v\n stdout: %s \n stderr : %s " , t . repo . FullName (), t . basePath , err , stdOut . String (), stdErr . String () )
138
+ return "" , fmt . Errorf ( "Unable to hash-object to temporary repo: %s Error: %v \n stdout: %s \n stderr: %s" , t . repo . FullName (), err , stdOut . String (), stdErr . String ())
199
139
}
200
140
201
- return strings .TrimSpace (stdOutBuffer .String ()), nil
141
+ return strings .TrimSpace (stdOut .String ()), nil
202
142
}
203
143
204
144
// AddObjectToIndex adds the provided object hash to the index with the provided mode and path
205
145
func (t * TemporaryUploadRepository ) AddObjectToIndex (mode , objectHash , objectPath string ) error {
206
- if _ , stderr , err := process .GetManager ().ExecDir (5 * time .Minute ,
207
- t .basePath ,
208
- fmt .Sprintf ("addObjectToIndex (git update-index): %s" , t .basePath ),
209
- git .GitExecutable , "update-index" , "--add" , "--replace" , "--cacheinfo" , mode , objectHash , objectPath ); err != nil {
146
+ if _ , err := git .NewCommand ("update-index" , "--add" , "--replace" , "--cacheinfo" , mode , objectHash , objectPath ).RunInDir (t .basePath ); err != nil {
147
+ stderr := err .Error ()
210
148
if matched , _ := regexp .MatchString (".*Invalid path '.*" , stderr ); matched {
211
149
return models.ErrFilePathInvalid {
212
150
Message : objectPath ,
213
151
Path : objectPath ,
214
152
}
215
153
}
216
- return fmt .Errorf ("git update-index: %s" , stderr )
154
+ log .Error ("Unable to add object to index: %s %s %s in temporary repo %s(%s) Error: %v" , mode , objectHash , objectPath , t .repo .FullName (), t .basePath , err )
155
+ return fmt .Errorf ("Unable to add object to index at %s in temporary repo %s Error: %v" , objectPath , t .repo .FullName (), err )
217
156
}
218
157
return nil
219
158
}
220
159
221
160
// WriteTree writes the current index as a tree to the object db and returns its hash
222
161
func (t * TemporaryUploadRepository ) WriteTree () (string , error ) {
223
- treeHash , stderr , err := process .GetManager ().ExecDir (5 * time .Minute ,
224
- t .basePath ,
225
- fmt .Sprintf ("WriteTree (git write-tree): %s" , t .basePath ),
226
- git .GitExecutable , "write-tree" )
162
+ stdout , err := git .NewCommand ("write-tree" ).RunInDir (t .basePath )
227
163
if err != nil {
228
- return "" , fmt .Errorf ("git write-tree: %s" , stderr )
164
+ log .Error ("Unable to write tree in temporary repo: %s(%s): Error: %v" , t .repo .FullName (), t .basePath , err )
165
+ return "" , fmt .Errorf ("Unable to write-tree in temporary repo for: %s Error: %v" , t .repo .FullName (), err )
229
166
}
230
- return strings .TrimSpace (treeHash ), nil
167
+ return strings .TrimSpace (stdout ), nil
231
168
}
232
169
233
170
// GetLastCommit gets the last commit ID SHA of the repo
@@ -240,14 +177,12 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ref string) (string, erro
240
177
if ref == "" {
241
178
ref = "HEAD"
242
179
}
243
- treeHash , stderr , err := process .GetManager ().ExecDir (5 * time .Minute ,
244
- t .basePath ,
245
- fmt .Sprintf ("GetLastCommit (git rev-parse %s): %s" , ref , t .basePath ),
246
- git .GitExecutable , "rev-parse" , ref )
180
+ stdout , err := git .NewCommand ("rev-parse" , ref ).RunInDir (t .basePath )
247
181
if err != nil {
248
- return "" , fmt .Errorf ("git rev-parse %s: %s" , ref , stderr )
182
+ log .Error ("Unable to get last ref for %s in temporary repo: %s(%s): Error: %v" , ref , t .repo .FullName (), t .basePath , err )
183
+ return "" , fmt .Errorf ("Unable to rev-parse %s in temporary repo for: %s Error: %v" , ref , t .repo .FullName (), err )
249
184
}
250
- return strings .TrimSpace (treeHash ), nil
185
+ return strings .TrimSpace (stdout ), nil
251
186
}
252
187
253
188
// CommitTree creates a commit from a given tree for the user with provided message
@@ -287,64 +222,64 @@ func (t *TemporaryUploadRepository) CommitTree(author, committer *models.User, t
287
222
}
288
223
}
289
224
290
- commitHash , stderr , err := process .GetManager ().ExecDirEnvStdIn (5 * time .Minute ,
291
- t .basePath ,
292
- fmt .Sprintf ("commitTree (git commit-tree): %s" , t .basePath ),
293
- env ,
294
- messageBytes ,
295
- git .GitExecutable , args ... )
296
- if err != nil {
297
- return "" , fmt .Errorf ("git commit-tree: %s" , stderr )
225
+ stdout := new (bytes.Buffer )
226
+ stderr := new (bytes.Buffer )
227
+ if err := git .NewCommand (args ... ).RunInDirTimeoutEnvFullPipeline (env , - 1 , t .basePath , stdout , stderr , messageBytes ); err != nil {
228
+ log .Error ("Unable to commit-tree in temporary repo: %s (%s) Error: %v\n Stdout: %s\n Stderr: %s" ,
229
+ t .repo .FullName (), t .basePath , err , stdout , stderr )
230
+ return "" , fmt .Errorf ("Unable to commit-tree in temporary repo: %s Error: %v\n Stdout: %s\n Stderr: %s" ,
231
+ t .repo .FullName (), err , stdout , stderr )
298
232
}
299
- return strings .TrimSpace (commitHash ), nil
233
+ return strings .TrimSpace (stdout . String () ), nil
300
234
}
301
235
302
236
// Push the provided commitHash to the repository branch by the provided user
303
237
func (t * TemporaryUploadRepository ) Push (doer * models.User , commitHash string , branch string ) error {
304
238
// Because calls hooks we need to pass in the environment
305
239
env := models .PushingEnvironment (doer , t .repo )
306
240
307
- if _ , stderr , err := process .GetManager ().ExecDirEnv (5 * time .Minute ,
308
- t .basePath ,
309
- fmt .Sprintf ("actuallyPush (git push): %s" , t .basePath ),
310
- env ,
311
- git .GitExecutable , "push" , t .repo .RepoPath (), strings .TrimSpace (commitHash )+ ":refs/heads/" + strings .TrimSpace (branch )); err != nil {
312
- return fmt .Errorf ("git push: %s" , stderr )
241
+ if _ , err := git .NewCommand ("push" , t .repo .RepoPath (), strings .TrimSpace (commitHash )+ ":refs/heads/" + strings .TrimSpace (branch )).RunInDirWithEnv (t .basePath , env ); err != nil {
242
+ log .Error ("Unable to push back to repo from temporary repo: %s (%s) Error: %v" ,
243
+ t .repo .FullName (), t .basePath , err )
244
+ return fmt .Errorf ("Unable to push back to repo from temporary repo: %s (%s) Error: %v" ,
245
+ t .repo .FullName (), t .basePath , err )
313
246
}
314
247
return nil
315
248
}
316
249
317
250
// DiffIndex returns a Diff of the current index to the head
318
- func (t * TemporaryUploadRepository ) DiffIndex () (diff * gitdiff.Diff , err error ) {
319
- timeout := 5 * time .Minute
320
- ctx , cancel := context .WithTimeout (context .Background (), timeout )
321
- defer cancel ()
322
-
323
- stdErr := new (bytes.Buffer )
324
-
325
- cmd := exec .CommandContext (ctx , git .GitExecutable , "diff-index" , "--cached" , "-p" , "HEAD" )
326
- cmd .Dir = t .basePath
327
- cmd .Stderr = stdErr
328
-
329
- stdout , err := cmd .StdoutPipe ()
251
+ func (t * TemporaryUploadRepository ) DiffIndex () (* gitdiff.Diff , error ) {
252
+ stdoutReader , stdoutWriter , err := os .Pipe ()
330
253
if err != nil {
331
- return nil , fmt .Errorf ("StdoutPipe: %v stderr %s" , err , stdErr .String ())
332
- }
333
-
334
- if err = cmd .Start (); err != nil {
335
- return nil , fmt .Errorf ("Start: %v stderr %s" , err , stdErr .String ())
336
- }
337
-
338
- pid := process .GetManager ().Add (fmt .Sprintf ("diffIndex [repo_path: %s]" , t .repo .RepoPath ()), cmd )
339
- defer process .GetManager ().Remove (pid )
340
-
341
- diff , err = gitdiff .ParsePatch (setting .Git .MaxGitDiffLines , setting .Git .MaxGitDiffLineCharacters , setting .Git .MaxGitDiffFiles , stdout )
342
- if err != nil {
343
- return nil , fmt .Errorf ("ParsePatch: %v" , err )
344
- }
345
-
346
- if err = cmd .Wait (); err != nil {
347
- return nil , fmt .Errorf ("Wait: %v" , err )
254
+ log .Error ("Unable to open stdout pipe: %v" , err )
255
+ return nil , fmt .Errorf ("Unable to open stdout pipe: %v" , err )
256
+ }
257
+ defer func () {
258
+ _ = stdoutReader .Close ()
259
+ _ = stdoutWriter .Close ()
260
+ }()
261
+ stderr := new (bytes.Buffer )
262
+ var diff * gitdiff.Diff
263
+ var finalErr error
264
+
265
+ if err := git .NewCommand ("diff-index" , "--cached" , "-p" , "HEAD" ).
266
+ RunInDirTimeoutEnvFullPipelineFunc (nil , 30 * time .Second , t .basePath , stdoutWriter , stderr , nil , func (ctx context.Context , cancel context.CancelFunc ) {
267
+ _ = stdoutWriter .Close ()
268
+ diff , finalErr = gitdiff .ParsePatch (setting .Git .MaxGitDiffLines , setting .Git .MaxGitDiffLineCharacters , setting .Git .MaxGitDiffFiles , stdoutReader )
269
+ if finalErr != nil {
270
+ log .Error ("ParsePatch: %v" , finalErr )
271
+ cancel ()
272
+ }
273
+ _ = stdoutReader .Close ()
274
+ }); err != nil {
275
+ if finalErr != nil {
276
+ log .Error ("Unable to ParsePatch in temporary repo %s (%s). Error: %v" , t .repo .FullName (), t .basePath , finalErr )
277
+ return nil , finalErr
278
+ }
279
+ log .Error ("Unable to run diff-index pipeline in temporary repo %s (%s). Error: %v\n Stderr: %s" ,
280
+ t .repo .FullName (), t .basePath , err , stderr )
281
+ return nil , fmt .Errorf ("Unable to run diff-index pipeline in temporary repo %s. Error: %v\n Stderr: %s" ,
282
+ t .repo .FullName (), err , stderr )
348
283
}
349
284
350
285
return diff , nil
@@ -358,12 +293,8 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
358
293
return nil , err
359
294
}
360
295
361
- stdOut := new (bytes.Buffer )
362
- stdErr := new (bytes.Buffer )
363
-
364
- timeout := 5 * time .Minute
365
- ctx , cancel := context .WithTimeout (context .Background (), timeout )
366
- defer cancel ()
296
+ stdout := new (bytes.Buffer )
297
+ stderr := new (bytes.Buffer )
367
298
368
299
cmdArgs := []string {"check-attr" , "-z" , attribute }
369
300
@@ -379,26 +310,14 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
379
310
}
380
311
}
381
312
382
- cmd := exec .CommandContext (ctx , git .GitExecutable , cmdArgs ... )
383
- desc := fmt .Sprintf ("checkAttr: (git check-attr) %s %v" , attribute , cmdArgs )
384
- cmd .Dir = t .basePath
385
- cmd .Stdout = stdOut
386
- cmd .Stderr = stdErr
387
-
388
- if err := cmd .Start (); err != nil {
389
- return nil , fmt .Errorf ("exec(%s) failed: %v(%v)" , desc , err , ctx .Err ())
390
- }
391
-
392
- pid := process .GetManager ().Add (desc , cmd )
393
- err = cmd .Wait ()
394
- process .GetManager ().Remove (pid )
395
-
396
- if err != nil {
397
- err = fmt .Errorf ("exec(%d:%s) failed: %v(%v) stdout: %v stderr: %v" , pid , desc , err , ctx .Err (), stdOut , stdErr )
398
- return nil , err
313
+ if err := git .NewCommand (cmdArgs ... ).RunInDirPipeline (t .basePath , stdout , stderr ); err != nil {
314
+ log .Error ("Unable to check-attr in temporary repo: %s (%s) Error: %v\n Stdout: %s\n Stderr: %s" ,
315
+ t .repo .FullName (), t .basePath , err , stdout , stderr )
316
+ return nil , fmt .Errorf ("Unable to check-attr in temporary repo: %s Error: %v\n Stdout: %s\n Stderr: %s" ,
317
+ t .repo .FullName (), err , stdout , stderr )
399
318
}
400
319
401
- fields := bytes .Split (stdOut .Bytes (), []byte {'\000' })
320
+ fields := bytes .Split (stdout .Bytes (), []byte {'\000' })
402
321
403
322
if len (fields )% 3 != 1 {
404
323
return nil , fmt .Errorf ("Wrong number of fields in return from check-attr" )
0 commit comments