Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14096726
D13989.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
D13989.diff
View Options
diff --git a/src/repository/api/ArcanistGitAPI.php b/src/repository/api/ArcanistGitAPI.php
--- a/src/repository/api/ArcanistGitAPI.php
+++ b/src/repository/api/ArcanistGitAPI.php
@@ -482,22 +482,37 @@
return $stdout;
}
- public function getBranchName() {
- // TODO: consider:
- //
- // $ git rev-parse --abbrev-ref `git symbolic-ref HEAD`
- //
- // But that may fail if you're not on a branch.
- list($stdout) = $this->execxLocal('branch --no-color');
-
- // Assume that any branch beginning with '(' means 'no branch', or whatever
- // 'no branch' is in the current locale.
- $matches = null;
- if (preg_match('/^\* ([^\(].*)$/m', $stdout, $matches)) {
- return $matches[1];
+ private function getBranchNameFromRef($ref) {
+ $count = 0;
+ $branch = preg_replace('/^refs\/heads\//', '', $ref, 1, $count);
+ if ($count !== 1) {
+ return null;
}
- return null;
+ return $branch;
+ }
+
+ public function getBranchName() {
+ list($err, $stdout, $stderr) = $this->execManualLocal(
+ 'symbolic-ref --quiet HEAD');
+
+ if ($err === 0) {
+ // We expect the branch name to come qualified with a refs/heads/ prefix.
+ // Verify this, and strip it.
+ $ref = rtrim($stdout);
+ $branch = $this->getBranchNameFromRef($ref);
+ if (!$branch) {
+ throw new Exception(
+ pht('Failed to parse %s output!', 'git symbolic-ref'));
+ }
+ return $branch;
+ } else if ($err === 1) {
+ // Exit status 1 with --quiet indicates that HEAD is detached.
+ return null;
+ } else {
+ throw new Exception(
+ pht('Command %s failed: %s', 'git symbolic-ref', $stderr));
+ }
}
public function getRemoteURI() {
@@ -886,24 +901,21 @@
* @return list<dict<string, string>> Dictionary of branch information.
*/
public function getAllBranches() {
- list($branch_info) = $this->execxLocal(
- 'branch --no-color');
- $lines = explode("\n", rtrim($branch_info));
+ list($ref_list) = $this->execxLocal(
+ 'for-each-ref --format=%s refs/heads',
+ '%(refname)');
+ $refs = explode("\n", rtrim($ref_list));
+ $current = $this->getBranchName();
$result = array();
- foreach ($lines as $line) {
-
- if (preg_match('@^[* ]+\(no branch|detached from \w+/\w+\)@', $line)) {
- // This is indicating that the working copy is in a detached state;
- // just ignore it.
- continue;
+ foreach ($refs as $ref) {
+ $branch = $this->getBranchNameFromRef($ref);
+ if ($branch) {
+ $result[] = array(
+ 'current' => ($branch === $current),
+ 'name' => $branch,
+ );
}
-
- list($current, $name) = preg_split('/\s+/', $line, 2);
- $result[] = array(
- 'current' => !empty($current),
- 'name' => $name,
- );
}
return $result;
@@ -1134,11 +1146,28 @@
$commits[] = $merge_base;
$head_branch_count = null;
+ $all_branch_names = ipull($this->getAllBranches(), 'name');
foreach ($commits as $commit) {
+ // Ideally, we would use something like "for-each-ref --contains"
+ // to get a filtered list of branches ready for script consumption.
+ // Instead, try to get predictable output from "branch --contains".
list($branches) = $this->execxLocal(
- 'branch --contains %s',
+ '-c column.ui=never -c color.ui=never branch --contains %s',
$commit);
$branches = array_filter(explode("\n", $branches));
+
+ // Filter the list, removing the "current" marker (*) and ignoring
+ // anything other than known branch names (mainly, any possible
+ // "detached HEAD" or "no branch" line).
+ foreach ($branches as $key => $branch) {
+ $branch = trim($branch, ' *');
+ if (in_array($branch, $all_branch_names)) {
+ $branches[$key] = $branch;
+ } else {
+ unset($branches[$key]);
+ }
+ }
+
if ($head_branch_count === null) {
// If this is the first commit, it's HEAD. Count how many
// branches it is on; we want to include commits on the same
@@ -1147,9 +1176,6 @@
// for whatever reason.
$head_branch_count = count($branches);
} else if (count($branches) > $head_branch_count) {
- foreach ($branches as $key => $branch) {
- $branches[$key] = trim($branch, ' *');
- }
$branches = implode(', ', $branches);
$this->setBaseCommitExplanation(
pht(
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 27, 5:01 AM (21 h, 21 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6791992
Default Alt Text
D13989.diff (4 KB)
Attached To
Mode
D13989: Minimize reliance on 'git branch' output format
Attached
Detach File
Event Timeline
Log In to Comment