Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/data/DiffusionGitBranch.php
12241 views
1
<?php
2
3
final class DiffusionGitBranch extends Phobject {
4
5
const DEFAULT_GIT_REMOTE = 'origin';
6
7
/**
8
* Parse the output of 'git branch -r --verbose --no-abbrev' or similar into
9
* a map. For instance:
10
*
11
* array(
12
* 'origin/master' => '99a9c082f9a1b68c7264e26b9e552484a5ae5f25',
13
* );
14
*
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:
17
*
18
* array(
19
* 'master' => '99a9c082f9a1b68c7264e26b9e552484a5ae5f25',
20
* );
21
*
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.
25
*/
26
public static function parseRemoteBranchOutput(
27
$stdout,
28
$only_this_remote = null) {
29
$map = array();
30
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:
36
//
37
// origin/HEAD -> origin/master
38
//
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;
43
}
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));
49
}
50
51
$remote_branch = $matches[1];
52
$branch_head = $matches[2];
53
54
if (strpos($remote_branch, 'HEAD') !== false) {
55
// let's assume that no one will call their remote or branch HEAD
56
continue;
57
}
58
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));
66
}
67
$remote_name = $matches[1];
68
$branch_name = $matches[2];
69
if ($remote_name != $only_this_remote) {
70
continue;
71
}
72
$map[$branch_name] = $branch_head;
73
} else {
74
$map[$remote_branch] = $branch_head;
75
}
76
}
77
78
return $map;
79
}
80
81
/**
82
* As above, but with no `-r`. Used for bare repositories.
83
*/
84
public static function parseLocalBranchOutput($stdout) {
85
$map = array();
86
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));
96
}
97
98
$branch = $matches[1];
99
$branch_head = $matches[2];
100
if ($branch == '(no branch)') {
101
continue;
102
}
103
104
$map[$branch] = $branch_head;
105
}
106
107
return $map;
108
}
109
110
}
111
112