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