mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 00:32:41 +01:00
Improve performance of arc branch
in Git with many branches
Summary: This is mostly just a personal quality-of-life fix. I run this command fairly often and having it return a little faster is nice. This replaces a `git show` for each individual branch with a big `git for-each-ref` which we were already running anyway. This is quite a bit faster. This command also occasionally hangs or segfaults for me while executing the huge pile of subprocesses. This is unreliable to reproduce, probably some bug in some PHP extension I have, and likely hard to narrow down, and this approach is better in every way anyway. Test Plan: - Ran `arc branch` in Git, observed faster output (in my `phabricator/`, about 2000ms -> 1200ms). - Ran `arc feature` in Mercurial. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D15735
This commit is contained in:
parent
737f5c0df9
commit
a2ab38df78
2 changed files with 59 additions and 31 deletions
|
@ -966,19 +966,43 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
* @return list<dict<string, string>> Dictionary of branch information.
|
* @return list<dict<string, string>> Dictionary of branch information.
|
||||||
*/
|
*/
|
||||||
public function getAllBranches() {
|
public function getAllBranches() {
|
||||||
list($ref_list) = $this->execxLocal(
|
$field_list = array(
|
||||||
'for-each-ref --format=%s refs/heads',
|
'%(refname)',
|
||||||
'%(refname)');
|
'%(objectname)',
|
||||||
$refs = explode("\n", rtrim($ref_list));
|
'%(committerdate:raw)',
|
||||||
|
'%(tree)',
|
||||||
|
'%(subject)',
|
||||||
|
'%(subject)%0a%0a%(body)',
|
||||||
|
'%02',
|
||||||
|
);
|
||||||
|
|
||||||
|
list($stdout) = $this->execxLocal(
|
||||||
|
'for-each-ref --format=%s -- refs/heads',
|
||||||
|
implode('%01', $field_list));
|
||||||
|
|
||||||
$current = $this->getBranchName();
|
$current = $this->getBranchName();
|
||||||
$result = array();
|
$result = array();
|
||||||
foreach ($refs as $ref) {
|
|
||||||
|
$lines = explode("\2", $stdout);
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$line = trim($line);
|
||||||
|
if (!strlen($line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = explode("\1", $line, 6);
|
||||||
|
list($ref, $hash, $epoch, $tree, $desc, $text) = $fields;
|
||||||
|
|
||||||
$branch = $this->getBranchNameFromRef($ref);
|
$branch = $this->getBranchNameFromRef($ref);
|
||||||
if ($branch) {
|
if ($branch) {
|
||||||
$result[] = array(
|
$result[] = array(
|
||||||
'current' => ($branch === $current),
|
'current' => ($branch === $current),
|
||||||
'name' => $branch,
|
'name' => $branch,
|
||||||
|
'hash' => $hash,
|
||||||
|
'tree' => $tree,
|
||||||
|
'epoch' => (int)$epoch,
|
||||||
|
'desc' => $desc,
|
||||||
|
'text' => $text,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,38 +174,37 @@ EOTEXT
|
||||||
private function loadCommitInfo(array $branches) {
|
private function loadCommitInfo(array $branches) {
|
||||||
$repository_api = $this->getRepositoryAPI();
|
$repository_api = $this->getRepositoryAPI();
|
||||||
|
|
||||||
$futures = array();
|
$branches = ipull($branches, null, 'name');
|
||||||
foreach ($branches as $branch) {
|
|
||||||
if ($repository_api instanceof ArcanistMercurialAPI) {
|
if ($repository_api instanceof ArcanistMercurialAPI) {
|
||||||
|
$futures = array();
|
||||||
|
foreach ($branches as $branch) {
|
||||||
$futures[$branch['name']] = $repository_api->execFutureLocal(
|
$futures[$branch['name']] = $repository_api->execFutureLocal(
|
||||||
'log -l 1 --template %s -r %s',
|
'log -l 1 --template %s -r %s',
|
||||||
"{node}\1{date|hgdate}\1{p1node}\1{desc|firstline}\1{desc}",
|
"{node}\1{date|hgdate}\1{p1node}\1{desc|firstline}\1{desc}",
|
||||||
hgsprintf('%s', $branch['name']));
|
hgsprintf('%s', $branch['name']));
|
||||||
} else {
|
}
|
||||||
// NOTE: "-s" is an option deep in git's diff argument parser that
|
|
||||||
// doesn't seem to have much documentation and has no long form. It
|
$futures = id(new FutureIterator($futures))
|
||||||
// suppresses any diff output.
|
->limit(16);
|
||||||
$futures[$branch['name']] = $repository_api->execFutureLocal(
|
foreach ($futures as $name => $future) {
|
||||||
'show -s --format=%C %s --',
|
list($info) = $future->resolvex();
|
||||||
'%H%x01%ct%x01%T%x01%s%x01%s%n%n%b',
|
|
||||||
$branch['name']);
|
$fields = explode("\1", trim($info), 5);
|
||||||
|
list($hash, $epoch, $tree, $desc, $text) = $fields;
|
||||||
|
|
||||||
|
$branches[$name] += array(
|
||||||
|
'hash' => $hash,
|
||||||
|
'desc' => $desc,
|
||||||
|
'tree' => $tree,
|
||||||
|
'epoch' => (int)$epoch,
|
||||||
|
'text' => $text,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$branches = ipull($branches, null, 'name');
|
foreach ($branches as $name => $branch) {
|
||||||
|
$text = $branch['text'];
|
||||||
$futures = id(new FutureIterator($futures))
|
|
||||||
->limit(16);
|
|
||||||
foreach ($futures as $name => $future) {
|
|
||||||
list($info) = $future->resolvex();
|
|
||||||
list($hash, $epoch, $tree, $desc, $text) = explode("\1", trim($info), 5);
|
|
||||||
|
|
||||||
$branch = $branches[$name] + array(
|
|
||||||
'hash' => $hash,
|
|
||||||
'desc' => $desc,
|
|
||||||
'tree' => $tree,
|
|
||||||
'epoch' => (int)$epoch,
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$message = ArcanistDifferentialCommitMessage::newFromRawCorpus($text);
|
$message = ArcanistDifferentialCommitMessage::newFromRawCorpus($text);
|
||||||
|
@ -332,6 +331,11 @@ EOTEXT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$out) {
|
||||||
|
// All of the revisions are closed or abandoned.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$len_name = max(array_map('strlen', ipull($out, 'name'))) + 2;
|
$len_name = max(array_map('strlen', ipull($out, 'name'))) + 2;
|
||||||
$len_status = max(array_map('strlen', ipull($out, 'status'))) + 2;
|
$len_status = max(array_map('strlen', ipull($out, 'status'))) + 2;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue