Skip to content

Commit 601ae1d

Browse files
author
Alexandre Salomé
committed
Merge pull request #17 from lyrixx/feat-enhancement
Added some enhancement
2 parents a1a5849 + 0668229 commit 601ae1d

File tree

13 files changed

+330
-50
lines changed

13 files changed

+330
-50
lines changed

doc/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ API documentation
1111
api/commit
1212
api/blame
1313
api/blob
14+
api/branch
1415
api/tree
1516
api/log
1617
api/diff

doc/api/branch.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Branch
2+
======
3+
4+
To access a *Branch*, starting from a repository object:
5+
6+
.. code-block:: php
7+
8+
$repository = new Gitonomy\Git\Repository('/path/to/repository');
9+
$branch = $repository->getReferences()->getBranch('master');
10+
11+
You can check is the branch is a local or remote one:
12+
13+
.. code-block:: php
14+
15+
$branch->isLocal();
16+
$branch->isRemote();

doc/api/commit.rst

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,33 @@ To access the message, you can use the *getMessage* method:
9494
$commit->getMessage();
9595
9696
For your convenience, this library provides a shortcut method to keep only the
97-
first line or first 80 characters if the first line is too long:
97+
first line or first 50 characters if the first line is too long:
9898

9999
.. code-block:: php
100100
101101
$commit->getShortMessage();
102102
103+
You can customize it like this:
104+
105+
.. code-block:: php
106+
107+
$commit->getShortMessage(45, true, '.');
108+
109+
* The first parameter is the max length of the message.
110+
* The second parameter determine if the last word should be cut or preserved
111+
* The third parameter is the separator
112+
113+
There are also two other methods for your convenience:
114+
115+
.. code-block:: php
116+
117+
// The first line
118+
$commit->getSubjectMessage();
119+
120+
// The body (rest of the message)
121+
$commit->getBodyMessage();
122+
123+
103124
Diff of a commit
104125
----------------
105126

@@ -137,3 +158,12 @@ Here is a very straightforward example:
137158
echo" Author: ".$last->getAuthorName()."\n";
138159
echo" Date: ".$last->getAuthorDate()->format('d/m/Y')."\n";
139160
echo" Message: ".$last->getMessage();
161+
162+
Find every branches containing a commit
163+
---------------------------------------
164+
165+
.. code-block:: php
166+
167+
$branches = $commit->getIncludingBranches($includeLocalBranches, $includeRemoteBranches);
168+
$localBranches = $commit->getIncludingBranches(true, false);
169+
$remoteBranches = $commit->getIncludingBranches(false, true);

doc/api/references.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,21 @@ If you want to access all branches or all tags:
2323

2424
.. code-block:: php
2525
26-
$branches = $repository->getBranches();
27-
$tags = $repository->getTags();
28-
$all = $repository->getAll();
26+
$branches = $repository->getBranches();
27+
$localBranches = $repository->getLocalBranches();
28+
$remoteBranches = $repository->getRemoteBranches();
29+
$tags = $repository->getTags();
30+
$all = $repository->getAll();
2931
3032
To get a given branch or tag, call *getBranch* or *getTag* on the
3133
*ReferenceBag*. Those methods return *Branch* and *Tag* objects:
3234

3335
.. code-block:: php
3436
35-
$master = $references->getBranch('master');
36-
$v0_1 = $references->getTag('0.1');
37+
$master = $references->getBranch('master');
38+
$feat123 = $references->getLocalBranch('feat123');
39+
$feat456 = $references->getRemoteBranch('origin/feat456');
40+
$v0_1 = $references->getTag('0.1');
3741
3842
If the reference cannot be resolved, a *ReferenceNotFoundException* will be
3943
thrown.

src/Gitonomy/Git/Commit.php

Lines changed: 108 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,6 @@ class Commit
111111
*/
112112
private $message;
113113

114-
/**
115-
* Short message of the commit.
116-
*
117-
* @var string
118-
*/
119-
private $shortMessage;
120-
121114
/**
122115
* Constructor.
123116
*
@@ -266,36 +259,97 @@ public function getLastModification($path, $lastHash = null)
266259
}
267260

268261
/**
269-
* Returns the first line of the commit, and the first 80 characters.
262+
* Returns the first line of the commit, and the first 50 characters.
263+
*
264+
* Ported from https://github.com/fabpot/Twig-extensions/blob/d67bc7e69788795d7905b52d31188bbc1d390e01/lib/Twig/Extensions/Extension/Text.php#L52-L109
265+
*
266+
* @param integer $length
267+
* @param boolean $preserve
268+
* @param string $separator
270269
*
271270
* @return string
272271
*/
273-
public function getShortMessage($limit = 50)
272+
public function getShortMessage($length = 50, $preserve = false, $separator = '...')
274273
{
275274
$this->initialize();
276275

277-
if (null !== $this->shortMessage) {
278-
return $this->shortMessage;
279-
}
276+
$message = $this->getSubjectMessage();
280277

281-
$pos = mb_strpos($this->message, "\n");
282-
$length = mb_strlen($this->message);
278+
if (function_exists('mb_substr')) {
279+
if (mb_strlen($message) > $length) {
280+
if ($preserve) {
281+
if (false !== ($breakpoint = mb_strpos($message, ' ', $length))) {
282+
$length = $breakpoint;
283+
}
284+
}
283285

284-
if (false === $pos) {
285-
if ($length < $limit) {
286-
$shortMessage = $this->message;
287-
} else {
288-
$shortMessage = mb_substr($this->message, 0, $limit).'...';
286+
return rtrim(mb_substr($message, 0, $length)) . $separator;
289287
}
288+
289+
return $message;
290290
} else {
291-
if ($pos < $limit) {
292-
$shortMessage = mb_substr($this->message, 0, $pos);
291+
if (strlen($message) > $length) {
292+
if ($preserve) {
293+
if (false !== ($breakpoint = strpos($message, ' ', $length))) {
294+
$length = $breakpoint;
295+
}
296+
}
297+
298+
return rtrim(substr($message, 0, $length)) . $separator;
299+
}
300+
301+
return $message;
302+
}
303+
}
304+
305+
/**
306+
* Find branch containing the commit
307+
*
308+
* @param boolean $local set true to try to locate a commit on local repository
309+
* @param boolean $remote set true to try to locate a commit on remote repository
310+
*
311+
* @return array An array of Reference\Branch
312+
*/
313+
public function getIncludingBranches($local = true, $remote = true)
314+
{
315+
$arguments = array('--contains', $this->hash);
316+
317+
if ($local && $remote) {
318+
$arguments[] = '-a';
319+
} elseif (!$local && $remote) {
320+
$arguments[] = '-r';
321+
} elseif (!$local && !$remote) {
322+
throw new \InvalidArgumentException('You should a least set one argument to true');
323+
}
324+
325+
try {
326+
$result = $this->repository->run('branch', $arguments);
327+
} catch (\Exception $e) {
328+
return array();
329+
}
330+
331+
if (!$result) {
332+
return array();
333+
}
334+
335+
$branchesName = explode("\n", trim(str_replace('*', '', $result)));
336+
$branchesName = array_filter($branchesName, function($v) { return false === strpos($v, '->');});
337+
$branchesName = array_map('trim', $branchesName);
338+
339+
$references = $this->repository->getReferences();
340+
341+
$branches = array();
342+
foreach ($branchesName as $branchName) {
343+
if (false === $local) {
344+
$branches[] = $references->getRemoteBranch($branchName);
345+
} elseif (0 === strrpos($branchName, 'remotes/')) {
346+
$branches[] = $references->getRemoteBranch(str_replace('remotes/', '', $branchName));
293347
} else {
294-
$shortMessage = mb_substr($this->message, 0, $limit).'...';
348+
$branches[] = $references->getBranch($branchName);
295349
}
296350
}
297351

298-
return $this->shortMessage = $shortMessage;
352+
return $branches;
299353
}
300354

301355
/**
@@ -381,4 +435,35 @@ public function getMessage()
381435

382436
return $this->message;
383437
}
438+
439+
/**
440+
* Returns the subject message (the first line)
441+
*
442+
* @return string The subject message
443+
*/
444+
public function getSubjectMessage()
445+
{
446+
$message = $this->getMessage();
447+
448+
$lines = explode("\n", $message);
449+
450+
return reset($lines);
451+
}
452+
453+
/**
454+
* Return the body message
455+
*
456+
* @return string The body message
457+
*/
458+
public function getBodyMessage()
459+
{
460+
$message = $this->getMessage();
461+
462+
$lines = explode("\n", $message);
463+
464+
array_shift($lines);
465+
array_shift($lines);
466+
467+
return implode("\n", $lines);
468+
}
384469
}

src/Gitonomy/Git/Exception/ReferenceNotFoundException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ class ReferenceNotFoundException extends \InvalidArgumentException implements Gi
1616
{
1717
public function __construct($reference)
1818
{
19-
parent::__construct(sprintf('Reference not found'));
19+
parent::__construct(sprintf('Reference not found: "%s"', $reference));
2020
}
2121
}

src/Gitonomy/Git/Reference/Branch.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,42 @@
2121
*/
2222
class Branch extends Reference
2323
{
24+
private $local = null;
25+
2426
/**
2527
* {@inheritdoc}
2628
*/
2729
public function getName()
2830
{
29-
if (!preg_match('#^refs/heads/(.*)$#', $this->fullname, $vars)) {
30-
throw new \RuntimeException(sprintf('Cannot extract branch name from "%s"', $this->fullname));
31+
if (preg_match('#^refs/heads/(?<name>.*)$#', $this->fullname, $vars)) {
32+
return $vars['name'];
33+
}
34+
35+
if (preg_match('#^refs/remotes/(?<remote>[^/]*)/(?<name>.*)$#', $this->fullname, $vars)) {
36+
return $vars['remote'].'/'.$vars['name'];
3137
}
3238

33-
return $vars[1];
39+
throw new \RuntimeException(sprintf('Cannot extract branch name from "%s"', $this->fullname));
40+
}
41+
42+
public function isRemote()
43+
{
44+
$this->detectBranchType();
45+
46+
return !$this->local;
47+
}
48+
49+
public function isLocal()
50+
{
51+
$this->detectBranchType();
52+
53+
return $this->local;
54+
}
55+
56+
private function detectBranchType()
57+
{
58+
if (null === $this->local) {
59+
$this->local = !preg_match('#^refs/remotes/(?<remote>[^/]*)/(?<name>.*)$#', $this->fullname);
60+
}
3461
}
3562
}

0 commit comments

Comments
 (0)