/** * Retrives all the branches from the current git repository, * and parses their commit messages. * * @return array a list of BranchInfo objects, one per branch. */ public static function loadAll(ArcanistGitAPI $api) { $branches_raw = $api->getAllBranches(); $branches = array(); foreach ($branches_raw as $branch_raw) { $branch_info = new BranchInfo($branch_raw['name']); $branch_info->setSha1($branch_raw['sha1']); if ($branch_raw['current']) { $branch_info->setCurrent(); } $branches[] = $branch_info; } $name_sha1_map = mpull($branches, 'getSha1', 'getName'); $commits_list = $api->multigetCommitMessages(array_unique(array_values($name_sha1_map)), "%ct%n%an%n%s%n%b"); foreach ($branches as $branch) { $sha1 = $name_sha1_map[$branch->getName()]; $branch->setSha1($sha1); $branch->parseCommitMessage($commits_list[$sha1]); } $branches = msort($branches, 'getCommitTime'); return $branches; }
public function run() { $working_copy = $this->getWorkingCopy(); if (!$working_copy->getProjectID()) { throw new ArcanistUsageException("You have installed a git pre-receive hook in a remote without an " . ".arcconfig."); } // Git repositories have special rules in pre-receive hooks. We need to // construct the API against the .git directory instead of the project // root or commands don't work properly. $repository_api = ArcanistGitAPI::newHookAPI($_SERVER['PWD']); $root = $working_copy->getProjectRoot(); $parser = new ArcanistDiffParser(); $mark_revisions = array(); $stdin = file_get_contents('php://stdin'); $commits = array_filter(explode("\n", $stdin)); foreach ($commits as $commit) { list($old_ref, $new_ref, $refname) = explode(' ', $commit); list($log) = execx('(cd %s && git log -n1 %s)', $repository_api->getPath(), $new_ref); $message_log = reset($parser->parseDiff($log)); $message = ArcanistDifferentialCommitMessage::newFromRawCorpus($message_log->getMetadata('message')); $revision_id = $message->getRevisionID(); if ($revision_id) { $mark_revisions[] = $revision_id; } // TODO: Do commit message junk. $info = $repository_api->getPreReceiveHookStatus($old_ref, $new_ref); $paths = ipull($info, 'mask'); $frefs = ipull($info, 'ref'); $data = array(); foreach ($paths as $path => $mask) { list($stdout) = execx('(cd %s && git cat-file blob %s)', $repository_api->getPath(), $frefs[$path]); $data[$path] = $stdout; } // TODO: Do commit content junk. $commit_name = $new_ref; if ($revision_id) { $commit_name = 'D' . $revision_id . ' (' . $commit_name . ')'; } echo "[arc pre-receive] {$commit_name} OK...\n"; } $conduit = $this->getConduit(); $futures = array(); foreach ($mark_revisions as $revision_id) { $futures[] = $conduit->callMethod('differential.close', array('revisionID' => $revision_id)); } Futures($futures)->resolveAll(); return 0; }
/** * Creates and/or cleans a workspace for the requested repo. * * return ArcanistGitAPI */ public static function getCleanGitWorkspace(PhabricatorRepository $repo) { $origin_path = $repo->getLocalPath(); $path = rtrim($origin_path, '/'); $path = $path . '__workspace'; if (!Filesystem::pathExists($path)) { $repo->execxLocalCommand('clone -- file://%s %s', $origin_path, $path); if (!$repo->isHosted()) { id(new ArcanistGitAPI($path))->execxLocal('remote set-url origin %s', $repo->getRemoteURI()); } } $workspace = new ArcanistGitAPI($path); $workspace->execxLocal('clean -f -d'); $workspace->execxLocal('checkout master'); $workspace->execxLocal('fetch'); $workspace->execxLocal('reset --hard origin/master'); $workspace->reloadWorkingCopy(); return $workspace; }