Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / diffusion / data / DiffusionGitBranch.php
blob7fe8f5c6c0398e1c34d8f0f9f6651fa330cfcd4a
1 <?php
3 final class DiffusionGitBranch extends Phobject {
5 const DEFAULT_GIT_REMOTE = 'origin';
7 /**
8 * Parse the output of 'git branch -r --verbose --no-abbrev' or similar into
9 * a map. For instance:
11 * array(
12 * 'origin/master' => '99a9c082f9a1b68c7264e26b9e552484a5ae5f25',
13 * );
15 * If you specify $only_this_remote, branches will be filtered to only those
16 * on the given remote, **and the remote name will be stripped**. For example:
18 * array(
19 * 'master' => '99a9c082f9a1b68c7264e26b9e552484a5ae5f25',
20 * );
22 * @param string stdout of git branch command.
23 * @param string Filter branches to those on a specific remote.
24 * @return map Map of 'branch' or 'remote/branch' to hash at HEAD.
26 public static function parseRemoteBranchOutput(
27 $stdout,
28 $only_this_remote = null) {
29 $map = array();
31 $lines = array_filter(explode("\n", $stdout));
32 foreach ($lines as $line) {
33 $matches = null;
34 if (preg_match('/^ (\S+)\s+-> (\S+)$/', $line, $matches)) {
35 // This is a line like:
37 // origin/HEAD -> origin/master
39 // ...which we don't currently do anything interesting with, although
40 // in theory we could use it to automatically choose the default
41 // branch.
42 continue;
44 if (!preg_match('/^ *(\S+)\s+([a-z0-9]{40})/', $line, $matches)) {
45 throw new Exception(
46 pht(
47 'Failed to parse %s!',
48 $line));
51 $remote_branch = $matches[1];
52 $branch_head = $matches[2];
54 if (strpos($remote_branch, 'HEAD') !== false) {
55 // let's assume that no one will call their remote or branch HEAD
56 continue;
59 if ($only_this_remote) {
60 $matches = null;
61 if (!preg_match('#^([^/]+)/(.*)$#', $remote_branch, $matches)) {
62 throw new Exception(
63 pht(
64 "Failed to parse remote branch '%s'!",
65 $remote_branch));
67 $remote_name = $matches[1];
68 $branch_name = $matches[2];
69 if ($remote_name != $only_this_remote) {
70 continue;
72 $map[$branch_name] = $branch_head;
73 } else {
74 $map[$remote_branch] = $branch_head;
78 return $map;
81 /**
82 * As above, but with no `-r`. Used for bare repositories.
84 public static function parseLocalBranchOutput($stdout) {
85 $map = array();
87 $lines = array_filter(explode("\n", $stdout));
88 $regex = '/^[* ]*(\(no branch\)|\S+)\s+([a-z0-9]{40})/';
89 foreach ($lines as $line) {
90 $matches = null;
91 if (!preg_match($regex, $line, $matches)) {
92 throw new Exception(
93 pht(
94 'Failed to parse %s!',
95 $line));
98 $branch = $matches[1];
99 $branch_head = $matches[2];
100 if ($branch == '(no branch)') {
101 continue;
104 $map[$branch] = $branch_head;
107 return $map;