@@ -65,11 +65,8 @@ type Repository struct {
6565}
6666
6767func NewRepository (path string ) (* Repository , error ) {
68- command := exec .Command (
69- "git" , "-C" , path ,
70- "rev-parse" , "--git-dir" ,
71- )
72- out , err := command .Output ()
68+ cmd := exec .Command ("git" , "-C" , path , "rev-parse" , "--git-dir" )
69+ out , err := cmd .Output ()
7370 if err != nil {
7471 switch err := err .(type ) {
7572 case * exec.Error :
@@ -90,13 +87,22 @@ func NewRepository(path string) (*Repository, error) {
9087 return nil , err
9188 }
9289 }
93- gitDir := filepath .Join (path , string (bytes .TrimSpace (out )))
90+ gitDir := string (bytes .TrimSpace (out ))
91+ if ! filepath .IsAbs (gitDir ) {
92+ gitDir = filepath .Join (path , gitDir )
93+ }
9494 repo := & Repository {
9595 path : gitDir ,
9696 }
9797 return repo , nil
9898}
9999
100+ func (repo * Repository ) gitCommand (args ... string ) * exec.Cmd {
101+ cmd := exec .Command ("git" , args ... )
102+ cmd .Env = append (os .Environ (), "GIT_DIR=" + repo .path )
103+ return cmd
104+ }
105+
100106func (repo * Repository ) Path () string {
101107 return repo .path
102108}
@@ -113,7 +119,7 @@ type Reference struct {
113119}
114120
115121type ReferenceIter struct {
116- command * exec.Cmd
122+ cmd * exec.Cmd
117123 out io.ReadCloser
118124 f * bufio.Reader
119125 errChan <- chan error
@@ -122,25 +128,24 @@ type ReferenceIter struct {
122128// NewReferenceIter returns an iterator that iterates over all of the
123129// references in `repo`.
124130func (repo * Repository ) NewReferenceIter () (* ReferenceIter , error ) {
125- command := exec .Command (
126- "git" , "-C" , repo .path ,
131+ cmd := repo .gitCommand (
127132 "for-each-ref" , "--format=%(objectname) %(objecttype) %(objectsize) %(refname)" ,
128133 )
129134
130- out , err := command .StdoutPipe ()
135+ out , err := cmd .StdoutPipe ()
131136 if err != nil {
132137 return nil , err
133138 }
134139
135- command .Stderr = os .Stderr
140+ cmd .Stderr = os .Stderr
136141
137- err = command .Start ()
142+ err = cmd .Start ()
138143 if err != nil {
139144 return nil , err
140145 }
141146
142147 return & ReferenceIter {
143- command : command ,
148+ cmd : cmd ,
144149 out : out ,
145150 f : bufio .NewReader (out ),
146151 errChan : make (chan error , 1 ),
@@ -180,49 +185,46 @@ func (iter *ReferenceIter) Next() (Reference, bool, error) {
180185
181186func (l * ReferenceIter ) Close () error {
182187 err := l .out .Close ()
183- err2 := l .command .Wait ()
188+ err2 := l .cmd .Wait ()
184189 if err == nil {
185190 err = err2
186191 }
187192 return err
188193}
189194
190195type BatchObjectIter struct {
191- command * exec.Cmd
192- out io.ReadCloser
193- f * bufio.Reader
196+ cmd * exec.Cmd
197+ out io.ReadCloser
198+ f * bufio.Reader
194199}
195200
196201// NewBatchObjectIter returns iterates over objects whose names are
197202// fed into its stdin. The output is buffered, so it has to be closed
198203// before you can be sure to read all of the objects.
199204func (repo * Repository ) NewBatchObjectIter () (* BatchObjectIter , io.WriteCloser , error ) {
200- command := exec .Command (
201- "git" , "-C" , repo .path ,
202- "cat-file" , "--batch" , "--buffer" ,
203- )
205+ cmd := repo .gitCommand ("cat-file" , "--batch" , "--buffer" )
204206
205- in , err := command .StdinPipe ()
207+ in , err := cmd .StdinPipe ()
206208 if err != nil {
207209 return nil , nil , err
208210 }
209211
210- out , err := command .StdoutPipe ()
212+ out , err := cmd .StdoutPipe ()
211213 if err != nil {
212214 return nil , nil , err
213215 }
214216
215- command .Stderr = os .Stderr
217+ cmd .Stderr = os .Stderr
216218
217- err = command .Start ()
219+ err = cmd .Start ()
218220 if err != nil {
219221 return nil , nil , err
220222 }
221223
222224 return & BatchObjectIter {
223- command : command ,
224- out : out ,
225- f : bufio .NewReader (out ),
225+ cmd : cmd ,
226+ out : out ,
227+ f : bufio .NewReader (out ),
226228 }, in , nil
227229}
228230
@@ -247,7 +249,7 @@ func (iter *BatchObjectIter) Next() (OID, ObjectType, counts.Count32, []byte, er
247249
248250func (l * BatchObjectIter ) Close () error {
249251 err := l .out .Close ()
250- err2 := l .command .Wait ()
252+ err2 := l .cmd .Wait ()
251253 if err == nil {
252254 err = err2
253255 }
@@ -355,13 +357,13 @@ func parseBatchHeader(spec string, header string) (OID, ObjectType, counts.Count
355357}
356358
357359type ObjectIter struct {
358- command1 * exec.Cmd
359- command2 * exec.Cmd
360- in1 io.Writer
361- out1 io.ReadCloser
362- out2 io.ReadCloser
363- f * bufio.Reader
364- errChan <- chan error
360+ cmd1 * exec.Cmd
361+ cmd2 * exec.Cmd
362+ in1 io.Writer
363+ out1 io.ReadCloser
364+ out2 io.ReadCloser
365+ f * bufio.Reader
366+ errChan <- chan error
365367}
366368
367369// NewObjectIter returns an iterator that iterates over objects in
@@ -371,49 +373,43 @@ type ObjectIter struct {
371373func (repo * Repository ) NewObjectIter (args ... string ) (
372374 * ObjectIter , io.WriteCloser , error ,
373375) {
374- cmdArgs := []string {"-C" , repo .path , "rev-list" , "--objects" }
375- cmdArgs = append (cmdArgs , args ... )
376- command1 := exec .Command ("git" , cmdArgs ... )
377- in1 , err := command1 .StdinPipe ()
376+ cmd1 := repo .gitCommand (append ([]string {"rev-list" , "--objects" }, args ... )... )
377+ in1 , err := cmd1 .StdinPipe ()
378378 if err != nil {
379379 return nil , nil , err
380380 }
381381
382- out1 , err := command1 .StdoutPipe ()
382+ out1 , err := cmd1 .StdoutPipe ()
383383 if err != nil {
384384 return nil , nil , err
385385 }
386386
387- command1 .Stderr = os .Stderr
387+ cmd1 .Stderr = os .Stderr
388388
389- err = command1 .Start ()
389+ err = cmd1 .Start ()
390390 if err != nil {
391391 return nil , nil , err
392392 }
393393
394- command2 := exec .Command (
395- "git" , "-C" , repo .path ,
396- "cat-file" , "--batch-check" , "--buffer" ,
397- )
398-
399- in2 , err := command2 .StdinPipe ()
394+ cmd2 := repo .gitCommand ("cat-file" , "--batch-check" , "--buffer" )
395+ in2 , err := cmd2 .StdinPipe ()
400396 if err != nil {
401397 out1 .Close ()
402- command1 .Wait ()
398+ cmd1 .Wait ()
403399 return nil , nil , err
404400 }
405401
406- out2 , err := command2 .StdoutPipe ()
402+ out2 , err := cmd2 .StdoutPipe ()
407403 if err != nil {
408404 in2 .Close ()
409405 out1 .Close ()
410- command1 .Wait ()
406+ cmd1 .Wait ()
411407 return nil , nil , err
412408 }
413409
414- command2 .Stderr = os .Stderr
410+ cmd2 .Stderr = os .Stderr
415411
416- err = command2 .Start ()
412+ err = cmd2 .Start ()
417413 if err != nil {
418414 return nil , nil , err
419415 }
@@ -444,23 +440,20 @@ func (repo *Repository) NewObjectIter(args ...string) (
444440 }()
445441
446442 return & ObjectIter {
447- command1 : command1 ,
448- command2 : command2 ,
449- out1 : out1 ,
450- out2 : out2 ,
451- f : bufio .NewReader (out2 ),
452- errChan : errChan ,
443+ cmd1 : cmd1 ,
444+ cmd2 : cmd2 ,
445+ out1 : out1 ,
446+ out2 : out2 ,
447+ f : bufio .NewReader (out2 ),
448+ errChan : errChan ,
453449 }, in1 , nil
454450}
455451
456452// CreateObject creates a new Git object, of the specified type, in
457453// `Repository`. `writer` is a function that writes the object in `git
458454// hash-object` input format. This is used for testing only.
459455func (repo * Repository ) CreateObject (t ObjectType , writer func (io.Writer ) error ) (OID , error ) {
460- cmd := exec .Command (
461- "git" , "-C" , repo .path ,
462- "hash-object" , "-w" , "-t" , string (t ), "--stdin" ,
463- )
456+ cmd := repo .gitCommand ("hash-object" , "-w" , "-t" , string (t ), "--stdin" )
464457 in , err := cmd .StdinPipe ()
465458 if err != nil {
466459 return OID {}, err
@@ -505,15 +498,9 @@ func (repo *Repository) UpdateRef(refname string, oid OID) error {
505498 var cmd * exec.Cmd
506499
507500 if oid == NullOID {
508- cmd = exec .Command (
509- "git" , "-C" , repo .path ,
510- "update-ref" , "-d" , refname ,
511- )
501+ cmd = repo .gitCommand ("update-ref" , "-d" , refname )
512502 } else {
513- cmd = exec .Command (
514- "git" , "-C" , repo .path ,
515- "update-ref" , refname , oid .String (),
516- )
503+ cmd = repo .gitCommand ("update-ref" , refname , oid .String ())
517504 }
518505 return cmd .Run ()
519506}
@@ -532,11 +519,11 @@ func (l *ObjectIter) Close() error {
532519 l .out1 .Close ()
533520 err := <- l .errChan
534521 l .out2 .Close ()
535- err2 := l .command1 .Wait ()
522+ err2 := l .cmd1 .Wait ()
536523 if err == nil {
537524 err = err2
538525 }
539- err2 = l .command2 .Wait ()
526+ err2 = l .cmd2 .Wait ()
540527 if err == nil {
541528 err = err2
542529 }
0 commit comments