public function isMatch(GitRepo $gitRepo) { if (preg_match(';github.com/([^/]+)/([^/]+)/pull/([0-9]+)(|.diff|.patch);', $this->expr, $matches)) { $owner = $matches[1]; $repoName = $matches[2]; $prNum = $matches[3]; foreach ($gitRepo->getRemoteUrls() as $remote => $remoteUrl) { $baseUrl = preg_replace(';\\.git$;', '', $remoteUrl); if ($baseUrl === "https://github.com/{$owner}/{$repoName}") { return TRUE; } if ($baseUrl === "git@github.com:{$owner}/{$repoName}") { return TRUE; } } } elseif ($this->expr[0] == ';') { list(, $regex, $patchFile) = explode(';', $this->expr); foreach ($gitRepo->getRemoteUrls() as $remote => $remoteUrl) { if (preg_match(";{$regex};", $remoteUrl)) { return TRUE; } } return FALSE; } else { throw new \RuntimeException("Failed to recognize auto-merge rule: {$this->expr}"); } }
public function testDiff_multiCase_json() { $this->createExampleRepo($this->fixturePath . '/orig/foo/repo-change-me'); $this->createExampleRepo($this->fixturePath . '/orig/bar/repo-keep-me'); $this->createExampleRepo($this->fixturePath . '/orig/whiz/repo-delete-me'); ProcessUtil::runOk($this->command($this->fixturePath, "cp -r orig changed")); ProcessUtil::runOk($this->command($this->fixturePath, "rm -rf changed/whiz/repo-delete-me")); $this->createExampleRepo($this->fixturePath . '/changed/bang/repo-add-me'); $changeMe = new GitRepo($this->fixturePath . '/changed/foo/repo-change-me'); ProcessUtil::runOk($changeMe->command("git checkout -b feature-branch")); $changeMe->commitFile("new-stuff.txt", "This is a change to the repo!"); $commandTester = $this->createCommandTester(array('command' => 'diff', 'from' => "{$this->fixturePath}/orig", 'to' => "{$this->fixturePath}/changed", '--format' => 'json')); $json = $commandTester->getDisplay(FALSE); $actualDoc = json_decode($json, TRUE); $expectRegexp = array(array('path' => ':^bang/repo-add-me$:', 'status' => '/^\\+$/', 'from' => '/^$/', 'to' => '/^master \\([0-9a-f]+\\)$/', 'changes' => '/^\\(Added repository\\)$/'), array('path' => ':^bar/repo-keep-me$:', 'status' => '/^ $/', 'from' => '/^master \\([0-9a-f]+\\)$/', 'to' => '/^master \\([0-9a-f]+\\)$/', 'changes' => '/^$/'), array('path' => ':^foo/repo-change-me$:', 'status' => '/^M$/', 'from' => '/^master \\([0-9a-f]+\\)$/', 'to' => '/^feature-branch \\([0-9a-f]+\\)$/', 'changes' => '/^1 \\[.*\\]$/'), array('path' => ':^whiz/repo-delete-me$:', 'status' => '/^-$/', 'from' => '/^master \\([0-9a-f]+\\)$/', 'to' => '/^$/', 'changes' => '/^\\(Removed repository\\)$/')); $this->assertEquals(count($actualDoc), count($expectRegexp), "Unexpected number of rows: " . print_r($actualDoc, TRUE)); foreach ($expectRegexp as $offset => $expectRow) { foreach ($expectRow as $key => $pattern) { $this->assertRegExp($pattern, $actualDoc[$offset][$key]); } } }
/** * @param string $checkout the treeish to checkout * @return GitRepo the upstream repo has: * - a master branch * - a new (unmerged) feature branch (my-feature) * - a tag of after the merge of my-feature-1 (0.2) */ protected function createUpstreamRepo($checkout = 'master') { $gitRepo = new GitRepo($this->fixturePath . '/upstream'); if (!$gitRepo->init()) { throw new \RuntimeException("Error: Repo already exists!"); } $gitRepo->commitFile("example.txt", "example text"); ProcessUtil::runOk($gitRepo->command("git tag 0.1")); $gitRepo->commitFile("changelog.txt", "new in v0.2: don't know yet!"); ProcessUtil::runOk($gitRepo->command("git checkout -b my-feature")); $gitRepo->commitFile("example.txt", "example text plus my feature"); // Validate ProcessUtil::runOk($gitRepo->command("git checkout master")); $this->assertEquals("example text", $gitRepo->readFile("example.txt")); ProcessUtil::runOk($gitRepo->command("git checkout my-feature")); $this->assertEquals("example text plus my feature", $gitRepo->readFile("example.txt")); // Wrap up ProcessUtil::runOk($gitRepo->command("git checkout {$checkout}")); return $gitRepo; }
/** * Ensure that we've checked out a branch where we can do merges. * * @param \GitScan\GitRepo $gitRepo */ protected function checkoutAutomergeBranch(InputInterface $input, OutputInterface $output, GitRepo $gitRepo, $repoName) { if ($gitRepo->hasUncommittedChanges(TRUE)) { throw new \RuntimeException("Cannot apply patch"); } $localBranch = $gitRepo->getLocalBranch(); $upstreamBranch = $gitRepo->getUpstreamBranch(); $newLocalBranch = "merge-{$localBranch}-" . date('YmdHis'); $mode = $this->getAutomergeMode($input, $output, $repoName, $localBranch, $upstreamBranch, $newLocalBranch); switch ($mode) { case 'keep': $output->writeln("In \"<info>{$repoName}</info>\", keep the current branch \"<info>{$localBranch}</info>\"."); return; case 'rebuild': $backupBranch = 'backup-' . $localBranch . '-' . date('YmdHis') . '-' . rand(0, 100); $output->writeln("In \"<info>{$repoName}</info>\", rename \"<info>{$localBranch}</info>\" to \"<info>{$backupBranch}</info>\"."); Process::runOk($gitRepo->command("git branch -m {$localBranch} {$backupBranch}")); $output->writeln("In \"<info>{$repoName}</info>\", create \"<info>{$localBranch}</info>\" using \"<info>{$upstreamBranch}</info>\"."); Process::runOk($gitRepo->command("git checkout {$upstreamBranch} -b {$localBranch}")); return; case 'new': $output->writeln("In \"<info>{$repoName}</info>\", create \"<info>{$newLocalBranch}</info>\" using \"<info>{$upstreamBranch}</info>\"."); Process::runOk($gitRepo->command("git checkout {$upstreamBranch} -b {$newLocalBranch}")); return; case 'abort': // Pass through... // Pass through... default: throw new \RuntimeException("Could not decide how to base local branch."); } }
/** * @param \GitScan\GitRepo $gitRepo * @param $name * @return string * Path to the patch file. */ protected function createPatchFile(GitRepo $gitRepo, $name) { $file = $this->fixturePath . '/' . $name . '.patch'; ProcessUtil::runOk($gitRepo->command("git checkout master -b tmp")); $gitRepo->commitFile("changelog.txt", "new in v0.3: the future has been patched!"); ProcessUtil::runOk($gitRepo->command("git format-patch --stdout HEAD~1 > {$file}")); ProcessUtil::runOk($gitRepo->command("git checkout master")); return $file; }