mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-25 15:00:58 +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:
parent
5bdc7dd07b
commit
065d865bce
2 changed files with 157 additions and 7 deletions
src
|
@ -39,8 +39,20 @@ final class PhabricatorConfigVersionController
|
||||||
$versions = $this->loadVersions($viewer);
|
$versions = $this->loadVersions($viewer);
|
||||||
|
|
||||||
$version_property_list = id(new PHUIPropertyListView());
|
$version_property_list = id(new PHUIPropertyListView());
|
||||||
foreach ($versions as $name => $version) {
|
foreach ($versions as $name => $info) {
|
||||||
$version_property_list->addProperty($name, $version);
|
$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'));
|
$phabricator_root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
@ -67,16 +79,109 @@ final class PhabricatorConfigVersionController
|
||||||
$other_libraries = array_diff($all_libraries, $specs);
|
$other_libraries = array_diff($all_libraries, $specs);
|
||||||
$specs = array_merge($specs, $other_libraries);
|
$specs = array_merge($specs, $other_libraries);
|
||||||
|
|
||||||
$futures = array();
|
$log_futures = array();
|
||||||
|
$remote_futures = array();
|
||||||
|
|
||||||
foreach ($specs as $lib) {
|
foreach ($specs as $lib) {
|
||||||
$root = dirname(phutil_get_library_root($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);
|
->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();
|
$results = array();
|
||||||
foreach ($futures as $key => $future) {
|
foreach ($log_futures as $lib => $future) {
|
||||||
list($err, $stdout) = $future->resolve();
|
list($err, $stdout) = $future->resolve();
|
||||||
if (!$err) {
|
if (!$err) {
|
||||||
list($hash, $epoch) = explode(' ', $stdout);
|
list($hash, $epoch) = explode(' ', $stdout);
|
||||||
|
@ -84,7 +189,29 @@ final class PhabricatorConfigVersionController
|
||||||
} else {
|
} else {
|
||||||
$version = pht('Unknown');
|
$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;
|
return $results;
|
||||||
|
|
|
@ -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.
|
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
|
Next Steps
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue