Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/config/controller/PhabricatorConfigVersionController.php b/src/applications/config/controller/PhabricatorConfigVersionController.php
index 15877ddbd7..8f43192b3b 100644
--- a/src/applications/config/controller/PhabricatorConfigVersionController.php
+++ b/src/applications/config/controller/PhabricatorConfigVersionController.php
@@ -1,93 +1,220 @@
<?php
final class PhabricatorConfigVersionController
extends PhabricatorConfigController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$title = pht('Version Information');
$crumbs = $this
->buildApplicationCrumbs()
->addTextCrumb($title)
->setBorder(true);
$versions = $this->renderModuleStatus($viewer);
$nav = $this->buildSideNavView();
$nav->selectFilter('version/');
$header = id(new PHUIHeaderView())
->setHeader($title)
->setProfileHeader(true);
$content = id(new PhabricatorConfigPageView())
->setHeader($header)
->setContent($versions);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setNavigation($nav)
->appendChild($content)
->addClass('white-background');
}
public function renderModuleStatus($viewer) {
$versions = $this->loadVersions($viewer);
$version_property_list = id(new PHUIPropertyListView());
- foreach ($versions as $name => $version) {
- $version_property_list->addProperty($name, $version);
+ foreach ($versions as $name => $info) {
+ $version = $info['version'];
+
+ if ($info['branchpoint']) {
+ $display = pht(
+ '%s (branched from %s on %s)',
+ $version,
+ $info['branchpoint'],
+ $info['upstream']);
+ } else {
+ $display = $version;
+ }
+
+ $version_property_list->addProperty($name, $display);
}
$phabricator_root = dirname(phutil_get_library_root('phabricator'));
$version_path = $phabricator_root.'/conf/local/VERSION';
if (Filesystem::pathExists($version_path)) {
$version_from_file = Filesystem::readFile($version_path);
$version_property_list->addProperty(
pht('Local Version'),
$version_from_file);
}
return $version_property_list;
}
private function loadVersions(PhabricatorUser $viewer) {
$specs = array(
'phabricator',
'arcanist',
'phutil',
);
$all_libraries = PhutilBootloader::getInstance()->getAllLibraries();
// This puts the core libraries at the top:
$other_libraries = array_diff($all_libraries, $specs);
$specs = array_merge($specs, $other_libraries);
- $futures = array();
+ $log_futures = array();
+ $remote_futures = array();
+
foreach ($specs as $lib) {
$root = dirname(phutil_get_library_root($lib));
- $futures[$lib] =
- id(new ExecFuture('git log --format=%s -n 1 --', '%H %ct'))
+
+ $log_command = csprintf(
+ 'git log --format=%s -n 1 --',
+ '%H %ct');
+
+ $remote_command = csprintf(
+ 'git remote -v');
+
+ $log_futures[$lib] = id(new ExecFuture('%C', $log_command))
+ ->setCWD($root);
+
+ $remote_futures[$lib] = id(new ExecFuture('%C', $remote_command))
->setCWD($root);
}
+ $all_futures = array_merge($log_futures, $remote_futures);
+
+ id(new FutureIterator($all_futures))
+ ->resolveAll();
+
+ // A repository may have a bunch of remotes, but we're only going to look
+ // for remotes we host to try to figure out where this repository branched.
+ $upstream_pattern = '(github\.com/phacility/|secure\.phabricator\.com/)';
+
+ $upstream_futures = array();
+ $lib_upstreams = array();
+ foreach ($specs as $lib) {
+ $remote_future = $remote_futures[$lib];
+
+ list($err, $stdout) = $remote_future->resolve();
+ if ($err) {
+ // If this fails for whatever reason, just move on.
+ continue;
+ }
+
+ // These look like this, with a tab separating the first two fields:
+ // remote-name http://remote.uri/ (push)
+
+ $upstreams = array();
+
+ $remotes = phutil_split_lines($stdout, false);
+ foreach ($remotes as $remote) {
+ $remote_pattern = '/^([^\t]+)\t([^ ]+) \(([^)]+)\)\z/';
+ $matches = null;
+ if (!preg_match($remote_pattern, $remote, $matches)) {
+ continue;
+ }
+
+ // Remote URIs are either "push" or "fetch": we only care about "fetch"
+ // URIs.
+ $type = $matches[3];
+ if ($type != 'fetch') {
+ continue;
+ }
+
+ $uri = $matches[2];
+ $is_upstream = preg_match($upstream_pattern, $uri);
+ if (!$is_upstream) {
+ continue;
+ }
+
+ $name = $matches[1];
+ $upstreams[$name] = $name;
+ }
+
+ // If we have several suitable upstreams, try to pick the one named
+ // "origin", if it exists. Otherwise, just pick the first one.
+ if (isset($upstreams['origin'])) {
+ $upstream = $upstreams['origin'];
+ } else if ($upstreams) {
+ $upstream = head($upstreams);
+ } else {
+ $upstream = null;
+ }
+
+ if (!$upstream) {
+ continue;
+ }
+
+ $lib_upstreams[$lib] = $upstream;
+
+ $merge_base_command = csprintf(
+ 'git merge-base HEAD %s/master --',
+ $upstream);
+
+ $root = dirname(phutil_get_library_root($lib));
+
+ $upstream_futures[$lib] = id(new ExecFuture('%C', $merge_base_command))
+ ->setCWD($root);
+ }
+
+ if ($upstream_futures) {
+ id(new FutureIterator($upstream_futures))
+ ->resolveAll();
+ }
+
$results = array();
- foreach ($futures as $key => $future) {
+ foreach ($log_futures as $lib => $future) {
list($err, $stdout) = $future->resolve();
if (!$err) {
list($hash, $epoch) = explode(' ', $stdout);
$version = pht('%s (%s)', $hash, phabricator_date($epoch, $viewer));
} else {
$version = pht('Unknown');
}
- $results[$key] = $version;
+
+ $result = array(
+ 'version' => $version,
+ 'upstream' => null,
+ 'branchpoint' => null,
+ );
+
+ $upstream_future = idx($upstream_futures, $lib);
+ if ($upstream_future) {
+ list($err, $stdout) = $upstream_future->resolve();
+ if (!$err) {
+ $branchpoint = trim($stdout);
+ if (strlen($branchpoint)) {
+ // We only list a branchpoint if it differs from HEAD.
+ if ($branchpoint != $hash) {
+ $result['upstream'] = $lib_upstreams[$lib];
+ $result['branchpoint'] = trim($stdout);
+ }
+ }
+ }
+ }
+
+ $results[$lib] = $result;
}
return $results;
}
}
diff --git a/src/docs/contributor/version.diviner b/src/docs/contributor/version.diviner
index 81b1c845ef..a13c12d86f 100644
--- a/src/docs/contributor/version.diviner
+++ b/src/docs/contributor/version.diviner
@@ -1,57 +1,80 @@
@title Providing Version Information
@group detail
How to provide version information with reports made to the upstream.
Overview
========
When you submit a bug report, we require that you include version information.
Despite our insistence that users update before reporting issues, many reports
we receive describe issues which have already been resolved. Including version
information in your report allows us to quickly determine that you are out of
date and that updating will fix your issue.
That said, your report must also include reproduction steps, and you should be
unable to generate valid reproduction steps for an issue which has already been
resolved because valid reproduction steps must also reproduce against a clean,
up-to-date install. See @{article:Providing Reproduction Steps} for details.
Phabricator Version
===================
To get Phabricator version information:
- Go to the {nav Config} application. You can type "Config" into the global
search box, or navigate to `https://your.install.com/config/`. You must
be an administrator to access this application.
- Click {nav Versions} in the left menu.
- Copy and paste all of the information on the page into your report.
Arcanist Version
================
To get Arcanist version information:
- Run `arc version`.
- Copy and paste all of the output into your report.
Other Versions
==============
In general, we use `git` commit hashes as version identifiers, so you can
identify the version of something by running `git show` and copy/pasting the
hash from the output. This may be useful if you're encountering an issue which
prevents you from reaching the version reporting screen.
+Running a Fork?
+===============
+
+If you've forked Phabricator and have local commits, please make sure you are
+reporting upstream commit hashes, not local commit hashes. The UI will attempt
+to figure out where you branched from, but it may not be able to in all cases.
+
+If you report local commit hashes instead of upstream commit hashes we can not
+go look up the commit hashes to figure out which changes they correspond to, so
+we can not use that information to determine out how old your install is or
+which patches you are missing.
+
+In most cases, you can find the upstream commit you've branched from like this:
+
+```
+$ git merge-base HEAD origin/master
+````
+
+Note that if you report a bug and have local commits, we will almost always ask
+you to reproduce the issue against a clean copy of Phabricator before we
+continue. You can get help faster by doing this //before// reporting an issue.
+
+
Next Steps
==========
Continue by:
- returning to @{article:Contributing Bug Reports}.

File Metadata

Mime Type
text/x-diff
Expires
Wed, Nov 5, 3:32 PM (8 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
321041
Default Alt Text
(9 KB)

Event Timeline