@@ -10,15 +10,13 @@ import (
1010 "fmt"
1111 "io"
1212 "os"
13- "os/exec"
1413 "regexp"
1514 "strings"
1615 "time"
1716
1817 "code.gitea.io/gitea/models"
1918 "code.gitea.io/gitea/modules/git"
2019 "code.gitea.io/gitea/modules/log"
21- "code.gitea.io/gitea/modules/process"
2220 "code.gitea.io/gitea/modules/setting"
2321 "code.gitea.io/gitea/services/gitdiff"
2422
@@ -51,9 +49,8 @@ func (t *TemporaryUploadRepository) Close() {
5149
5250// Clone the base repository to our path and set branch as the HEAD
5351func (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 ()
5754 if matched , _ := regexp .MatchString (".*Remote branch .* not found in upstream origin.*" , stderr ); matched {
5855 return git.ErrBranchNotExist {
5956 Name : branch ,
@@ -79,11 +76,8 @@ func (t *TemporaryUploadRepository) Clone(branch string) error {
7976
8077// SetDefaultIndex sets the git index to our HEAD
8178func (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 )
8781 }
8882 return nil
8983}
@@ -93,33 +87,16 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro
9387 stdOut := new (bytes.Buffer )
9488 stdErr := new (bytes.Buffer )
9589
96- timeout := 5 * time .Minute
97- ctx , cancel := context .WithTimeout (context .Background (), timeout )
98- defer cancel ()
99-
10090 cmdArgs := []string {"ls-files" , "-z" , "--" }
10191 for _ , arg := range filenames {
10292 if arg != "" {
10393 cmdArgs = append (cmdArgs , arg )
10494 }
10595 }
10696
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 ())
123100 return nil , err
124101 }
125102
@@ -128,7 +105,7 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro
128105 filelist = append (filelist , string (line ))
129106 }
130107
131- return filelist , err
108+ return filelist , nil
132109}
133110
134111// RemoveFilesFromIndex removes the given files from the index
@@ -144,90 +121,50 @@ func (t *TemporaryUploadRepository) RemoveFilesFromIndex(filenames ...string) er
144121 }
145122 }
146123
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 ())
169127 }
170-
171- return err
128+ return nil
172129}
173130
174131// HashObject writes the provided content to the object db and returns its hash
175132func (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 )
195135
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 ())
199139 }
200140
201- return strings .TrimSpace (stdOutBuffer .String ()), nil
141+ return strings .TrimSpace (stdOut .String ()), nil
202142}
203143
204144// AddObjectToIndex adds the provided object hash to the index with the provided mode and path
205145func (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 ()
210148 if matched , _ := regexp .MatchString (".*Invalid path '.*" , stderr ); matched {
211149 return models.ErrFilePathInvalid {
212150 Message : objectPath ,
213151 Path : objectPath ,
214152 }
215153 }
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 )
217156 }
218157 return nil
219158}
220159
221160// WriteTree writes the current index as a tree to the object db and returns its hash
222161func (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 )
227163 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 )
229166 }
230- return strings .TrimSpace (treeHash ), nil
167+ return strings .TrimSpace (stdout ), nil
231168}
232169
233170// GetLastCommit gets the last commit ID SHA of the repo
@@ -240,14 +177,12 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ref string) (string, erro
240177 if ref == "" {
241178 ref = "HEAD"
242179 }
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 )
247181 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 )
249184 }
250- return strings .TrimSpace (treeHash ), nil
185+ return strings .TrimSpace (stdout ), nil
251186}
252187
253188// 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
287222 }
288223 }
289224
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 )
298232 }
299- return strings .TrimSpace (commitHash ), nil
233+ return strings .TrimSpace (stdout . String () ), nil
300234}
301235
302236// Push the provided commitHash to the repository branch by the provided user
303237func (t * TemporaryUploadRepository ) Push (doer * models.User , commitHash string , branch string ) error {
304238 // Because calls hooks we need to pass in the environment
305239 env := models .PushingEnvironment (doer , t .repo )
306240
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 )
313246 }
314247 return nil
315248}
316249
317250// 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 ()
330253 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 )
348283 }
349284
350285 return diff , nil
@@ -358,12 +293,8 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
358293 return nil , err
359294 }
360295
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 )
367298
368299 cmdArgs := []string {"check-attr" , "-z" , attribute }
369300
@@ -379,26 +310,14 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
379310 }
380311 }
381312
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 )
399318 }
400319
401- fields := bytes .Split (stdOut .Bytes (), []byte {'\000' })
320+ fields := bytes .Split (stdout .Bytes (), []byte {'\000' })
402321
403322 if len (fields )% 3 != 1 {
404323 return nil , fmt .Errorf ("Wrong number of fields in return from check-attr" )
0 commit comments