@@ -29,13 +29,46 @@ class Git extends AbstractGit implements VcsInterface
2929{
3030 const PRETTY_FORMAT = '<logentry><commit>%H</commit>%n<date>%aD</date>%n<author>%an</author>%n<msg><![CDATA[%B]]></msg></logentry> ' ;
3131
32+ /**
33+ * @var array remote tags cache
34+ */
35+ private $ tags ;
36+
37+ /**
38+ * @var array remote branches cache
39+ */
40+ private $ branches ;
41+
42+ /** @var bool ensures that we only fetch once */
43+ private $ isFetched = false ;
44+
45+ public function cloneRepository ($ dest = null )
46+ {
47+ $ temporary = $ this ->isTemporary ;
48+
49+ $ realdest = (true === is_null ($ dest ) ? $ this ->cwd : $ dest );
50+ $ branch = $ this ->getHead ()->getName ();
51+
52+ $ result = $ this ->execute ('clone ' , array ('-b ' => (string ) $ branch , $ this ->url , $ realdest ));
53+
54+ $ this ->setCwd ($ realdest );
55+
56+ // the setCwd resets the isTemporary flag, this keeps it correct
57+ $ this ->isTemporary = $ temporary ;
58+
59+ // a clone implies a fetch
60+ $ this ->isFetched = true ;
61+ }
62+
3263 /**
3364 * Perform a clone operation
3465 *
3566 * @param string|null $dest
3667 */
3768 public function checkout ($ dest = null )
3869 {
70+ $ temporary = $ this ->isTemporary ;
71+
3972 if (true === is_null ($ dest )) {
4073 $ realdest = $ this ->cwd ;
4174 } else {
@@ -45,13 +78,15 @@ public function checkout($dest = null)
4578 $ head = $ this ->getHead ();
4679 $ branch = $ head ->getName ();
4780
48- $ result = $ this ->execute ('clone ' , array ('-b ' => (string ) $ branch , $ this ->url , $ realdest ));
81+ if (false === $ this ->hasClone || false === is_null ($ dest )) {
82+ $ this ->cloneRepository ($ dest );
83+ } else {
84+ $ result = $ this ->execute ('checkout ' , array ((string ) $ branch ));
85+ }
4986
50- $ this ->setCwd ( $ realdest ) ;
87+ $ this ->hasCheckout = true ;
5188
52- if (true === is_null ($ dest )) {
53- $ this ->isTemporary = true ;
54- }
89+ $ result = $ this ->pull ();
5590 }
5691
5792 /**
@@ -130,11 +165,23 @@ public function export($path, $dest)
130165 $ head = $ this ->getHead ();
131166 $ branch = $ head ->getName ();
132167
133- $ result = $ this ->execute ('clone ' , array ('-b ' => (string ) $ branch , '--depth=1 ' , $ this ->url , $ dest ));
168+ if (!$ this ->hasCheckout ) {
169+ // if ($this->isTemporary) {
170+ // // create a shallow checkout
171+ // $result = $this->execute('clone', array('-b' => (string) $branch, '--depth=1', $this->url, $dest));
172+ // } else {
173+ // $this->checkout();
174+ // }
175+
176+ $ this ->checkout ();
177+ }
178+
179+ // we already have cloned the repository, use that instead
180+ $ result = $ this ->execute ('clone ' , array ('-b ' => (string ) $ branch , '--depth=1 ' , 'file:// ' . $ this ->cwd , $ dest ), getcwd ());
134181
135182 $ result = $ this ->adapter ->execute ('submodule ' , array ('update ' , '--init ' => true , '--recursive ' => true ), $ dest );
136183
137- $ this ->isTemporary = false ;
184+ // $this->isTemporary = false;
138185
139186 $ filesystem = new Filesystem ();
140187 $ filesystem ->remove ($ dest . '/.git ' );
@@ -184,9 +231,7 @@ public function ls($path)
184231 */
185232 public function log ($ path , $ revision = null , $ limit = null )
186233 {
187- if (!$ this ->hasCheckout ) {
188- $ this ->checkout ();
189- }
234+ $ this ->fetch ();
190235
191236 if ('' === $ path ) {
192237 $ path = '. ' ;
@@ -206,9 +251,7 @@ public function log($path, $revision = null, $limit = null)
206251 */
207252 public function changelog ($ revision1 , $ revision2 )
208253 {
209- if (!$ this ->hasCheckout ) {
210- $ this ->checkout ();
211- }
254+ $ this ->fetch ();
212255
213256 return $ this ->execute ('log ' , array (
214257 '--pretty= ' => self ::PRETTY_FORMAT ,
@@ -245,6 +288,8 @@ public function cat($path)
245288 public function diff ($ oldPath , $ newPath , $ oldRevision = 'HEAD ' ,
246289 $ newRevision = 'HEAD ' , $ summary = true )
247290 {
291+ $ this ->fetch ();
292+
248293 $ arguments = array (
249294 '--name-status ' => $ summary ,
250295 $ oldRevision ,
@@ -267,17 +312,21 @@ public function diff($oldPath, $newPath, $oldRevision = 'HEAD',
267312 */
268313 public function branches ()
269314 {
270- $ retval = $ this ->execute ('ls-remote ' , array ('--heads ' => true , $ this ->getUrl ()));
315+ if (null === $ this ->branches ) {
316+ $ retval = $ this ->execute ('ls-remote ' , array ('--heads ' => true , $ this ->getUrl ()));
317+
318+ $ list = explode ("\n" , rtrim ($ retval ));
271319
272- $ list = explode ("\n" , rtrim ($ retval ));
320+ $ branches = array ();
321+ foreach ($ list as $ line ) {
322+ list ($ hash , $ ref ) = explode ("\t" , $ line );
323+ $ branches [] = new Reference (basename ($ ref ), Reference::BRANCH , $ hash );
324+ }
273325
274- $ branches = array ();
275- foreach ($ list as $ line ) {
276- list ($ hash , $ ref ) = explode ("\t" , $ line );
277- $ branches [] = new Reference (basename ($ ref ), Reference::BRANCH , $ hash );
326+ $ this ->branches = $ branches ;
278327 }
279328
280- return $ branches ;
329+ return $ this -> branches ;
281330 }
282331
283332 /**
@@ -286,29 +335,33 @@ public function branches()
286335 */
287336 public function tags ()
288337 {
289- $ retval = $ this ->execute ('ls-remote ' , array ('--tags ' => true , $ this ->getUrl ()));
338+ if (null === $ this ->tags ) {
339+ $ retval = $ this ->execute ('ls-remote ' , array ('--tags ' => true , $ this ->getUrl ()));
290340
291- if ('' === $ retval ) {
292- return array ();
293- }
341+ if ('' === $ retval ) {
342+ return $ this ->tags = array ();
343+ }
344+
345+ $ list = explode ("\n" , rtrim ($ retval ));
294346
295- $ list = explode ("\n" , rtrim ($ retval ));
347+ $ tags = array ();
348+ foreach ($ list as $ line ) {
349+ list ($ hash , $ ref ) = explode ("\t" , $ line );
350+ $ tags [] = new Reference (basename ($ ref ), Reference::TAG , $ hash );
351+ }
296352
297- $ tags = array ();
298- foreach ($ list as $ line ) {
299- list ($ hash , $ ref ) = explode ("\t" , $ line );
300- $ tags [] = new Reference (basename ($ ref ), Reference::TAG , $ hash );
353+ $ this ->tags = $ tags ;
301354 }
302355
303- return $ tags ;
356+ return $ this -> tags ;
304357 }
305358
306359 /**
307360 * Git push
308361 *
309362 * @param string $remote
310363 * @throws \RuntimeException
311- * @return string
364+ * @return null| string
312365 */
313366 public function push ($ remote = 'origin ' )
314367 {
@@ -322,6 +375,8 @@ public function push($remote = 'origin')
322375 // ignore output on stderr: it contains
323376 // progress information, for example about hooks
324377 }
378+
379+ return null ;
325380 }
326381
327382 /**
@@ -341,11 +396,41 @@ public function pull($remote = 'origin')
341396 }
342397
343398 /**
344- * (non-PHPdoc)
345- * @see Webcreate\Vcs.VcsInterface::revisionCompare()
399+ * Git fetch
400+ *
401+ * @param string $remote
402+ * @throws \RuntimeException
403+ * @return bool
404+ */
405+ public function fetch ($ remote = null )
406+ {
407+ if ($ this ->isFetched ) {
408+ return false ;
409+ }
410+
411+ if (!$ this ->hasClone ) {
412+ $ this ->cloneRepository ();
413+ }
414+
415+ $ args = array ();
416+ if (null !== $ remote ) {
417+ $ args [] = $ remote ;
418+ }
419+
420+ $ this ->execute ('fetch ' , $ args );
421+
422+ $ this ->isFetched = true ;
423+
424+ return true ;
425+ }
426+
427+ /**
428+ * {@inheritdoc}
346429 */
347430 public function revisionCompare ($ revision1 , $ revision2 )
348431 {
432+ $ this ->fetch ();
433+
349434 if ($ revision1 == $ revision2 ) {
350435 return 0 ;
351436 } else {
0 commit comments