Skip to content

Commit 241294e

Browse files
author
Tim Helfensdörfer
committed
Merge remote-tracking branch 'upstream/master'
2 parents 81bef16 + b3cf49b commit 241294e

File tree

2 files changed

+164
-14
lines changed

2 files changed

+164
-14
lines changed

Git.php

Lines changed: 158 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* A PHP git library
77
*
88
* @package Git.php
9-
* @version 0.1.2
9+
* @version 0.1.4
1010
* @author James Brumond
1111
* @copyright Copyright 2013 James Brumond
1212
* @repo http://github.com/kbjr/Git.php
@@ -32,22 +32,29 @@ class Git {
3232
* @var string
3333
*/
3434
protected static $bin = '/usr/bin/git';
35-
35+
3636
/**
3737
* Sets git executable path
38-
*
38+
*
3939
* @param string $path executable location
4040
*/
4141
public static function set_bin($path) {
4242
self::$bin = $path;
4343
}
44-
44+
4545
/**
4646
* Gets git executable path
4747
*/
4848
public static function get_bin() {
4949
return self::$bin;
5050
}
51+
52+
/**
53+
* Sets up library for use in a default Windows environment
54+
*/
55+
public static function windows_mode() {
56+
self::set_bin('git');
57+
}
5158

5259
/**
5360
* Create a new git repository
@@ -75,6 +82,21 @@ public static function &create($repo_path, $source = null) {
7582
public static function open($repo_path) {
7683
return new GitRepo($repo_path);
7784
}
85+
86+
/**
87+
* Clones a remote repo into a directory and then returns a GitRepo object
88+
* for the newly created local repo
89+
*
90+
* Accepts a creation path and a remote to clone from
91+
*
92+
* @access public
93+
* @param string repository path
94+
* @param string remote source
95+
* @return GitRepo
96+
**/
97+
public static function &clone_remote($repo_path, $remote) {
98+
return GitRepo::create_new($repo_path, $remote, true);
99+
}
78100

79101
/**
80102
* Checks if a variable is an instance of GitRepo
@@ -104,6 +126,8 @@ public static function is_repo($var) {
104126
class GitRepo {
105127

106128
protected $repo_path = null;
129+
protected $bare = false;
130+
protected $envopts = array();
107131

108132
/**
109133
* Create a new git repository
@@ -115,13 +139,17 @@ class GitRepo {
115139
* @param string directory to source
116140
* @return GitRepo
117141
*/
118-
public static function &create_new($repo_path, $source = null) {
142+
public static function &create_new($repo_path, $source = null, $remote_source = false) {
119143
if (is_dir($repo_path) && file_exists($repo_path."/.git") && is_dir($repo_path."/.git")) {
120144
throw new Exception('"'.$repo_path.'" is already a git repository');
121145
} else {
122146
$repo = new self($repo_path, true, false);
123147
if (is_string($source)) {
124-
$repo->clone_from($source);
148+
if ($remote_source) {
149+
$repo->clone_remote($source);
150+
} else {
151+
$repo->clone_from($source);
152+
}
125153
} else {
126154
$repo->run('init');
127155
}
@@ -153,15 +181,25 @@ public function __construct($repo_path = null, $create_new = false, $_init = tru
153181
* @access public
154182
* @param string repository path
155183
* @param bool create if not exists?
184+
* @param bool initialize new Git repo if not exists?
156185
* @return void
157186
*/
158187
public function set_repo_path($repo_path, $create_new = false, $_init = true) {
159188
if (is_string($repo_path)) {
160189
if ($new_path = realpath($repo_path)) {
161190
$repo_path = $new_path;
162191
if (is_dir($repo_path)) {
192+
// Is this a work tree?
163193
if (file_exists($repo_path."/.git") && is_dir($repo_path."/.git")) {
164194
$this->repo_path = $repo_path;
195+
$this->bare = false;
196+
// Is this a bare repo?
197+
} else if (is_file($repo_path."/config")) {
198+
$parse_ini = parse_ini_file($repo_path."/config");
199+
if ($parse_ini['bare']) {
200+
$this->repo_path = $repo_path;
201+
$this->bare = true;
202+
}
165203
} else {
166204
if ($create_new) {
167205
$this->repo_path = $repo_path;
@@ -230,7 +268,26 @@ protected function run_command($command) {
230268
2 => array('pipe', 'w'),
231269
);
232270
$pipes = array();
233-
$resource = proc_open($command, $descriptorspec, $pipes, $this->repo_path);
271+
/* Depending on the value of variables_order, $_ENV may be empty.
272+
* In that case, we have to explicitly set the new variables with
273+
* putenv, and call proc_open with env=null to inherit the reset
274+
* of the system.
275+
*
276+
* This is kind of crappy because we cannot easily restore just those
277+
* variables afterwards.
278+
*
279+
* If $_ENV is not empty, then we can just copy it and be done with it.
280+
*/
281+
if(count($_ENV) === 0) {
282+
$env = NULL;
283+
foreach($this->envopts as $k => $v) {
284+
putenv(sprintf("%s=%s",$k,$v));
285+
}
286+
} else {
287+
$env = array_merge($_ENV, $this->envopts);
288+
}
289+
$cwd = $this->repo_path;
290+
$resource = proc_open($command, $descriptorspec, $pipes, $cwd, $env);
234291

235292
$stdout = stream_get_contents($pipes[1]);
236293
$stderr = stream_get_contents($pipes[2]);
@@ -257,6 +314,23 @@ public function run($command) {
257314
return $this->run_command(Git::get_bin()." ".$command);
258315
}
259316

317+
/**
318+
* Runs a 'git status' call
319+
*
320+
* Accept a convert to HTML bool
321+
*
322+
* @access public
323+
* @param bool return string with <br />
324+
* @return string
325+
*/
326+
public function status($html = false) {
327+
$msg = $this->run("status");
328+
if ($html == true) {
329+
$msg = str_replace("\n", "<br />", $msg);
330+
}
331+
return $msg;
332+
}
333+
260334
/**
261335
* Runs a `git add` call
262336
*
@@ -272,6 +346,24 @@ public function add($files = "*") {
272346
}
273347
return $this->run("add $files -v");
274348
}
349+
350+
/**
351+
* Runs a `git rm` call
352+
*
353+
* Accepts a list of files to remove
354+
*
355+
* @access public
356+
* @param mixed files to remove
357+
* @param Boolean use the --cached flag?
358+
* @return string
359+
*/
360+
public function rm($files = "*", $cached = false) {
361+
if (is_array($files)) {
362+
$files = '"'.implode('" "', $files).'"';
363+
}
364+
return $this->run("rm ".($cached ? '--cached ' : '').$files);
365+
}
366+
275367

276368
/**
277369
* Runs a `git commit` call
@@ -280,10 +372,12 @@ public function add($files = "*") {
280372
*
281373
* @access public
282374
* @param string commit message
375+
* @param boolean should all files be committed automatically (-a flag)
283376
* @return string
284377
*/
285-
public function commit($message = "") {
286-
return $this->run("commit -av -m ".escapeshellarg($message));
378+
public function commit($message = "", $commit_all = true) {
379+
$flags = $commit_all ? '-av' : '-v';
380+
return $this->run("commit ".$flags." -m ".escapeshellarg($message));
287381
}
288382

289383
/**
@@ -335,10 +429,11 @@ public function clone_remote($source) {
335429
*
336430
* @access public
337431
* @param bool delete directories?
432+
* @param bool force clean?
338433
* @return string
339434
*/
340-
public function clean($dirs = false) {
341-
return $this->run("clean".(($dirs) ? " -d" : ""));
435+
public function clean($dirs = false, $force = false) {
436+
return $this->run("clean".(($force) ? " -f" : "").(($dirs) ? " -d" : ""));
342437
}
343438

344439
/**
@@ -388,6 +483,25 @@ public function list_branches($keep_asterisk = false) {
388483
return $branchArray;
389484
}
390485

486+
/**
487+
* Lists remote branches (using `git branch -r`).
488+
*
489+
* Also strips out the HEAD reference (e.g. "origin/HEAD -> origin/master").
490+
*
491+
* @access public
492+
* @return array
493+
*/
494+
public function list_remote_branches() {
495+
$branchArray = explode("\n", $this->run("branch -r"));
496+
foreach($branchArray as $i => &$branch) {
497+
$branch = trim($branch);
498+
if ($branch == "" || strpos($branch, 'HEAD -> ') !== false) {
499+
unset($branchArray[$i]);
500+
}
501+
}
502+
return $branchArray;
503+
}
504+
391505
/**
392506
* Returns name of active branch
393507
*
@@ -460,6 +574,26 @@ public function add_tag($tag, $message = null) {
460574
return $this->run("tag -a $tag -m $message");
461575
}
462576

577+
/**
578+
* List all the available repository tags.
579+
*
580+
* Optionally, accept a shell wildcard pattern and return only tags matching it.
581+
*
582+
* @access public
583+
* @param string $pattern Shell wildcard pattern to match tags against.
584+
* @return array Available repository tags.
585+
*/
586+
public function list_tags($pattern = null) {
587+
$tagArray = explode("\n", $this->run("tag -l $pattern"));
588+
foreach ($tagArray as $i => &$tag) {
589+
$tag = trim($tag);
590+
if ($tag == '') {
591+
unset($tagArray[$i]);
592+
}
593+
}
594+
595+
return $tagArray;
596+
}
463597

464598
/**
465599
* Push specific branch to a remote
@@ -473,7 +607,7 @@ public function add_tag($tag, $message = null) {
473607
public function push($remote, $branch) {
474608
return $this->run("push --tags $remote $branch");
475609
}
476-
610+
477611
/**
478612
* Pull specific branch from remote
479613
*
@@ -511,7 +645,17 @@ public function set_description($new) {
511645
public function get_description() {
512646
return file_get_contents($this->repo_path."/.git/description");
513647
}
514-
648+
649+
/**
650+
* Sets custom environment options for calling Git
651+
*
652+
* @param string key
653+
* @param string value
654+
*/
655+
public function setenv($key, $value) {
656+
$this->envopts[$key] = $value;
657+
}
658+
515659
}
516660

517-
/* End of file */
661+
/* End of file */

composer.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "kbjr/Git.php",
3+
"autoload": {
4+
"classmap": ["Git.php"]
5+
}
6+
}

0 commit comments

Comments
 (0)