1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 03:50:54 +01:00

In the "Version Information" panel, try to include branchpoints

Summary:
Fixes T12040. In T12039, a user running local patches followed the report instructions as far as grabbing version information, but didn't update or revert their local changes or try against a clean install before reporting.

This obviously isn't ideal for us, but it's understandable (grabbing version information is much easier than upgrading/reverting), and we can do better about making this information useful: when compiling version information, try to figure out the branchpoint from a known upstream `master` branch by listing remotes, then running `git merge-base` against them.

Additionally, explicitly document that we want upstream hashes. We have to have a fallback case in this document anyway (for when you can't get to Config) so hopefully this makes it more likely that we get useful information in initial reports.

Test Plan: {F2229574}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12040

Differential Revision: https://secure.phabricator.com/D17103
This commit is contained in:
epriestley 2016-12-23 07:16:03 -08:00
parent 5bdc7dd07b
commit 065d865bce
2 changed files with 157 additions and 7 deletions

View file

@ -39,8 +39,20 @@ final class PhabricatorConfigVersionController
$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'));
@ -67,16 +79,109 @@ final class PhabricatorConfigVersionController
$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);
@ -84,7 +189,29 @@ final class PhabricatorConfigVersionController
} 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;

View file

@ -49,6 +49,29 @@ 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
==========