mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 21:02:41 +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
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
==========
|
||||
|
||||
|
|
Loading…
Reference in a new issue