Browse Source

fetch tag,commit form local but not ref

Robert Lu 7 years ago
parent
commit
e768e297cd
2 changed files with 24 additions and 8 deletions
  1. 3 1
      src/Composer/Downloader/GitDownloader.php
  2. 21 7
      src/Composer/Util/Git.php

+ 3 - 1
src/Composer/Downloader/GitDownloader.php

@@ -55,12 +55,14 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
             $this->io->writeError('', true, IOInterface::DEBUG);
             $this->io->writeError(sprintf('    Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
             try {
-                $this->gitUtil->lazySyncMirror($url, $cachePath, $ref);
+                $cached = $this->gitUtil->fetchRef($url, $cachePath, $ref);
                 if (is_dir($cachePath)) {
                     $command =
                         'git clone --no-checkout %cachePath% %path% --dissociate --reference %cachePath% '
                         . '&& cd '.$flag.'%path% '
                         . '&& git remote set-url origin %url% && git remote add composer %url%';
+                    if (!$cached)
+                        $command .= ' && git fetch composer';
                     $msg = "Cloning ".$this->getShortHash($ref).' from cache';
                 }
             } catch (\RuntimeException $e) {

+ 21 - 7
src/Composer/Util/Git.php

@@ -228,20 +228,34 @@ class Git
         return true;
     }
 
-    public function lazySyncMirror($url, $dir, $ref)
+    public function fetchRef($url, $dir, $ref)
     {
         if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
             try {
-                $commandCallable = function ($ref) {
-                    return sprintf('git cat-file -t %s', ProcessExecutor::escape($ref));
-                };
-                $this->runCommand($commandCallable, $ref, $dir);
-                return true;
+                $isTag = $isRef = $actualCommit = false;
+                $escapedRef = ProcessExecutor::escape($ref);
+                $exitCode = $this->process->execute(sprintf('git show-ref --tags %s', $escapedRef), $output, $dir);
+                if (!$exitCode)
+                    $isTag = true;
+                $exitCode = $this->process->execute(sprintf('git show-ref %s', $escapedRef), $output, $dir);
+                if (!$exitCode)
+                    $isRef = true;
+                $exitCode = $this->process->execute(sprintf('git cat-file -t %s', $escapedRef), $output, $dir);
+                if (!$exitCode && trim($output) == "commit")
+                    $actualCommit = true;
+
+                if ($isTag){
+                    return true;
+                }
+                if (!$isRef && $actualCommit) {
+                    return true;
+                }
             } catch (\Exception $e) {
             }
         }
 
-        return $this->syncMirror($url, $dir);
+        $this->syncMirror($url, $dir);
+        return false;
     }
 
     private function isAuthenticationFailure($url, &$match)