/** * Returns true if VP uninstallation should remove the Git repo from the root folder (and back it * up somewhere). This is true if the first commit is VersionPress commit. Otherwise, the Git repo * was probably created by the user before VP was installed and we should keep the repo untouched. * * @return bool */ public static function uninstallationShouldRemoveGitRepo() { global $versionPressContainer; /** @var GitRepository $repository */ $repository = $versionPressContainer->resolve(VersionPressServices::REPOSITORY); $initialCommit = $repository->getInitialCommit(); return $initialCommit && ChangeInfoMatcher::matchesChangeInfo($initialCommit->getMessage(), 'VersionPress\\ChangeInfos\\VersionPressChangeInfo'); }
public function getChangeDescription() { global $versionPressContainer; // temporary solution todo: find better way to pass the dependency /** @var GitRepository $repository */ $repository = $versionPressContainer->resolve(VersionPressServices::REPOSITORY); $revertedCommit = $repository->getCommit($this->commitHash); if ($this->action === self::ACTION_UNDO) { $revertedChangeInfo = ChangeInfoMatcher::buildChangeInfo($revertedCommit->getMessage()); return sprintf("Reverted change \"%s\"", $revertedChangeInfo->getChangeDescription()); } return sprintf("Rollback to the same state as of %s", $revertedCommit->getDate()->format('d-M-y H:i:s')); }
/** * @param WP_REST_Request $request * @return WP_REST_Response|\WP_Error */ public function getCommits(WP_REST_Request $request) { $gitLogPaginator = new GitLogPaginator($this->gitRepository); $gitLogPaginator->setCommitsPerPage(25); $page = intval($request['page']); $commits = $gitLogPaginator->getPage($page); if (empty($commits)) { return new \WP_Error('notice', 'No more commits to show.', array('status' => 403)); } $preActivationHash = trim(file_get_contents(VERSIONPRESS_ACTIVATION_FILE)); if (empty($preActivationHash)) { $initialCommitHash = $this->gitRepository->getInitialCommit()->getHash(); } else { $initialCommitHash = $this->gitRepository->getChildCommit($preActivationHash); } $isChildOfInitialCommit = $this->gitRepository->wasCreatedAfter($commits[0]->getHash(), $initialCommitHash); $isFirstCommit = $page === 0; $result = array(); foreach ($commits as $commit) { $isChildOfInitialCommit = $isChildOfInitialCommit && $commit->getHash() !== $initialCommitHash; $canUndoCommit = $isChildOfInitialCommit && !$commit->isMerge(); $canRollbackToThisCommit = !$isFirstCommit && ($isChildOfInitialCommit || $commit->getHash() === $initialCommitHash); $changeInfo = ChangeInfoMatcher::buildChangeInfo($commit->getMessage()); $isEnabled = $isChildOfInitialCommit || $canRollbackToThisCommit || $commit->getHash() === $initialCommitHash; $fileChanges = $this->getFileChanges($commit); $changeInfoList = $changeInfo instanceof ChangeInfoEnvelope ? $changeInfo->getChangeInfoList() : array(); $result[] = array("hash" => $commit->getHash(), "date" => $commit->getDate()->format('c'), "message" => $changeInfo->getChangeDescription(), "canUndo" => $canUndoCommit, "canRollback" => $canRollbackToThisCommit, "isEnabled" => $isEnabled, "isInitial" => $commit->getHash() === $initialCommitHash, "isMerge" => $commit->isMerge(), "changes" => array_merge($this->convertChangeInfoList($changeInfoList), $fileChanges)); $isFirstCommit = false; } return new WP_REST_Response(array('pages' => $gitLogPaginator->getPrettySteps($page), 'commits' => $result)); }
use VersionPress\Git\GitRepository; use VersionPress\Git\Reverter; use VersionPress\DI\VersionPressServices; use VersionPress\ChangeInfos\ChangeInfoMatcher; if (!in_array($_GET['method'], array('undo', 'rollback'))) { exit; } global $versionPressContainer; /** @var GitRepository $repository */ $repository = $versionPressContainer->resolve(VersionPressServices::REPOSITORY); /** @var Reverter $reverter */ $reverter = $versionPressContainer->resolve(VersionPressServices::REVERTER); $canRevert = $reverter->canRevert(); $commit = $repository->getCommit($_GET['commit']); $changeInfo = ChangeInfoMatcher::buildChangeInfo($commit->getMessage()); $method = $_GET['method']; $title = $method == 'undo' ? "<div class='title-content'>Undo <em>{$changeInfo->getChangeDescription()}</em> ?</div>" : "<div class='title-content'>Roll back to <em>{$commit->getDate()->format('d-M-y H:i:s')}</em> ?</div>"; $message = "\n <p>\n For EAP releases, please have a backup.\n <a href='http://docs.versionpress.net/en/feature-focus/undo-and-rollback' target='_blank'>\n Learn more about reverts.\n </a>\n </p>"; $errors = !$canRevert ? "\n <p class='undo-warning'>\n <span class='icon icon-warning'></span>\n You have <a href='http://docs.versionpress.net/en/feature-focus/undo-and-rollback#uncommitted-files' target='_blank'>uncommitted changes</a> in your WordPress directory.<br>\n Please commit them before doing a revert.\n </p>" : ""; $buttonProceed = "<a " . "class='button " . (!$canRevert ? "disabled" : "") . "' " . "id='popover-ok-button' " . "href='" . (!$canRevert ? "javascript:;" : admin_url('admin.php?action=vp_' . $method . '&commit=' . $commit->getHash())) . "'>Proceed</a>"; $buttonCancel = "<a " . "class='button cancel' " . "id='popover-cancel-button' " . "href='" . (isAjax() ? "javascript:;" : menu_page_url('versionpress', false)) . "'>Cancel</a>"; $body = "\n <div>\n {$message}\n {$errors}\n <div class='button-container'>\n {$buttonProceed}\n {$buttonCancel}\n </div>\n </div>\n "; if (isAjax()) { $response = new stdClass(); $response->body = $body; echo json_encode($response); wp_die(); } else { echo "<h3>{$title}</h3>"; echo $body;
/** * Factory method - builds a ChangeInfo object from a commit message. Used when VersionPress * table is constructed; hooks use the normal constructor. * * @param CommitMessage $commitMessage * @return ChangeInfo */ public static function buildFromCommitMessage(CommitMessage $commitMessage) { $fullBody = $commitMessage->getBody(); $splittedBodies = explode("\n\n", $fullBody); $lastBody = $splittedBodies[count($splittedBodies) - 1]; $changeInfoList = array(); $version = null; if (self::containsVersion($lastBody)) { $version = self::extractVersion($lastBody); array_pop($splittedBodies); } foreach ($splittedBodies as $body) { $partialCommitMessage = new CommitMessage("", $body); /** @var ChangeInfo $matchingChangeInfoType */ $matchingChangeInfoType = ChangeInfoMatcher::findMatchingChangeInfo($partialCommitMessage); $changeInfoList[] = $matchingChangeInfoType::buildFromCommitMessage($partialCommitMessage); } return new self($changeInfoList, $version); }
private function checkReferencesForRevertedCommit(Commit $revertedCommit) { $changeInfo = ChangeInfoMatcher::buildChangeInfo($revertedCommit->getMessage()); if ($changeInfo instanceof UntrackedChangeInfo) { return true; } foreach ($changeInfo->getChangeInfoList() as $subChangeInfo) { if ($subChangeInfo instanceof EntityChangeInfo && !$this->checkEntityReferences($subChangeInfo->getEntityName(), $subChangeInfo->getEntityId(), $subChangeInfo->getParentId())) { return false; } } return true; }