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) {
104126class 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 */
0 commit comments