xref: /plugin/gitbacked/classes/GitRepo.php (revision b08c3d51e04f23d878d49c6b945b5f8a1aef6f50)
1*b08c3d51SMarkus Hoffrogge<?php
2*b08c3d51SMarkus Hoffrogge
3*b08c3d51SMarkus Hoffrogge/*
4*b08c3d51SMarkus Hoffrogge * Git.php
5*b08c3d51SMarkus Hoffrogge *
6*b08c3d51SMarkus Hoffrogge * A PHP git library
7*b08c3d51SMarkus Hoffrogge *
8*b08c3d51SMarkus Hoffrogge * @package    Git.php
9*b08c3d51SMarkus Hoffrogge * @version    0.1.4
10*b08c3d51SMarkus Hoffrogge * @author     James Brumond
11*b08c3d51SMarkus Hoffrogge * @copyright  Copyright 2013 James Brumond
12*b08c3d51SMarkus Hoffrogge * @repo       http://github.com/kbjr/Git.php
13*b08c3d51SMarkus Hoffrogge */
14*b08c3d51SMarkus Hoffrogge
15*b08c3d51SMarkus Hoffroggeif (__FILE__ == $_SERVER['SCRIPT_FILENAME']) die('Bad load order');
16*b08c3d51SMarkus Hoffrogge
17*b08c3d51SMarkus Hoffrogge// ------------------------------------------------------------------------
18*b08c3d51SMarkus Hoffrogge
19*b08c3d51SMarkus Hoffrogge/**
20*b08c3d51SMarkus Hoffrogge * Git Repository Interface Class
21*b08c3d51SMarkus Hoffrogge *
22*b08c3d51SMarkus Hoffrogge * This class enables the creating, reading, and manipulation
23*b08c3d51SMarkus Hoffrogge * of a git repository
24*b08c3d51SMarkus Hoffrogge *
25*b08c3d51SMarkus Hoffrogge * @class  GitRepo
26*b08c3d51SMarkus Hoffrogge */
27*b08c3d51SMarkus Hoffroggeclass GitRepo {
28*b08c3d51SMarkus Hoffrogge
29*b08c3d51SMarkus Hoffrogge	// This regex will filter a probable password from any string containing a Git URL.
30*b08c3d51SMarkus Hoffrogge	// Limitation: it will work for the first git URL occurrence in a string.
31*b08c3d51SMarkus Hoffrogge	// Used https://regex101.com/ for evaluating!
32*b08c3d51SMarkus Hoffrogge	const REGEX_GIT_URL_FILTER_PWD = "/^(.*)((http:)|(https:))([^:]+)(:[^@]*)?(.*)/im";
33*b08c3d51SMarkus Hoffrogge	const REGEX_GIT_URL_FILTER_PWD_REPLACE_PATTERN = "$1$2$5$7";
34*b08c3d51SMarkus Hoffrogge
35*b08c3d51SMarkus Hoffrogge	protected $repo_path = null;
36*b08c3d51SMarkus Hoffrogge	protected $bare = false;
37*b08c3d51SMarkus Hoffrogge	protected $envopts = array();
38*b08c3d51SMarkus Hoffrogge	// Fix for PHP <=7.3 compatibility: Type declarations for properties work since PHP >= 7.4 only.
39*b08c3d51SMarkus Hoffrogge	// protected ?\action_plugin_gitbacked_editcommit $plugin = null;
40*b08c3d51SMarkus Hoffrogge	protected $plugin = null;
41*b08c3d51SMarkus Hoffrogge
42*b08c3d51SMarkus Hoffrogge	/**
43*b08c3d51SMarkus Hoffrogge	 * Create a new git repository
44*b08c3d51SMarkus Hoffrogge	 *
45*b08c3d51SMarkus Hoffrogge	 * Accepts a creation path, and, optionally, a source path
46*b08c3d51SMarkus Hoffrogge	 *
47*b08c3d51SMarkus Hoffrogge	 * @access  public
48*b08c3d51SMarkus Hoffrogge	 * @param   string  repository path
49*b08c3d51SMarkus Hoffrogge	 * @param   \action_plugin_gitbacked_editcommit plugin
50*b08c3d51SMarkus Hoffrogge	 * @param   string  directory to source
51*b08c3d51SMarkus Hoffrogge	 * @param   string  reference path
52*b08c3d51SMarkus Hoffrogge	 * @return  GitRepo  or null in case of an error
53*b08c3d51SMarkus Hoffrogge	 */
54*b08c3d51SMarkus Hoffrogge	public static function &create_new($repo_path, \action_plugin_gitbacked_editcommit $plugin = null, $source = null, $remote_source = false, $reference = null) {
55*b08c3d51SMarkus Hoffrogge		if (is_dir($repo_path) && file_exists($repo_path."/.git") && is_dir($repo_path."/.git")) {
56*b08c3d51SMarkus Hoffrogge			throw new Exception(self::handle_create_new_error($repo_path, $reference, '"'.$repo_path.'" is already a git repository', $plugin));
57*b08c3d51SMarkus Hoffrogge		} else {
58*b08c3d51SMarkus Hoffrogge			$repo = new self($repo_path, $plugin, true, false);
59*b08c3d51SMarkus Hoffrogge			if (is_string($source)) {
60*b08c3d51SMarkus Hoffrogge				if ($remote_source) {
61*b08c3d51SMarkus Hoffrogge					if (!is_dir($reference) || !is_dir($reference.'/.git')) {
62*b08c3d51SMarkus Hoffrogge						throw new Exception(self::handle_create_new_error($repo_path, $reference, '"'.$reference.'" is not a git repository. Cannot use as reference.', $plugin));
63*b08c3d51SMarkus Hoffrogge					} else if (strlen($reference)) {
64*b08c3d51SMarkus Hoffrogge						$reference = realpath($reference);
65*b08c3d51SMarkus Hoffrogge						$reference = "--reference $reference";
66*b08c3d51SMarkus Hoffrogge					}
67*b08c3d51SMarkus Hoffrogge					$repo->clone_remote($source, $reference);
68*b08c3d51SMarkus Hoffrogge				} else {
69*b08c3d51SMarkus Hoffrogge					$repo->clone_from($source);
70*b08c3d51SMarkus Hoffrogge				}
71*b08c3d51SMarkus Hoffrogge			} else {
72*b08c3d51SMarkus Hoffrogge				$repo->run('init');
73*b08c3d51SMarkus Hoffrogge			}
74*b08c3d51SMarkus Hoffrogge			return $repo;
75*b08c3d51SMarkus Hoffrogge		}
76*b08c3d51SMarkus Hoffrogge	}
77*b08c3d51SMarkus Hoffrogge
78*b08c3d51SMarkus Hoffrogge	/**
79*b08c3d51SMarkus Hoffrogge	 * Constructor
80*b08c3d51SMarkus Hoffrogge	 *
81*b08c3d51SMarkus Hoffrogge	 * Accepts a repository path
82*b08c3d51SMarkus Hoffrogge	 *
83*b08c3d51SMarkus Hoffrogge	 * @access  public
84*b08c3d51SMarkus Hoffrogge	 * @param   string  repository path
85*b08c3d51SMarkus Hoffrogge	 * @param   \action_plugin_gitbacked_editcommit plugin
86*b08c3d51SMarkus Hoffrogge	 * @param   bool    create if not exists?
87*b08c3d51SMarkus Hoffrogge	 * @return  void
88*b08c3d51SMarkus Hoffrogge	 */
89*b08c3d51SMarkus Hoffrogge	public function __construct($repo_path = null, \action_plugin_gitbacked_editcommit $plugin = null, $create_new = false, $_init = true) {
90*b08c3d51SMarkus Hoffrogge		$this->plugin = $plugin;
91*b08c3d51SMarkus Hoffrogge		if (is_string($repo_path)) {
92*b08c3d51SMarkus Hoffrogge			$this->set_repo_path($repo_path, $create_new, $_init);
93*b08c3d51SMarkus Hoffrogge		}
94*b08c3d51SMarkus Hoffrogge	}
95*b08c3d51SMarkus Hoffrogge
96*b08c3d51SMarkus Hoffrogge	/**
97*b08c3d51SMarkus Hoffrogge	 * Set the repository's path
98*b08c3d51SMarkus Hoffrogge	 *
99*b08c3d51SMarkus Hoffrogge	 * Accepts the repository path
100*b08c3d51SMarkus Hoffrogge	 *
101*b08c3d51SMarkus Hoffrogge	 * @access  public
102*b08c3d51SMarkus Hoffrogge	 * @param   string  repository path
103*b08c3d51SMarkus Hoffrogge	 * @param   bool    create if not exists?
104*b08c3d51SMarkus Hoffrogge	 * @param   bool    initialize new Git repo if not exists?
105*b08c3d51SMarkus Hoffrogge	 * @return  void
106*b08c3d51SMarkus Hoffrogge	 */
107*b08c3d51SMarkus Hoffrogge	public function set_repo_path($repo_path, $create_new = false, $_init = true) {
108*b08c3d51SMarkus Hoffrogge		if (is_string($repo_path)) {
109*b08c3d51SMarkus Hoffrogge			if ($new_path = realpath($repo_path)) {
110*b08c3d51SMarkus Hoffrogge				$repo_path = $new_path;
111*b08c3d51SMarkus Hoffrogge				if (is_dir($repo_path)) {
112*b08c3d51SMarkus Hoffrogge					// Is this a work tree?
113*b08c3d51SMarkus Hoffrogge					if (file_exists($repo_path."/.git") && is_dir($repo_path."/.git")) {
114*b08c3d51SMarkus Hoffrogge						$this->repo_path = $repo_path;
115*b08c3d51SMarkus Hoffrogge						$this->bare = false;
116*b08c3d51SMarkus Hoffrogge					// Is this a bare repo?
117*b08c3d51SMarkus Hoffrogge					} else if (is_file($repo_path."/config")) {
118*b08c3d51SMarkus Hoffrogge					  $parse_ini = parse_ini_file($repo_path."/config");
119*b08c3d51SMarkus Hoffrogge						if ($parse_ini['bare']) {
120*b08c3d51SMarkus Hoffrogge							$this->repo_path = $repo_path;
121*b08c3d51SMarkus Hoffrogge							$this->bare = true;
122*b08c3d51SMarkus Hoffrogge						}
123*b08c3d51SMarkus Hoffrogge					} else {
124*b08c3d51SMarkus Hoffrogge						if ($create_new) {
125*b08c3d51SMarkus Hoffrogge							$this->repo_path = $repo_path;
126*b08c3d51SMarkus Hoffrogge							if ($_init) {
127*b08c3d51SMarkus Hoffrogge								$this->run('init');
128*b08c3d51SMarkus Hoffrogge							}
129*b08c3d51SMarkus Hoffrogge						} else {
130*b08c3d51SMarkus Hoffrogge							throw new Exception($this->handle_repo_path_error($repo_path, '"'.$repo_path.'" is not a git repository'));
131*b08c3d51SMarkus Hoffrogge						}
132*b08c3d51SMarkus Hoffrogge					}
133*b08c3d51SMarkus Hoffrogge				} else {
134*b08c3d51SMarkus Hoffrogge					throw new Exception($this->handle_repo_path_error($repo_path, '"'.$repo_path.'" is not a directory'));
135*b08c3d51SMarkus Hoffrogge				}
136*b08c3d51SMarkus Hoffrogge			} else {
137*b08c3d51SMarkus Hoffrogge				if ($create_new) {
138*b08c3d51SMarkus Hoffrogge					if ($parent = realpath(dirname($repo_path))) {
139*b08c3d51SMarkus Hoffrogge						mkdir($repo_path);
140*b08c3d51SMarkus Hoffrogge						$this->repo_path = $repo_path;
141*b08c3d51SMarkus Hoffrogge						if ($_init) $this->run('init');
142*b08c3d51SMarkus Hoffrogge					} else {
143*b08c3d51SMarkus Hoffrogge						throw new Exception($this->handle_repo_path_error($repo_path, 'cannot create repository in non-existent directory'));
144*b08c3d51SMarkus Hoffrogge					}
145*b08c3d51SMarkus Hoffrogge				} else {
146*b08c3d51SMarkus Hoffrogge					throw new Exception($this->handle_repo_path_error($repo_path, '"'.$repo_path.'" does not exist'));
147*b08c3d51SMarkus Hoffrogge				}
148*b08c3d51SMarkus Hoffrogge			}
149*b08c3d51SMarkus Hoffrogge		}
150*b08c3d51SMarkus Hoffrogge	}
151*b08c3d51SMarkus Hoffrogge
152*b08c3d51SMarkus Hoffrogge	/**
153*b08c3d51SMarkus Hoffrogge	 * Get the path to the git repo directory (eg. the ".git" directory)
154*b08c3d51SMarkus Hoffrogge	 *
155*b08c3d51SMarkus Hoffrogge	 * @access public
156*b08c3d51SMarkus Hoffrogge	 * @return string
157*b08c3d51SMarkus Hoffrogge	 */
158*b08c3d51SMarkus Hoffrogge	public function git_directory_path() {
159*b08c3d51SMarkus Hoffrogge		return ($this->bare) ? $this->repo_path : $this->repo_path."/.git";
160*b08c3d51SMarkus Hoffrogge	}
161*b08c3d51SMarkus Hoffrogge
162*b08c3d51SMarkus Hoffrogge	/**
163*b08c3d51SMarkus Hoffrogge	 * Tests if git is installed
164*b08c3d51SMarkus Hoffrogge	 *
165*b08c3d51SMarkus Hoffrogge	 * @access  public
166*b08c3d51SMarkus Hoffrogge	 * @return  bool
167*b08c3d51SMarkus Hoffrogge	 */
168*b08c3d51SMarkus Hoffrogge	public function test_git() {
169*b08c3d51SMarkus Hoffrogge		$descriptorspec = array(
170*b08c3d51SMarkus Hoffrogge			1 => array('pipe', 'w'),
171*b08c3d51SMarkus Hoffrogge			2 => array('pipe', 'w'),
172*b08c3d51SMarkus Hoffrogge		);
173*b08c3d51SMarkus Hoffrogge		$pipes = array();
174*b08c3d51SMarkus Hoffrogge		$resource = proc_open(Git::get_bin(), $descriptorspec, $pipes);
175*b08c3d51SMarkus Hoffrogge
176*b08c3d51SMarkus Hoffrogge		$stdout = stream_get_contents($pipes[1]);
177*b08c3d51SMarkus Hoffrogge		$stderr = stream_get_contents($pipes[2]);
178*b08c3d51SMarkus Hoffrogge		foreach ($pipes as $pipe) {
179*b08c3d51SMarkus Hoffrogge			fclose($pipe);
180*b08c3d51SMarkus Hoffrogge		}
181*b08c3d51SMarkus Hoffrogge
182*b08c3d51SMarkus Hoffrogge		$status = trim(proc_close($resource));
183*b08c3d51SMarkus Hoffrogge		return ($status != 127);
184*b08c3d51SMarkus Hoffrogge	}
185*b08c3d51SMarkus Hoffrogge
186*b08c3d51SMarkus Hoffrogge	/**
187*b08c3d51SMarkus Hoffrogge	 * Run a command in the git repository
188*b08c3d51SMarkus Hoffrogge	 *
189*b08c3d51SMarkus Hoffrogge	 * Accepts a shell command to run
190*b08c3d51SMarkus Hoffrogge	 *
191*b08c3d51SMarkus Hoffrogge	 * @access  protected
192*b08c3d51SMarkus Hoffrogge	 * @param   string  command to run
193*b08c3d51SMarkus Hoffrogge	 * @return  string  or null in case of an error
194*b08c3d51SMarkus Hoffrogge	 */
195*b08c3d51SMarkus Hoffrogge	protected function run_command($command) {
196*b08c3d51SMarkus Hoffrogge		//dbglog("Git->run_command(command=[".$command."])");
197*b08c3d51SMarkus Hoffrogge		$descriptorspec = array(
198*b08c3d51SMarkus Hoffrogge			1 => array('pipe', 'w'),
199*b08c3d51SMarkus Hoffrogge			2 => array('pipe', 'w'),
200*b08c3d51SMarkus Hoffrogge		);
201*b08c3d51SMarkus Hoffrogge		$pipes = array();
202*b08c3d51SMarkus Hoffrogge		$cwd = $this->repo_path;
203*b08c3d51SMarkus Hoffrogge		//dbglog("GitBacked - cwd: [".$cwd."]");
204*b08c3d51SMarkus Hoffrogge		/* Provide any $this->envopts via putenv
205*b08c3d51SMarkus Hoffrogge		 * and call proc_open with env=null to inherit the rest
206*b08c3d51SMarkus Hoffrogge		 * of env variables from the original process of the system.
207*b08c3d51SMarkus Hoffrogge		 * Note: Variables set by putenv live for a
208*b08c3d51SMarkus Hoffrogge		 * single PHP request run only. These variables
209*b08c3d51SMarkus Hoffrogge		 * are visible "locally". They are NOT listed by getenv(),
210*b08c3d51SMarkus Hoffrogge		 * but they are visible to the process forked by proc_open().
211*b08c3d51SMarkus Hoffrogge		 */
212*b08c3d51SMarkus Hoffrogge		foreach($this->envopts as $k => $v) {
213*b08c3d51SMarkus Hoffrogge			putenv(sprintf("%s=%s",$k,$v));
214*b08c3d51SMarkus Hoffrogge		}
215*b08c3d51SMarkus Hoffrogge		$resource = proc_open($command, $descriptorspec, $pipes, $cwd, null);
216*b08c3d51SMarkus Hoffrogge
217*b08c3d51SMarkus Hoffrogge		$stdout = stream_get_contents($pipes[1]);
218*b08c3d51SMarkus Hoffrogge		$stderr = stream_get_contents($pipes[2]);
219*b08c3d51SMarkus Hoffrogge		foreach ($pipes as $pipe) {
220*b08c3d51SMarkus Hoffrogge			fclose($pipe);
221*b08c3d51SMarkus Hoffrogge		}
222*b08c3d51SMarkus Hoffrogge
223*b08c3d51SMarkus Hoffrogge		$status = trim(proc_close($resource));
224*b08c3d51SMarkus Hoffrogge		//dbglog("GitBacked: run_command status: ".$status);
225*b08c3d51SMarkus Hoffrogge		if ($status) {
226*b08c3d51SMarkus Hoffrogge			//dbglog("GitBacked - stderr: [".$stderr."]");
227*b08c3d51SMarkus Hoffrogge			// Remove a probable password from the Git URL, if the URL is contained in the error message
228*b08c3d51SMarkus Hoffrogge			$error_message = preg_replace($this::REGEX_GIT_URL_FILTER_PWD, $this::REGEX_GIT_URL_FILTER_PWD_REPLACE_PATTERN, $stderr);
229*b08c3d51SMarkus Hoffrogge			//dbglog("GitBacked - error_message: [".$error_message."]");
230*b08c3d51SMarkus Hoffrogge			throw new Exception($this->handle_command_error($this->repo_path, $cwd, $command, $status, $error_message));
231*b08c3d51SMarkus Hoffrogge		} else {
232*b08c3d51SMarkus Hoffrogge			$this->handle_command_success($this->repo_path, $cwd, $command);
233*b08c3d51SMarkus Hoffrogge		}
234*b08c3d51SMarkus Hoffrogge
235*b08c3d51SMarkus Hoffrogge		return $stdout;
236*b08c3d51SMarkus Hoffrogge	}
237*b08c3d51SMarkus Hoffrogge
238*b08c3d51SMarkus Hoffrogge	/**
239*b08c3d51SMarkus Hoffrogge	 * Run a git command in the git repository
240*b08c3d51SMarkus Hoffrogge	 *
241*b08c3d51SMarkus Hoffrogge	 * Accepts a git command to run
242*b08c3d51SMarkus Hoffrogge	 *
243*b08c3d51SMarkus Hoffrogge	 * @access  public
244*b08c3d51SMarkus Hoffrogge	 * @param   string  command to run
245*b08c3d51SMarkus Hoffrogge	 * @return  string
246*b08c3d51SMarkus Hoffrogge	 */
247*b08c3d51SMarkus Hoffrogge	public function run($command) {
248*b08c3d51SMarkus Hoffrogge		return $this->run_command(Git::get_bin()." ".$command);
249*b08c3d51SMarkus Hoffrogge	}
250*b08c3d51SMarkus Hoffrogge
251*b08c3d51SMarkus Hoffrogge	/**
252*b08c3d51SMarkus Hoffrogge	 * Handles error on create_new
253*b08c3d51SMarkus Hoffrogge	 *
254*b08c3d51SMarkus Hoffrogge	 * @access  protected
255*b08c3d51SMarkus Hoffrogge	 * @param   string  repository path
256*b08c3d51SMarkus Hoffrogge	 * @param   string  error message
257*b08c3d51SMarkus Hoffrogge	 * @return  string  error message
258*b08c3d51SMarkus Hoffrogge	 */
259*b08c3d51SMarkus Hoffrogge	protected static function handle_create_new_error($repo_path, $reference, $error_message, $plugin) {
260*b08c3d51SMarkus Hoffrogge		if ($plugin instanceof \action_plugin_gitbacked_editcommit) {
261*b08c3d51SMarkus Hoffrogge			$plugin->notify_create_new_error($repo_path, $reference, $error_message);
262*b08c3d51SMarkus Hoffrogge		}
263*b08c3d51SMarkus Hoffrogge		return $error_message;
264*b08c3d51SMarkus Hoffrogge	}
265*b08c3d51SMarkus Hoffrogge
266*b08c3d51SMarkus Hoffrogge	/**
267*b08c3d51SMarkus Hoffrogge	 * Handles error on setting the repo path
268*b08c3d51SMarkus Hoffrogge	 *
269*b08c3d51SMarkus Hoffrogge	 * @access  protected
270*b08c3d51SMarkus Hoffrogge	 * @param   string  repository path
271*b08c3d51SMarkus Hoffrogge	 * @param   string  error message
272*b08c3d51SMarkus Hoffrogge	 * @return  string  error message
273*b08c3d51SMarkus Hoffrogge	 */
274*b08c3d51SMarkus Hoffrogge	protected function handle_repo_path_error($repo_path, $error_message) {
275*b08c3d51SMarkus Hoffrogge		if ($this->plugin instanceof \action_plugin_gitbacked_editcommit) {
276*b08c3d51SMarkus Hoffrogge			$this->plugin->notify_repo_path_error($repo_path, $error_message);
277*b08c3d51SMarkus Hoffrogge		}
278*b08c3d51SMarkus Hoffrogge		return $error_message;
279*b08c3d51SMarkus Hoffrogge	}
280*b08c3d51SMarkus Hoffrogge
281*b08c3d51SMarkus Hoffrogge	/**
282*b08c3d51SMarkus Hoffrogge	 * Handles error on git command
283*b08c3d51SMarkus Hoffrogge	 *
284*b08c3d51SMarkus Hoffrogge	 * @access  protected
285*b08c3d51SMarkus Hoffrogge	 * @param   string  repository path
286*b08c3d51SMarkus Hoffrogge	 * @param   string  current working dir
287*b08c3d51SMarkus Hoffrogge	 * @param   string  command line
288*b08c3d51SMarkus Hoffrogge	 * @param   int     exit code of command (status)
289*b08c3d51SMarkus Hoffrogge	 * @param   string  error message
290*b08c3d51SMarkus Hoffrogge	 * @return  string  error message
291*b08c3d51SMarkus Hoffrogge	 */
292*b08c3d51SMarkus Hoffrogge	protected function handle_command_error($repo_path, $cwd, $command, $status, $error_message) {
293*b08c3d51SMarkus Hoffrogge		if ($this->plugin instanceof \action_plugin_gitbacked_editcommit) {
294*b08c3d51SMarkus Hoffrogge			$this->plugin->notify_command_error($repo_path, $cwd, $command, $status, $error_message);
295*b08c3d51SMarkus Hoffrogge		}
296*b08c3d51SMarkus Hoffrogge		return $error_message;
297*b08c3d51SMarkus Hoffrogge	}
298*b08c3d51SMarkus Hoffrogge
299*b08c3d51SMarkus Hoffrogge	/**
300*b08c3d51SMarkus Hoffrogge	 * Handles success on git command
301*b08c3d51SMarkus Hoffrogge	 *
302*b08c3d51SMarkus Hoffrogge	 * @access  protected
303*b08c3d51SMarkus Hoffrogge	 * @param   string  repository path
304*b08c3d51SMarkus Hoffrogge	 * @param   string  current working dir
305*b08c3d51SMarkus Hoffrogge	 * @param   string  command line
306*b08c3d51SMarkus Hoffrogge	 * @return  void
307*b08c3d51SMarkus Hoffrogge	 */
308*b08c3d51SMarkus Hoffrogge	protected function handle_command_success($repo_path, $cwd, $command) {
309*b08c3d51SMarkus Hoffrogge		if ($this->plugin instanceof \action_plugin_gitbacked_editcommit) {
310*b08c3d51SMarkus Hoffrogge			$this->plugin->notify_command_success($repo_path, $cwd, $command);
311*b08c3d51SMarkus Hoffrogge		}
312*b08c3d51SMarkus Hoffrogge	}
313*b08c3d51SMarkus Hoffrogge
314*b08c3d51SMarkus Hoffrogge	/**
315*b08c3d51SMarkus Hoffrogge	 * Runs a 'git status' call
316*b08c3d51SMarkus Hoffrogge	 *
317*b08c3d51SMarkus Hoffrogge	 * Accept a convert to HTML bool
318*b08c3d51SMarkus Hoffrogge	 *
319*b08c3d51SMarkus Hoffrogge	 * @access public
320*b08c3d51SMarkus Hoffrogge	 * @param bool  return string with <br />
321*b08c3d51SMarkus Hoffrogge	 * @return string
322*b08c3d51SMarkus Hoffrogge	 */
323*b08c3d51SMarkus Hoffrogge	public function status($html = false) {
324*b08c3d51SMarkus Hoffrogge		$msg = $this->run("status");
325*b08c3d51SMarkus Hoffrogge		if ($html == true) {
326*b08c3d51SMarkus Hoffrogge			$msg = str_replace("\n", "<br />", $msg);
327*b08c3d51SMarkus Hoffrogge		}
328*b08c3d51SMarkus Hoffrogge		return $msg;
329*b08c3d51SMarkus Hoffrogge	}
330*b08c3d51SMarkus Hoffrogge
331*b08c3d51SMarkus Hoffrogge	/**
332*b08c3d51SMarkus Hoffrogge	 * Runs a `git add` call
333*b08c3d51SMarkus Hoffrogge	 *
334*b08c3d51SMarkus Hoffrogge	 * Accepts a list of files to add
335*b08c3d51SMarkus Hoffrogge	 *
336*b08c3d51SMarkus Hoffrogge	 * @access  public
337*b08c3d51SMarkus Hoffrogge	 * @param   mixed   files to add
338*b08c3d51SMarkus Hoffrogge	 * @return  string
339*b08c3d51SMarkus Hoffrogge	 */
340*b08c3d51SMarkus Hoffrogge	public function add($files = "*") {
341*b08c3d51SMarkus Hoffrogge		if (is_array($files)) {
342*b08c3d51SMarkus Hoffrogge			$files = '"'.implode('" "', $files).'"';
343*b08c3d51SMarkus Hoffrogge		}
344*b08c3d51SMarkus Hoffrogge		return $this->run("add $files -v");
345*b08c3d51SMarkus Hoffrogge	}
346*b08c3d51SMarkus Hoffrogge
347*b08c3d51SMarkus Hoffrogge	/**
348*b08c3d51SMarkus Hoffrogge	 * Runs a `git rm` call
349*b08c3d51SMarkus Hoffrogge	 *
350*b08c3d51SMarkus Hoffrogge	 * Accepts a list of files to remove
351*b08c3d51SMarkus Hoffrogge	 *
352*b08c3d51SMarkus Hoffrogge	 * @access  public
353*b08c3d51SMarkus Hoffrogge	 * @param   mixed    files to remove
354*b08c3d51SMarkus Hoffrogge	 * @param   Boolean  use the --cached flag?
355*b08c3d51SMarkus Hoffrogge	 * @return  string
356*b08c3d51SMarkus Hoffrogge	 */
357*b08c3d51SMarkus Hoffrogge	public function rm($files = "*", $cached = false) {
358*b08c3d51SMarkus Hoffrogge		if (is_array($files)) {
359*b08c3d51SMarkus Hoffrogge			$files = '"'.implode('" "', $files).'"';
360*b08c3d51SMarkus Hoffrogge		}
361*b08c3d51SMarkus Hoffrogge		return $this->run("rm ".($cached ? '--cached ' : '').$files);
362*b08c3d51SMarkus Hoffrogge	}
363*b08c3d51SMarkus Hoffrogge
364*b08c3d51SMarkus Hoffrogge
365*b08c3d51SMarkus Hoffrogge	/**
366*b08c3d51SMarkus Hoffrogge	 * Runs a `git commit` call
367*b08c3d51SMarkus Hoffrogge	 *
368*b08c3d51SMarkus Hoffrogge	 * Accepts a commit message string
369*b08c3d51SMarkus Hoffrogge	 *
370*b08c3d51SMarkus Hoffrogge	 * @access  public
371*b08c3d51SMarkus Hoffrogge	 * @param   string  commit message
372*b08c3d51SMarkus Hoffrogge	 * @param   boolean  should all files be committed automatically (-a flag)
373*b08c3d51SMarkus Hoffrogge	 * @return  string
374*b08c3d51SMarkus Hoffrogge	 */
375*b08c3d51SMarkus Hoffrogge	public function commit($message = "", $commit_all = true) {
376*b08c3d51SMarkus Hoffrogge		$flags = $commit_all ? '-av' : '-v';
377*b08c3d51SMarkus Hoffrogge		$msgfile = GitBackedUtil::createMessageFile($message);
378*b08c3d51SMarkus Hoffrogge		try {
379*b08c3d51SMarkus Hoffrogge		  return $this->run("commit --allow-empty ".$flags." --file=".$msgfile);
380*b08c3d51SMarkus Hoffrogge		} finally {
381*b08c3d51SMarkus Hoffrogge		  unlink($msgfile);
382*b08c3d51SMarkus Hoffrogge		}
383*b08c3d51SMarkus Hoffrogge	}
384*b08c3d51SMarkus Hoffrogge
385*b08c3d51SMarkus Hoffrogge	/**
386*b08c3d51SMarkus Hoffrogge	 * Runs a `git clone` call to clone the current repository
387*b08c3d51SMarkus Hoffrogge	 * into a different directory
388*b08c3d51SMarkus Hoffrogge	 *
389*b08c3d51SMarkus Hoffrogge	 * Accepts a target directory
390*b08c3d51SMarkus Hoffrogge	 *
391*b08c3d51SMarkus Hoffrogge	 * @access  public
392*b08c3d51SMarkus Hoffrogge	 * @param   string  target directory
393*b08c3d51SMarkus Hoffrogge	 * @return  string
394*b08c3d51SMarkus Hoffrogge	 */
395*b08c3d51SMarkus Hoffrogge	public function clone_to($target) {
396*b08c3d51SMarkus Hoffrogge		return $this->run("clone --local ".$this->repo_path." $target");
397*b08c3d51SMarkus Hoffrogge	}
398*b08c3d51SMarkus Hoffrogge
399*b08c3d51SMarkus Hoffrogge	/**
400*b08c3d51SMarkus Hoffrogge	 * Runs a `git clone` call to clone a different repository
401*b08c3d51SMarkus Hoffrogge	 * into the current repository
402*b08c3d51SMarkus Hoffrogge	 *
403*b08c3d51SMarkus Hoffrogge	 * Accepts a source directory
404*b08c3d51SMarkus Hoffrogge	 *
405*b08c3d51SMarkus Hoffrogge	 * @access  public
406*b08c3d51SMarkus Hoffrogge	 * @param   string  source directory
407*b08c3d51SMarkus Hoffrogge	 * @return  string
408*b08c3d51SMarkus Hoffrogge	 */
409*b08c3d51SMarkus Hoffrogge	public function clone_from($source) {
410*b08c3d51SMarkus Hoffrogge		return $this->run("clone --local $source ".$this->repo_path);
411*b08c3d51SMarkus Hoffrogge	}
412*b08c3d51SMarkus Hoffrogge
413*b08c3d51SMarkus Hoffrogge	/**
414*b08c3d51SMarkus Hoffrogge	 * Runs a `git clone` call to clone a remote repository
415*b08c3d51SMarkus Hoffrogge	 * into the current repository
416*b08c3d51SMarkus Hoffrogge	 *
417*b08c3d51SMarkus Hoffrogge	 * Accepts a source url
418*b08c3d51SMarkus Hoffrogge	 *
419*b08c3d51SMarkus Hoffrogge	 * @access  public
420*b08c3d51SMarkus Hoffrogge	 * @param   string  source url
421*b08c3d51SMarkus Hoffrogge	 * @param   string  reference path
422*b08c3d51SMarkus Hoffrogge	 * @return  string
423*b08c3d51SMarkus Hoffrogge	 */
424*b08c3d51SMarkus Hoffrogge	public function clone_remote($source, $reference) {
425*b08c3d51SMarkus Hoffrogge		return $this->run("clone $reference $source ".$this->repo_path);
426*b08c3d51SMarkus Hoffrogge	}
427*b08c3d51SMarkus Hoffrogge
428*b08c3d51SMarkus Hoffrogge	/**
429*b08c3d51SMarkus Hoffrogge	 * Runs a `git clean` call
430*b08c3d51SMarkus Hoffrogge	 *
431*b08c3d51SMarkus Hoffrogge	 * Accepts a remove directories flag
432*b08c3d51SMarkus Hoffrogge	 *
433*b08c3d51SMarkus Hoffrogge	 * @access  public
434*b08c3d51SMarkus Hoffrogge	 * @param   bool    delete directories?
435*b08c3d51SMarkus Hoffrogge	 * @param   bool    force clean?
436*b08c3d51SMarkus Hoffrogge	 * @return  string
437*b08c3d51SMarkus Hoffrogge	 */
438*b08c3d51SMarkus Hoffrogge	public function clean($dirs = false, $force = false) {
439*b08c3d51SMarkus Hoffrogge		return $this->run("clean".(($force) ? " -f" : "").(($dirs) ? " -d" : ""));
440*b08c3d51SMarkus Hoffrogge	}
441*b08c3d51SMarkus Hoffrogge
442*b08c3d51SMarkus Hoffrogge	/**
443*b08c3d51SMarkus Hoffrogge	 * Runs a `git branch` call
444*b08c3d51SMarkus Hoffrogge	 *
445*b08c3d51SMarkus Hoffrogge	 * Accepts a name for the branch
446*b08c3d51SMarkus Hoffrogge	 *
447*b08c3d51SMarkus Hoffrogge	 * @access  public
448*b08c3d51SMarkus Hoffrogge	 * @param   string  branch name
449*b08c3d51SMarkus Hoffrogge	 * @return  string
450*b08c3d51SMarkus Hoffrogge	 */
451*b08c3d51SMarkus Hoffrogge	public function create_branch($branch) {
452*b08c3d51SMarkus Hoffrogge		return $this->run("branch $branch");
453*b08c3d51SMarkus Hoffrogge	}
454*b08c3d51SMarkus Hoffrogge
455*b08c3d51SMarkus Hoffrogge	/**
456*b08c3d51SMarkus Hoffrogge	 * Runs a `git branch -[d|D]` call
457*b08c3d51SMarkus Hoffrogge	 *
458*b08c3d51SMarkus Hoffrogge	 * Accepts a name for the branch
459*b08c3d51SMarkus Hoffrogge	 *
460*b08c3d51SMarkus Hoffrogge	 * @access  public
461*b08c3d51SMarkus Hoffrogge	 * @param   string  branch name
462*b08c3d51SMarkus Hoffrogge	 * @return  string
463*b08c3d51SMarkus Hoffrogge	 */
464*b08c3d51SMarkus Hoffrogge	public function delete_branch($branch, $force = false) {
465*b08c3d51SMarkus Hoffrogge		return $this->run("branch ".(($force) ? '-D' : '-d')." $branch");
466*b08c3d51SMarkus Hoffrogge	}
467*b08c3d51SMarkus Hoffrogge
468*b08c3d51SMarkus Hoffrogge	/**
469*b08c3d51SMarkus Hoffrogge	 * Runs a `git branch` call
470*b08c3d51SMarkus Hoffrogge	 *
471*b08c3d51SMarkus Hoffrogge	 * @access  public
472*b08c3d51SMarkus Hoffrogge	 * @param   bool    keep asterisk mark on active branch
473*b08c3d51SMarkus Hoffrogge	 * @return  array
474*b08c3d51SMarkus Hoffrogge	 */
475*b08c3d51SMarkus Hoffrogge	public function list_branches($keep_asterisk = false) {
476*b08c3d51SMarkus Hoffrogge		$branchArray = explode("\n", $this->run("branch"));
477*b08c3d51SMarkus Hoffrogge		foreach($branchArray as $i => &$branch) {
478*b08c3d51SMarkus Hoffrogge			$branch = trim($branch);
479*b08c3d51SMarkus Hoffrogge			if (! $keep_asterisk) {
480*b08c3d51SMarkus Hoffrogge				$branch = str_replace("* ", "", $branch);
481*b08c3d51SMarkus Hoffrogge			}
482*b08c3d51SMarkus Hoffrogge			if ($branch == "") {
483*b08c3d51SMarkus Hoffrogge				unset($branchArray[$i]);
484*b08c3d51SMarkus Hoffrogge			}
485*b08c3d51SMarkus Hoffrogge		}
486*b08c3d51SMarkus Hoffrogge		return $branchArray;
487*b08c3d51SMarkus Hoffrogge	}
488*b08c3d51SMarkus Hoffrogge
489*b08c3d51SMarkus Hoffrogge	/**
490*b08c3d51SMarkus Hoffrogge	 * Lists remote branches (using `git branch -r`).
491*b08c3d51SMarkus Hoffrogge	 *
492*b08c3d51SMarkus Hoffrogge	 * Also strips out the HEAD reference (e.g. "origin/HEAD -> origin/master").
493*b08c3d51SMarkus Hoffrogge	 *
494*b08c3d51SMarkus Hoffrogge	 * @access  public
495*b08c3d51SMarkus Hoffrogge	 * @return  array
496*b08c3d51SMarkus Hoffrogge	 */
497*b08c3d51SMarkus Hoffrogge	public function list_remote_branches() {
498*b08c3d51SMarkus Hoffrogge		$branchArray = explode("\n", $this->run("branch -r"));
499*b08c3d51SMarkus Hoffrogge		foreach($branchArray as $i => &$branch) {
500*b08c3d51SMarkus Hoffrogge			$branch = trim($branch);
501*b08c3d51SMarkus Hoffrogge			if ($branch == "" || strpos($branch, 'HEAD -> ') !== false) {
502*b08c3d51SMarkus Hoffrogge				unset($branchArray[$i]);
503*b08c3d51SMarkus Hoffrogge			}
504*b08c3d51SMarkus Hoffrogge		}
505*b08c3d51SMarkus Hoffrogge		return $branchArray;
506*b08c3d51SMarkus Hoffrogge	}
507*b08c3d51SMarkus Hoffrogge
508*b08c3d51SMarkus Hoffrogge	/**
509*b08c3d51SMarkus Hoffrogge	 * Returns name of active branch
510*b08c3d51SMarkus Hoffrogge	 *
511*b08c3d51SMarkus Hoffrogge	 * @access  public
512*b08c3d51SMarkus Hoffrogge	 * @param   bool    keep asterisk mark on branch name
513*b08c3d51SMarkus Hoffrogge	 * @return  string
514*b08c3d51SMarkus Hoffrogge	 */
515*b08c3d51SMarkus Hoffrogge	public function active_branch($keep_asterisk = false) {
516*b08c3d51SMarkus Hoffrogge		$branchArray = $this->list_branches(true);
517*b08c3d51SMarkus Hoffrogge		$active_branch = preg_grep("/^\*/", $branchArray);
518*b08c3d51SMarkus Hoffrogge		reset($active_branch);
519*b08c3d51SMarkus Hoffrogge		if ($keep_asterisk) {
520*b08c3d51SMarkus Hoffrogge			return current($active_branch);
521*b08c3d51SMarkus Hoffrogge		} else {
522*b08c3d51SMarkus Hoffrogge			return str_replace("* ", "", current($active_branch));
523*b08c3d51SMarkus Hoffrogge		}
524*b08c3d51SMarkus Hoffrogge	}
525*b08c3d51SMarkus Hoffrogge
526*b08c3d51SMarkus Hoffrogge	/**
527*b08c3d51SMarkus Hoffrogge	 * Runs a `git checkout` call
528*b08c3d51SMarkus Hoffrogge	 *
529*b08c3d51SMarkus Hoffrogge	 * Accepts a name for the branch
530*b08c3d51SMarkus Hoffrogge	 *
531*b08c3d51SMarkus Hoffrogge	 * @access  public
532*b08c3d51SMarkus Hoffrogge	 * @param   string  branch name
533*b08c3d51SMarkus Hoffrogge	 * @return  string
534*b08c3d51SMarkus Hoffrogge	 */
535*b08c3d51SMarkus Hoffrogge	public function checkout($branch) {
536*b08c3d51SMarkus Hoffrogge		return $this->run("checkout $branch");
537*b08c3d51SMarkus Hoffrogge	}
538*b08c3d51SMarkus Hoffrogge
539*b08c3d51SMarkus Hoffrogge
540*b08c3d51SMarkus Hoffrogge	/**
541*b08c3d51SMarkus Hoffrogge	 * Runs a `git merge` call
542*b08c3d51SMarkus Hoffrogge	 *
543*b08c3d51SMarkus Hoffrogge	 * Accepts a name for the branch to be merged
544*b08c3d51SMarkus Hoffrogge	 *
545*b08c3d51SMarkus Hoffrogge	 * @access  public
546*b08c3d51SMarkus Hoffrogge	 * @param   string $branch
547*b08c3d51SMarkus Hoffrogge	 * @return  string
548*b08c3d51SMarkus Hoffrogge	 */
549*b08c3d51SMarkus Hoffrogge	public function merge($branch) {
550*b08c3d51SMarkus Hoffrogge		return $this->run("merge $branch --no-ff");
551*b08c3d51SMarkus Hoffrogge	}
552*b08c3d51SMarkus Hoffrogge
553*b08c3d51SMarkus Hoffrogge
554*b08c3d51SMarkus Hoffrogge	/**
555*b08c3d51SMarkus Hoffrogge	 * Runs a git fetch on the current branch
556*b08c3d51SMarkus Hoffrogge	 *
557*b08c3d51SMarkus Hoffrogge	 * @access  public
558*b08c3d51SMarkus Hoffrogge	 * @return  string
559*b08c3d51SMarkus Hoffrogge	 */
560*b08c3d51SMarkus Hoffrogge	public function fetch() {
561*b08c3d51SMarkus Hoffrogge		return $this->run("fetch");
562*b08c3d51SMarkus Hoffrogge	}
563*b08c3d51SMarkus Hoffrogge
564*b08c3d51SMarkus Hoffrogge	/**
565*b08c3d51SMarkus Hoffrogge	 * Add a new tag on the current position
566*b08c3d51SMarkus Hoffrogge	 *
567*b08c3d51SMarkus Hoffrogge	 * Accepts the name for the tag and the message
568*b08c3d51SMarkus Hoffrogge	 *
569*b08c3d51SMarkus Hoffrogge	 * @param string $tag
570*b08c3d51SMarkus Hoffrogge	 * @param string $message
571*b08c3d51SMarkus Hoffrogge	 * @return string
572*b08c3d51SMarkus Hoffrogge	 */
573*b08c3d51SMarkus Hoffrogge	public function add_tag($tag, $message = null) {
574*b08c3d51SMarkus Hoffrogge		if ($message === null) {
575*b08c3d51SMarkus Hoffrogge			$message = $tag;
576*b08c3d51SMarkus Hoffrogge		}
577*b08c3d51SMarkus Hoffrogge		$msgfile = GitBackedUtil::createMessageFile($message);
578*b08c3d51SMarkus Hoffrogge		try {
579*b08c3d51SMarkus Hoffrogge		  return $this->run("tag -a $tag --file=".$msgfile);
580*b08c3d51SMarkus Hoffrogge		} finally {
581*b08c3d51SMarkus Hoffrogge		  unlink($msgfile);
582*b08c3d51SMarkus Hoffrogge		}
583*b08c3d51SMarkus Hoffrogge	}
584*b08c3d51SMarkus Hoffrogge
585*b08c3d51SMarkus Hoffrogge	/**
586*b08c3d51SMarkus Hoffrogge	 * List all the available repository tags.
587*b08c3d51SMarkus Hoffrogge	 *
588*b08c3d51SMarkus Hoffrogge	 * Optionally, accept a shell wildcard pattern and return only tags matching it.
589*b08c3d51SMarkus Hoffrogge	 *
590*b08c3d51SMarkus Hoffrogge	 * @access	public
591*b08c3d51SMarkus Hoffrogge	 * @param	string	$pattern	Shell wildcard pattern to match tags against.
592*b08c3d51SMarkus Hoffrogge	 * @return	array				Available repository tags.
593*b08c3d51SMarkus Hoffrogge	 */
594*b08c3d51SMarkus Hoffrogge	public function list_tags($pattern = null) {
595*b08c3d51SMarkus Hoffrogge		$tagArray = explode("\n", $this->run("tag -l $pattern"));
596*b08c3d51SMarkus Hoffrogge		foreach ($tagArray as $i => &$tag) {
597*b08c3d51SMarkus Hoffrogge			$tag = trim($tag);
598*b08c3d51SMarkus Hoffrogge			if ($tag == '') {
599*b08c3d51SMarkus Hoffrogge				unset($tagArray[$i]);
600*b08c3d51SMarkus Hoffrogge			}
601*b08c3d51SMarkus Hoffrogge		}
602*b08c3d51SMarkus Hoffrogge
603*b08c3d51SMarkus Hoffrogge		return $tagArray;
604*b08c3d51SMarkus Hoffrogge	}
605*b08c3d51SMarkus Hoffrogge
606*b08c3d51SMarkus Hoffrogge	/**
607*b08c3d51SMarkus Hoffrogge	 * Push specific branch to a remote
608*b08c3d51SMarkus Hoffrogge	 *
609*b08c3d51SMarkus Hoffrogge	 * Accepts the name of the remote and local branch
610*b08c3d51SMarkus Hoffrogge	 *
611*b08c3d51SMarkus Hoffrogge	 * @param string $remote
612*b08c3d51SMarkus Hoffrogge	 * @param string $branch
613*b08c3d51SMarkus Hoffrogge	 * @return string
614*b08c3d51SMarkus Hoffrogge	 */
615*b08c3d51SMarkus Hoffrogge	public function push($remote, $branch) {
616*b08c3d51SMarkus Hoffrogge		return $this->run("push --tags $remote $branch");
617*b08c3d51SMarkus Hoffrogge	}
618*b08c3d51SMarkus Hoffrogge
619*b08c3d51SMarkus Hoffrogge	/**
620*b08c3d51SMarkus Hoffrogge	 * Pull specific branch from remote
621*b08c3d51SMarkus Hoffrogge	 *
622*b08c3d51SMarkus Hoffrogge	 * Accepts the name of the remote and local branch
623*b08c3d51SMarkus Hoffrogge	 *
624*b08c3d51SMarkus Hoffrogge	 * @param string $remote
625*b08c3d51SMarkus Hoffrogge	 * @param string $branch
626*b08c3d51SMarkus Hoffrogge	 * @return string
627*b08c3d51SMarkus Hoffrogge	 */
628*b08c3d51SMarkus Hoffrogge	public function pull($remote, $branch) {
629*b08c3d51SMarkus Hoffrogge		return $this->run("pull $remote $branch");
630*b08c3d51SMarkus Hoffrogge	}
631*b08c3d51SMarkus Hoffrogge
632*b08c3d51SMarkus Hoffrogge	/**
633*b08c3d51SMarkus Hoffrogge	 * List log entries.
634*b08c3d51SMarkus Hoffrogge	 *
635*b08c3d51SMarkus Hoffrogge	 * @param strgin $format
636*b08c3d51SMarkus Hoffrogge	 * @return string
637*b08c3d51SMarkus Hoffrogge	 */
638*b08c3d51SMarkus Hoffrogge	public function log($format = null) {
639*b08c3d51SMarkus Hoffrogge		if ($format === null)
640*b08c3d51SMarkus Hoffrogge			return $this->run('log');
641*b08c3d51SMarkus Hoffrogge		else
642*b08c3d51SMarkus Hoffrogge			return $this->run('log --pretty=format:"' . $format . '"');
643*b08c3d51SMarkus Hoffrogge	}
644*b08c3d51SMarkus Hoffrogge
645*b08c3d51SMarkus Hoffrogge	/**
646*b08c3d51SMarkus Hoffrogge	 * Sets the project description.
647*b08c3d51SMarkus Hoffrogge	 *
648*b08c3d51SMarkus Hoffrogge	 * @param string $new
649*b08c3d51SMarkus Hoffrogge	 */
650*b08c3d51SMarkus Hoffrogge	public function set_description($new) {
651*b08c3d51SMarkus Hoffrogge		$path = $this->git_directory_path();
652*b08c3d51SMarkus Hoffrogge		file_put_contents($path."/description", $new);
653*b08c3d51SMarkus Hoffrogge	}
654*b08c3d51SMarkus Hoffrogge
655*b08c3d51SMarkus Hoffrogge	/**
656*b08c3d51SMarkus Hoffrogge	 * Gets the project description.
657*b08c3d51SMarkus Hoffrogge	 *
658*b08c3d51SMarkus Hoffrogge	 * @return string
659*b08c3d51SMarkus Hoffrogge	 */
660*b08c3d51SMarkus Hoffrogge	public function get_description() {
661*b08c3d51SMarkus Hoffrogge		$path = $this->git_directory_path();
662*b08c3d51SMarkus Hoffrogge		return file_get_contents($path."/description");
663*b08c3d51SMarkus Hoffrogge	}
664*b08c3d51SMarkus Hoffrogge
665*b08c3d51SMarkus Hoffrogge	/**
666*b08c3d51SMarkus Hoffrogge	 * Sets custom environment options for calling Git
667*b08c3d51SMarkus Hoffrogge	 *
668*b08c3d51SMarkus Hoffrogge	 * @param string key
669*b08c3d51SMarkus Hoffrogge	 * @param string value
670*b08c3d51SMarkus Hoffrogge	 */
671*b08c3d51SMarkus Hoffrogge	public function setenv($key, $value) {
672*b08c3d51SMarkus Hoffrogge		$this->envopts[$key] = $value;
673*b08c3d51SMarkus Hoffrogge	}
674*b08c3d51SMarkus Hoffrogge
675*b08c3d51SMarkus Hoffrogge}
676*b08c3d51SMarkus Hoffrogge
677*b08c3d51SMarkus Hoffrogge/* End of file */
678