xref: /plugin/gitbacked/classes/GitRepo.php (revision c365e7db171e13fc94915621164a0270ac12db2e)
1b08c3d51SMarkus Hoffrogge<?php
2b08c3d51SMarkus Hoffrogge
32762023dSMarkus Hoffroggenamespace woolfg\dokuwiki\plugin\gitbacked;
4b08c3d51SMarkus Hoffrogge
52762023dSMarkus 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 */
162762023dSMarkus Hoffroggeclass GitRepo
172762023dSMarkus 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!
212762023dSMarkus Hoffrogge    public const REGEX_GIT_URL_FILTER_PWD = "/^(.*)((http:)|(https:))([^:]+)(:[^@]*)?(.*)/im";
222762023dSMarkus Hoffrogge    public const REGEX_GIT_URL_FILTER_PWD_REPLACE_PATTERN = "$1$2$5$7";
23b08c3d51SMarkus Hoffrogge
24*c365e7dbSmhoffrog    protected $repo_path;
25b08c3d51SMarkus Hoffrogge    protected $bare = false;
26*c365e7dbSmhoffrog    protected $envopts = [];
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;
29*c365e7dbSmhoffrog    protected $plugin;
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     */
432762023dSMarkus Hoffrogge    public static function &createNew(
442762023dSMarkus Hoffrogge        $repo_path,
452762023dSMarkus Hoffrogge        \action_plugin_gitbacked_editcommit $plugin = null,
462762023dSMarkus Hoffrogge        $source = null,
472762023dSMarkus Hoffrogge        $remote_source = false,
482762023dSMarkus Hoffrogge        $reference = null
492762023dSMarkus Hoffrogge    ) {
50b08c3d51SMarkus Hoffrogge        if (is_dir($repo_path) && file_exists($repo_path . "/.git") && is_dir($repo_path . "/.git")) {
512762023dSMarkus Hoffrogge            throw new \Exception(self::handleCreateNewError(
522762023dSMarkus Hoffrogge                $repo_path,
532762023dSMarkus Hoffrogge                $reference,
542762023dSMarkus Hoffrogge                '"' . $repo_path . '" is already a git repository',
552762023dSMarkus Hoffrogge                $plugin
562762023dSMarkus 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')) {
622762023dSMarkus Hoffrogge                        throw new \Exception(self::handleCreateNewError(
632762023dSMarkus Hoffrogge                            $repo_path,
642762023dSMarkus Hoffrogge                            $reference,
652762023dSMarkus Hoffrogge                            '"' . $reference . '" is not a git repository. Cannot use as reference.',
662762023dSMarkus Hoffrogge                            $plugin
672762023dSMarkus Hoffrogge                        ));
68b08c3d51SMarkus Hoffrogge                    } elseif (strlen($reference)) {
69b08c3d51SMarkus Hoffrogge                        $reference = realpath($reference);
70b08c3d51SMarkus Hoffrogge                        $reference = "--reference $reference";
71b08c3d51SMarkus Hoffrogge                    }
722762023dSMarkus Hoffrogge                    $repo->cloneRemote($source, $reference);
73b08c3d51SMarkus Hoffrogge                } else {
742762023dSMarkus 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     */
942762023dSMarkus Hoffrogge    public function __construct(
952762023dSMarkus Hoffrogge        $repo_path = null,
962762023dSMarkus Hoffrogge        \action_plugin_gitbacked_editcommit $plugin = null,
972762023dSMarkus Hoffrogge        $create_new = false,
982762023dSMarkus Hoffrogge        $_init = true
992762023dSMarkus Hoffrogge    ) {
100b08c3d51SMarkus Hoffrogge        $this->plugin = $plugin;
101b08c3d51SMarkus Hoffrogge        if (is_string($repo_path)) {
1022762023dSMarkus 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     */
1172762023dSMarkus Hoffrogge    public function setRepoPath($repo_path, $create_new = false, $_init = true)
1182762023dSMarkus 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                        }
134*c365e7dbSmhoffrog                    } elseif ($create_new) {
135b08c3d51SMarkus Hoffrogge                        $this->repo_path = $repo_path;
136b08c3d51SMarkus Hoffrogge                        if ($_init) {
137b08c3d51SMarkus Hoffrogge                            $this->run('init');
138b08c3d51SMarkus Hoffrogge                        }
139b08c3d51SMarkus Hoffrogge                    } else {
1402762023dSMarkus Hoffrogge                        throw new \Exception($this->handleRepoPathError(
1412762023dSMarkus Hoffrogge                            $repo_path,
1422762023dSMarkus Hoffrogge                            '"' . $repo_path . '" is not a git repository'
1432762023dSMarkus Hoffrogge                        ));
144b08c3d51SMarkus Hoffrogge                    }
145b08c3d51SMarkus Hoffrogge                } else {
1462762023dSMarkus Hoffrogge                    throw new \Exception($this->handleRepoPathError(
1472762023dSMarkus Hoffrogge                        $repo_path,
1482762023dSMarkus Hoffrogge                        '"' . $repo_path . '" is not a directory'
1492762023dSMarkus Hoffrogge                    ));
150b08c3d51SMarkus Hoffrogge                }
151*c365e7dbSmhoffrog            } elseif ($create_new) {
152b08c3d51SMarkus Hoffrogge                if ($parent = realpath(dirname($repo_path))) {
153b08c3d51SMarkus Hoffrogge                    mkdir($repo_path);
154b08c3d51SMarkus Hoffrogge                    $this->repo_path = $repo_path;
155b08c3d51SMarkus Hoffrogge                    if ($_init) $this->run('init');
156b08c3d51SMarkus Hoffrogge                } else {
1572762023dSMarkus Hoffrogge                    throw new \Exception($this->handleRepoPathError(
1582762023dSMarkus Hoffrogge                        $repo_path,
1592762023dSMarkus Hoffrogge                        'cannot create repository in non-existent directory'
1602762023dSMarkus Hoffrogge                    ));
161b08c3d51SMarkus Hoffrogge                }
162b08c3d51SMarkus Hoffrogge            } else {
1632762023dSMarkus Hoffrogge                throw new \Exception($this->handleRepoPathError(
1642762023dSMarkus Hoffrogge                    $repo_path,
1652762023dSMarkus Hoffrogge                    '"' . $repo_path . '" does not exist'
1662762023dSMarkus Hoffrogge                ));
167b08c3d51SMarkus Hoffrogge            }
168b08c3d51SMarkus Hoffrogge        }
169b08c3d51SMarkus Hoffrogge    }
170b08c3d51SMarkus Hoffrogge
171b08c3d51SMarkus Hoffrogge    /**
172b08c3d51SMarkus Hoffrogge     * Get the path to the git repo directory (eg. the ".git" directory)
173b08c3d51SMarkus Hoffrogge     *
174b08c3d51SMarkus Hoffrogge     * @access public
175b08c3d51SMarkus Hoffrogge     * @return string
176b08c3d51SMarkus Hoffrogge     */
1772762023dSMarkus Hoffrogge    public function gitDirectoryPath()
1782762023dSMarkus Hoffrogge    {
179b08c3d51SMarkus Hoffrogge        return ($this->bare) ? $this->repo_path : $this->repo_path . "/.git";
180b08c3d51SMarkus Hoffrogge    }
181b08c3d51SMarkus Hoffrogge
182b08c3d51SMarkus Hoffrogge    /**
183b08c3d51SMarkus Hoffrogge     * Tests if git is installed
184b08c3d51SMarkus Hoffrogge     *
185b08c3d51SMarkus Hoffrogge     * @access  public
186b08c3d51SMarkus Hoffrogge     * @return  bool
187b08c3d51SMarkus Hoffrogge     */
1882762023dSMarkus Hoffrogge    public function testGit()
1892762023dSMarkus Hoffrogge    {
190*c365e7dbSmhoffrog        $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
191*c365e7dbSmhoffrog        $pipes = [];
1922762023dSMarkus Hoffrogge        $resource = proc_open(Git::getBin(), $descriptorspec, $pipes);
193b08c3d51SMarkus Hoffrogge
194*c365e7dbSmhoffrog        stream_get_contents($pipes[1]);
195*c365e7dbSmhoffrog        stream_get_contents($pipes[2]);
196b08c3d51SMarkus Hoffrogge        foreach ($pipes as $pipe) {
197b08c3d51SMarkus Hoffrogge            fclose($pipe);
198b08c3d51SMarkus Hoffrogge        }
199b08c3d51SMarkus Hoffrogge
200b08c3d51SMarkus Hoffrogge        $status = trim(proc_close($resource));
201b08c3d51SMarkus Hoffrogge        return ($status != 127);
202b08c3d51SMarkus Hoffrogge    }
203b08c3d51SMarkus Hoffrogge
204b08c3d51SMarkus Hoffrogge    /**
205b08c3d51SMarkus Hoffrogge     * Run a command in the git repository
206b08c3d51SMarkus Hoffrogge     *
207b08c3d51SMarkus Hoffrogge     * Accepts a shell command to run
208b08c3d51SMarkus Hoffrogge     *
209b08c3d51SMarkus Hoffrogge     * @access  protected
210b08c3d51SMarkus Hoffrogge     * @param   string  command to run
211b08c3d51SMarkus Hoffrogge     * @return  string  or null in case of an error
212b08c3d51SMarkus Hoffrogge     */
2132762023dSMarkus Hoffrogge    protected function runCommand($command)
2142762023dSMarkus Hoffrogge    {
2152762023dSMarkus Hoffrogge        //dbglog("Git->runCommand(command=[".$command."])");
216*c365e7dbSmhoffrog        $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
217*c365e7dbSmhoffrog        $pipes = [];
218b08c3d51SMarkus Hoffrogge        $cwd = $this->repo_path;
219b08c3d51SMarkus Hoffrogge        //dbglog("GitBacked - cwd: [".$cwd."]");
220b08c3d51SMarkus Hoffrogge        /* Provide any $this->envopts via putenv
221b08c3d51SMarkus Hoffrogge         * and call proc_open with env=null to inherit the rest
222b08c3d51SMarkus Hoffrogge         * of env variables from the original process of the system.
223b08c3d51SMarkus Hoffrogge         * Note: Variables set by putenv live for a
224b08c3d51SMarkus Hoffrogge         * single PHP request run only. These variables
225b08c3d51SMarkus Hoffrogge         * are visible "locally". They are NOT listed by getenv(),
226b08c3d51SMarkus Hoffrogge         * but they are visible to the process forked by proc_open().
227b08c3d51SMarkus Hoffrogge         */
228b08c3d51SMarkus Hoffrogge        foreach ($this->envopts as $k => $v) {
229b08c3d51SMarkus Hoffrogge            putenv(sprintf("%s=%s", $k, $v));
230b08c3d51SMarkus Hoffrogge        }
231b08c3d51SMarkus Hoffrogge        $resource = proc_open($command, $descriptorspec, $pipes, $cwd, null);
232b08c3d51SMarkus Hoffrogge
233b08c3d51SMarkus Hoffrogge        $stdout = stream_get_contents($pipes[1]);
234b08c3d51SMarkus Hoffrogge        $stderr = stream_get_contents($pipes[2]);
235b08c3d51SMarkus Hoffrogge        foreach ($pipes as $pipe) {
236b08c3d51SMarkus Hoffrogge            fclose($pipe);
237b08c3d51SMarkus Hoffrogge        }
238b08c3d51SMarkus Hoffrogge
239b08c3d51SMarkus Hoffrogge        $status = trim(proc_close($resource));
2402762023dSMarkus Hoffrogge        //dbglog("GitBacked: runCommand status: ".$status);
241b08c3d51SMarkus Hoffrogge        if ($status) {
242b08c3d51SMarkus Hoffrogge            //dbglog("GitBacked - stderr: [".$stderr."]");
243b08c3d51SMarkus Hoffrogge            // Remove a probable password from the Git URL, if the URL is contained in the error message
2442762023dSMarkus Hoffrogge            $error_message = preg_replace(
2452762023dSMarkus Hoffrogge                $this::REGEX_GIT_URL_FILTER_PWD,
2462762023dSMarkus Hoffrogge                $this::REGEX_GIT_URL_FILTER_PWD_REPLACE_PATTERN,
2472762023dSMarkus Hoffrogge                $stderr
2482762023dSMarkus Hoffrogge            );
249b08c3d51SMarkus Hoffrogge            //dbglog("GitBacked - error_message: [".$error_message."]");
2502762023dSMarkus Hoffrogge            throw new \Exception($this->handleCommandError(
2512762023dSMarkus Hoffrogge                $this->repo_path,
2522762023dSMarkus Hoffrogge                $cwd,
2532762023dSMarkus Hoffrogge                $command,
2542762023dSMarkus Hoffrogge                $status,
2552762023dSMarkus Hoffrogge                $error_message
2562762023dSMarkus Hoffrogge            ));
257b08c3d51SMarkus Hoffrogge        } else {
2582762023dSMarkus Hoffrogge            $this->handleCommandSuccess($this->repo_path, $cwd, $command);
259b08c3d51SMarkus Hoffrogge        }
260b08c3d51SMarkus Hoffrogge
261b08c3d51SMarkus Hoffrogge        return $stdout;
262b08c3d51SMarkus Hoffrogge    }
263b08c3d51SMarkus Hoffrogge
264b08c3d51SMarkus Hoffrogge    /**
265b08c3d51SMarkus Hoffrogge     * Run a git command in the git repository
266b08c3d51SMarkus Hoffrogge     *
267b08c3d51SMarkus Hoffrogge     * Accepts a git command to run
268b08c3d51SMarkus Hoffrogge     *
269b08c3d51SMarkus Hoffrogge     * @access  public
270b08c3d51SMarkus Hoffrogge     * @param   string  command to run
271b08c3d51SMarkus Hoffrogge     * @return  string
272b08c3d51SMarkus Hoffrogge     */
2732762023dSMarkus Hoffrogge    public function run($command)
2742762023dSMarkus Hoffrogge    {
2752762023dSMarkus Hoffrogge        return $this->runCommand(Git::getBin() . " " . $command);
276b08c3d51SMarkus Hoffrogge    }
277b08c3d51SMarkus Hoffrogge
278b08c3d51SMarkus Hoffrogge    /**
279b08c3d51SMarkus Hoffrogge     * Handles error on create_new
280b08c3d51SMarkus Hoffrogge     *
281b08c3d51SMarkus Hoffrogge     * @access  protected
282b08c3d51SMarkus Hoffrogge     * @param   string  repository path
283b08c3d51SMarkus Hoffrogge     * @param   string  error message
284b08c3d51SMarkus Hoffrogge     * @return  string  error message
285b08c3d51SMarkus Hoffrogge     */
2862762023dSMarkus Hoffrogge    protected static function handleCreateNewError($repo_path, $reference, $error_message, $plugin)
2872762023dSMarkus Hoffrogge    {
288b08c3d51SMarkus Hoffrogge        if ($plugin instanceof \action_plugin_gitbacked_editcommit) {
2892762023dSMarkus Hoffrogge            $plugin->notifyCreateNewError($repo_path, $reference, $error_message);
290b08c3d51SMarkus Hoffrogge        }
291b08c3d51SMarkus Hoffrogge        return $error_message;
292b08c3d51SMarkus Hoffrogge    }
293b08c3d51SMarkus Hoffrogge
294b08c3d51SMarkus Hoffrogge    /**
295b08c3d51SMarkus Hoffrogge     * Handles error on setting the repo path
296b08c3d51SMarkus Hoffrogge     *
297b08c3d51SMarkus Hoffrogge     * @access  protected
298b08c3d51SMarkus Hoffrogge     * @param   string  repository path
299b08c3d51SMarkus Hoffrogge     * @param   string  error message
300b08c3d51SMarkus Hoffrogge     * @return  string  error message
301b08c3d51SMarkus Hoffrogge     */
3022762023dSMarkus Hoffrogge    protected function handleRepoPathError($repo_path, $error_message)
3032762023dSMarkus Hoffrogge    {
304b08c3d51SMarkus Hoffrogge        if ($this->plugin instanceof \action_plugin_gitbacked_editcommit) {
3052762023dSMarkus Hoffrogge            $this->plugin->notifyRepoPathError($repo_path, $error_message);
306b08c3d51SMarkus Hoffrogge        }
307b08c3d51SMarkus Hoffrogge        return $error_message;
308b08c3d51SMarkus Hoffrogge    }
309b08c3d51SMarkus Hoffrogge
310b08c3d51SMarkus Hoffrogge    /**
311b08c3d51SMarkus Hoffrogge     * Handles error on git command
312b08c3d51SMarkus Hoffrogge     *
313b08c3d51SMarkus Hoffrogge     * @access  protected
314b08c3d51SMarkus Hoffrogge     * @param   string  repository path
315b08c3d51SMarkus Hoffrogge     * @param   string  current working dir
316b08c3d51SMarkus Hoffrogge     * @param   string  command line
317b08c3d51SMarkus Hoffrogge     * @param   int     exit code of command (status)
318b08c3d51SMarkus Hoffrogge     * @param   string  error message
319b08c3d51SMarkus Hoffrogge     * @return  string  error message
320b08c3d51SMarkus Hoffrogge     */
3212762023dSMarkus Hoffrogge    protected function handleCommandError($repo_path, $cwd, $command, $status, $error_message)
3222762023dSMarkus Hoffrogge    {
323b08c3d51SMarkus Hoffrogge        if ($this->plugin instanceof \action_plugin_gitbacked_editcommit) {
3242762023dSMarkus Hoffrogge            $this->plugin->notifyCommandError($repo_path, $cwd, $command, $status, $error_message);
325b08c3d51SMarkus Hoffrogge        }
326b08c3d51SMarkus Hoffrogge        return $error_message;
327b08c3d51SMarkus Hoffrogge    }
328b08c3d51SMarkus Hoffrogge
329b08c3d51SMarkus Hoffrogge    /**
330b08c3d51SMarkus Hoffrogge     * Handles success on git command
331b08c3d51SMarkus Hoffrogge     *
332b08c3d51SMarkus Hoffrogge     * @access  protected
333b08c3d51SMarkus Hoffrogge     * @param   string  repository path
334b08c3d51SMarkus Hoffrogge     * @param   string  current working dir
335b08c3d51SMarkus Hoffrogge     * @param   string  command line
336b08c3d51SMarkus Hoffrogge     * @return  void
337b08c3d51SMarkus Hoffrogge     */
3382762023dSMarkus Hoffrogge    protected function handleCommandSuccess($repo_path, $cwd, $command)
3392762023dSMarkus Hoffrogge    {
340b08c3d51SMarkus Hoffrogge        if ($this->plugin instanceof \action_plugin_gitbacked_editcommit) {
3412762023dSMarkus Hoffrogge            $this->plugin->notifyCommandSuccess($repo_path, $cwd, $command);
342b08c3d51SMarkus Hoffrogge        }
343b08c3d51SMarkus Hoffrogge    }
344b08c3d51SMarkus Hoffrogge
345b08c3d51SMarkus Hoffrogge    /**
346b08c3d51SMarkus Hoffrogge     * Runs a 'git status' call
347b08c3d51SMarkus Hoffrogge     *
348b08c3d51SMarkus Hoffrogge     * Accept a convert to HTML bool
349b08c3d51SMarkus Hoffrogge     *
350b08c3d51SMarkus Hoffrogge     * @access public
351b08c3d51SMarkus Hoffrogge     * @param bool  return string with <br />
352b08c3d51SMarkus Hoffrogge     * @return string
353b08c3d51SMarkus Hoffrogge     */
3542762023dSMarkus Hoffrogge    public function status($html = false)
3552762023dSMarkus Hoffrogge    {
356b08c3d51SMarkus Hoffrogge        $msg = $this->run("status");
357b08c3d51SMarkus Hoffrogge        if ($html == true) {
358b08c3d51SMarkus Hoffrogge            $msg = str_replace("\n", "<br />", $msg);
359b08c3d51SMarkus Hoffrogge        }
360b08c3d51SMarkus Hoffrogge        return $msg;
361b08c3d51SMarkus Hoffrogge    }
362b08c3d51SMarkus Hoffrogge
363b08c3d51SMarkus Hoffrogge    /**
364b08c3d51SMarkus Hoffrogge     * Runs a `git add` call
365b08c3d51SMarkus Hoffrogge     *
366b08c3d51SMarkus Hoffrogge     * Accepts a list of files to add
367b08c3d51SMarkus Hoffrogge     *
368b08c3d51SMarkus Hoffrogge     * @access  public
369b08c3d51SMarkus Hoffrogge     * @param   mixed   files to add
370b08c3d51SMarkus Hoffrogge     * @return  string
371b08c3d51SMarkus Hoffrogge     */
3722762023dSMarkus Hoffrogge    public function add($files = "*")
3732762023dSMarkus Hoffrogge    {
374b08c3d51SMarkus Hoffrogge        if (is_array($files)) {
375b08c3d51SMarkus Hoffrogge            $files = '"' . implode('" "', $files) . '"';
376b08c3d51SMarkus Hoffrogge        }
377b08c3d51SMarkus Hoffrogge        return $this->run("add $files -v");
378b08c3d51SMarkus Hoffrogge    }
379b08c3d51SMarkus Hoffrogge
380b08c3d51SMarkus Hoffrogge    /**
381b08c3d51SMarkus Hoffrogge     * Runs a `git rm` call
382b08c3d51SMarkus Hoffrogge     *
383b08c3d51SMarkus Hoffrogge     * Accepts a list of files to remove
384b08c3d51SMarkus Hoffrogge     *
385b08c3d51SMarkus Hoffrogge     * @access  public
386b08c3d51SMarkus Hoffrogge     * @param   mixed    files to remove
387b08c3d51SMarkus Hoffrogge     * @param   Boolean  use the --cached flag?
388b08c3d51SMarkus Hoffrogge     * @return  string
389b08c3d51SMarkus Hoffrogge     */
3902762023dSMarkus Hoffrogge    public function rm($files = "*", $cached = false)
3912762023dSMarkus Hoffrogge    {
392b08c3d51SMarkus Hoffrogge        if (is_array($files)) {
393b08c3d51SMarkus Hoffrogge            $files = '"' . implode('" "', $files) . '"';
394b08c3d51SMarkus Hoffrogge        }
395b08c3d51SMarkus Hoffrogge        return $this->run("rm " . ($cached ? '--cached ' : '') . $files);
396b08c3d51SMarkus Hoffrogge    }
397b08c3d51SMarkus Hoffrogge
398b08c3d51SMarkus Hoffrogge
399b08c3d51SMarkus Hoffrogge    /**
400b08c3d51SMarkus Hoffrogge     * Runs a `git commit` call
401b08c3d51SMarkus Hoffrogge     *
402b08c3d51SMarkus Hoffrogge     * Accepts a commit message string
403b08c3d51SMarkus Hoffrogge     *
404b08c3d51SMarkus Hoffrogge     * @access  public
405b08c3d51SMarkus Hoffrogge     * @param   string  commit message
406b08c3d51SMarkus Hoffrogge     * @param   boolean  should all files be committed automatically (-a flag)
407b08c3d51SMarkus Hoffrogge     * @return  string
408b08c3d51SMarkus Hoffrogge     */
4092762023dSMarkus Hoffrogge    public function commit($message = "", $commit_all = true)
4102762023dSMarkus Hoffrogge    {
411b08c3d51SMarkus Hoffrogge        $flags = $commit_all ? '-av' : '-v';
412b08c3d51SMarkus Hoffrogge        $msgfile = GitBackedUtil::createMessageFile($message);
413b08c3d51SMarkus Hoffrogge        try {
414b08c3d51SMarkus Hoffrogge            return $this->run("commit --allow-empty " . $flags . " --file=" . $msgfile);
415b08c3d51SMarkus Hoffrogge        } finally {
416b08c3d51SMarkus Hoffrogge            unlink($msgfile);
417b08c3d51SMarkus Hoffrogge        }
418b08c3d51SMarkus Hoffrogge    }
419b08c3d51SMarkus Hoffrogge
420b08c3d51SMarkus Hoffrogge    /**
421b08c3d51SMarkus Hoffrogge     * Runs a `git clone` call to clone the current repository
422b08c3d51SMarkus Hoffrogge     * into a different directory
423b08c3d51SMarkus Hoffrogge     *
424b08c3d51SMarkus Hoffrogge     * Accepts a target directory
425b08c3d51SMarkus Hoffrogge     *
426b08c3d51SMarkus Hoffrogge     * @access  public
427b08c3d51SMarkus Hoffrogge     * @param   string  target directory
428b08c3d51SMarkus Hoffrogge     * @return  string
429b08c3d51SMarkus Hoffrogge     */
4302762023dSMarkus Hoffrogge    public function cloneTo($target)
4312762023dSMarkus Hoffrogge    {
432b08c3d51SMarkus Hoffrogge        return $this->run("clone --local " . $this->repo_path . " $target");
433b08c3d51SMarkus Hoffrogge    }
434b08c3d51SMarkus Hoffrogge
435b08c3d51SMarkus Hoffrogge    /**
436b08c3d51SMarkus Hoffrogge     * Runs a `git clone` call to clone a different repository
437b08c3d51SMarkus Hoffrogge     * into the current repository
438b08c3d51SMarkus Hoffrogge     *
439b08c3d51SMarkus Hoffrogge     * Accepts a source directory
440b08c3d51SMarkus Hoffrogge     *
441b08c3d51SMarkus Hoffrogge     * @access  public
442b08c3d51SMarkus Hoffrogge     * @param   string  source directory
443b08c3d51SMarkus Hoffrogge     * @return  string
444b08c3d51SMarkus Hoffrogge     */
4452762023dSMarkus Hoffrogge    public function cloneFrom($source)
4462762023dSMarkus Hoffrogge    {
447b08c3d51SMarkus Hoffrogge        return $this->run("clone --local $source " . $this->repo_path);
448b08c3d51SMarkus Hoffrogge    }
449b08c3d51SMarkus Hoffrogge
450b08c3d51SMarkus Hoffrogge    /**
451b08c3d51SMarkus Hoffrogge     * Runs a `git clone` call to clone a remote repository
452b08c3d51SMarkus Hoffrogge     * into the current repository
453b08c3d51SMarkus Hoffrogge     *
454b08c3d51SMarkus Hoffrogge     * Accepts a source url
455b08c3d51SMarkus Hoffrogge     *
456b08c3d51SMarkus Hoffrogge     * @access  public
457b08c3d51SMarkus Hoffrogge     * @param   string  source url
458b08c3d51SMarkus Hoffrogge     * @param   string  reference path
459b08c3d51SMarkus Hoffrogge     * @return  string
460b08c3d51SMarkus Hoffrogge     */
4612762023dSMarkus Hoffrogge    public function cloneRemote($source, $reference)
4622762023dSMarkus Hoffrogge    {
463b08c3d51SMarkus Hoffrogge        return $this->run("clone $reference $source " . $this->repo_path);
464b08c3d51SMarkus Hoffrogge    }
465b08c3d51SMarkus Hoffrogge
466b08c3d51SMarkus Hoffrogge    /**
467b08c3d51SMarkus Hoffrogge     * Runs a `git clean` call
468b08c3d51SMarkus Hoffrogge     *
469b08c3d51SMarkus Hoffrogge     * Accepts a remove directories flag
470b08c3d51SMarkus Hoffrogge     *
471b08c3d51SMarkus Hoffrogge     * @access  public
472b08c3d51SMarkus Hoffrogge     * @param   bool    delete directories?
473b08c3d51SMarkus Hoffrogge     * @param   bool    force clean?
474b08c3d51SMarkus Hoffrogge     * @return  string
475b08c3d51SMarkus Hoffrogge     */
4762762023dSMarkus Hoffrogge    public function clean($dirs = false, $force = false)
4772762023dSMarkus Hoffrogge    {
478b08c3d51SMarkus Hoffrogge        return $this->run("clean" . (($force) ? " -f" : "") . (($dirs) ? " -d" : ""));
479b08c3d51SMarkus Hoffrogge    }
480b08c3d51SMarkus Hoffrogge
481b08c3d51SMarkus Hoffrogge    /**
482b08c3d51SMarkus Hoffrogge     * Runs a `git branch` call
483b08c3d51SMarkus Hoffrogge     *
484b08c3d51SMarkus Hoffrogge     * Accepts a name for the branch
485b08c3d51SMarkus Hoffrogge     *
486b08c3d51SMarkus Hoffrogge     * @access  public
487b08c3d51SMarkus Hoffrogge     * @param   string  branch name
488b08c3d51SMarkus Hoffrogge     * @return  string
489b08c3d51SMarkus Hoffrogge     */
4902762023dSMarkus Hoffrogge    public function createBranch($branch)
4912762023dSMarkus Hoffrogge    {
492b08c3d51SMarkus Hoffrogge        return $this->run("branch $branch");
493b08c3d51SMarkus Hoffrogge    }
494b08c3d51SMarkus Hoffrogge
495b08c3d51SMarkus Hoffrogge    /**
496b08c3d51SMarkus Hoffrogge     * Runs a `git branch -[d|D]` call
497b08c3d51SMarkus Hoffrogge     *
498b08c3d51SMarkus Hoffrogge     * Accepts a name for the branch
499b08c3d51SMarkus Hoffrogge     *
500b08c3d51SMarkus Hoffrogge     * @access  public
501b08c3d51SMarkus Hoffrogge     * @param   string  branch name
502b08c3d51SMarkus Hoffrogge     * @return  string
503b08c3d51SMarkus Hoffrogge     */
5042762023dSMarkus Hoffrogge    public function deleteBranch($branch, $force = false)
5052762023dSMarkus Hoffrogge    {
506b08c3d51SMarkus Hoffrogge        return $this->run("branch " . (($force) ? '-D' : '-d') . " $branch");
507b08c3d51SMarkus Hoffrogge    }
508b08c3d51SMarkus Hoffrogge
509b08c3d51SMarkus Hoffrogge    /**
510b08c3d51SMarkus Hoffrogge     * Runs a `git branch` call
511b08c3d51SMarkus Hoffrogge     *
512b08c3d51SMarkus Hoffrogge     * @access  public
513b08c3d51SMarkus Hoffrogge     * @param   bool    keep asterisk mark on active branch
514b08c3d51SMarkus Hoffrogge     * @return  array
515b08c3d51SMarkus Hoffrogge     */
5162762023dSMarkus Hoffrogge    public function listBranches($keep_asterisk = false)
5172762023dSMarkus Hoffrogge    {
518b08c3d51SMarkus Hoffrogge        $branchArray = explode("\n", $this->run("branch"));
519b08c3d51SMarkus Hoffrogge        foreach ($branchArray as $i => &$branch) {
520b08c3d51SMarkus Hoffrogge            $branch = trim($branch);
521b08c3d51SMarkus Hoffrogge            if (! $keep_asterisk) {
522b08c3d51SMarkus Hoffrogge                $branch = str_replace("* ", "", $branch);
523b08c3d51SMarkus Hoffrogge            }
524b08c3d51SMarkus Hoffrogge            if ($branch == "") {
525b08c3d51SMarkus Hoffrogge                unset($branchArray[$i]);
526b08c3d51SMarkus Hoffrogge            }
527b08c3d51SMarkus Hoffrogge        }
528b08c3d51SMarkus Hoffrogge        return $branchArray;
529b08c3d51SMarkus Hoffrogge    }
530b08c3d51SMarkus Hoffrogge
531b08c3d51SMarkus Hoffrogge    /**
532b08c3d51SMarkus Hoffrogge     * Lists remote branches (using `git branch -r`).
533b08c3d51SMarkus Hoffrogge     *
534b08c3d51SMarkus Hoffrogge     * Also strips out the HEAD reference (e.g. "origin/HEAD -> origin/master").
535b08c3d51SMarkus Hoffrogge     *
536b08c3d51SMarkus Hoffrogge     * @access  public
537b08c3d51SMarkus Hoffrogge     * @return  array
538b08c3d51SMarkus Hoffrogge     */
5392762023dSMarkus Hoffrogge    public function listRemoteBranches()
5402762023dSMarkus Hoffrogge    {
541b08c3d51SMarkus Hoffrogge        $branchArray = explode("\n", $this->run("branch -r"));
542b08c3d51SMarkus Hoffrogge        foreach ($branchArray as $i => &$branch) {
543b08c3d51SMarkus Hoffrogge            $branch = trim($branch);
544b08c3d51SMarkus Hoffrogge            if ($branch == "" || strpos($branch, 'HEAD -> ') !== false) {
545b08c3d51SMarkus Hoffrogge                unset($branchArray[$i]);
546b08c3d51SMarkus Hoffrogge            }
547b08c3d51SMarkus Hoffrogge        }
548b08c3d51SMarkus Hoffrogge        return $branchArray;
549b08c3d51SMarkus Hoffrogge    }
550b08c3d51SMarkus Hoffrogge
551b08c3d51SMarkus Hoffrogge    /**
552b08c3d51SMarkus Hoffrogge     * Returns name of active branch
553b08c3d51SMarkus Hoffrogge     *
554b08c3d51SMarkus Hoffrogge     * @access  public
555b08c3d51SMarkus Hoffrogge     * @param   bool    keep asterisk mark on branch name
556b08c3d51SMarkus Hoffrogge     * @return  string
557b08c3d51SMarkus Hoffrogge     */
5582762023dSMarkus Hoffrogge    public function activeBranch($keep_asterisk = false)
5592762023dSMarkus Hoffrogge    {
5602762023dSMarkus Hoffrogge        $branchArray = $this->listBranches(true);
5612762023dSMarkus Hoffrogge        $activeBranch = preg_grep("/^\*/", $branchArray);
5622762023dSMarkus Hoffrogge        reset($activeBranch);
563b08c3d51SMarkus Hoffrogge        if ($keep_asterisk) {
5642762023dSMarkus Hoffrogge            return current($activeBranch);
565b08c3d51SMarkus Hoffrogge        } else {
5662762023dSMarkus Hoffrogge            return str_replace("* ", "", current($activeBranch));
567b08c3d51SMarkus Hoffrogge        }
568b08c3d51SMarkus Hoffrogge    }
569b08c3d51SMarkus Hoffrogge
570b08c3d51SMarkus Hoffrogge    /**
571b08c3d51SMarkus Hoffrogge     * Runs a `git checkout` call
572b08c3d51SMarkus Hoffrogge     *
573b08c3d51SMarkus Hoffrogge     * Accepts a name for the branch
574b08c3d51SMarkus Hoffrogge     *
575b08c3d51SMarkus Hoffrogge     * @access  public
576b08c3d51SMarkus Hoffrogge     * @param   string  branch name
577b08c3d51SMarkus Hoffrogge     * @return  string
578b08c3d51SMarkus Hoffrogge     */
5792762023dSMarkus Hoffrogge    public function checkout($branch)
5802762023dSMarkus Hoffrogge    {
581b08c3d51SMarkus Hoffrogge        return $this->run("checkout $branch");
582b08c3d51SMarkus Hoffrogge    }
583b08c3d51SMarkus Hoffrogge
584b08c3d51SMarkus Hoffrogge
585b08c3d51SMarkus Hoffrogge    /**
586b08c3d51SMarkus Hoffrogge     * Runs a `git merge` call
587b08c3d51SMarkus Hoffrogge     *
588b08c3d51SMarkus Hoffrogge     * Accepts a name for the branch to be merged
589b08c3d51SMarkus Hoffrogge     *
590b08c3d51SMarkus Hoffrogge     * @access  public
591b08c3d51SMarkus Hoffrogge     * @param   string $branch
592b08c3d51SMarkus Hoffrogge     * @return  string
593b08c3d51SMarkus Hoffrogge     */
5942762023dSMarkus Hoffrogge    public function merge($branch)
5952762023dSMarkus Hoffrogge    {
596b08c3d51SMarkus Hoffrogge        return $this->run("merge $branch --no-ff");
597b08c3d51SMarkus Hoffrogge    }
598b08c3d51SMarkus Hoffrogge
599b08c3d51SMarkus Hoffrogge
600b08c3d51SMarkus Hoffrogge    /**
601b08c3d51SMarkus Hoffrogge     * Runs a git fetch on the current branch
602b08c3d51SMarkus Hoffrogge     *
603b08c3d51SMarkus Hoffrogge     * @access  public
604b08c3d51SMarkus Hoffrogge     * @return  string
605b08c3d51SMarkus Hoffrogge     */
6062762023dSMarkus Hoffrogge    public function fetch()
6072762023dSMarkus Hoffrogge    {
608b08c3d51SMarkus Hoffrogge        return $this->run("fetch");
609b08c3d51SMarkus Hoffrogge    }
610b08c3d51SMarkus Hoffrogge
611b08c3d51SMarkus Hoffrogge    /**
612b08c3d51SMarkus Hoffrogge     * Add a new tag on the current position
613b08c3d51SMarkus Hoffrogge     *
614b08c3d51SMarkus Hoffrogge     * Accepts the name for the tag and the message
615b08c3d51SMarkus Hoffrogge     *
616b08c3d51SMarkus Hoffrogge     * @param string $tag
617b08c3d51SMarkus Hoffrogge     * @param string $message
618b08c3d51SMarkus Hoffrogge     * @return string
619b08c3d51SMarkus Hoffrogge     */
6202762023dSMarkus Hoffrogge    public function addTag($tag, $message = null)
6212762023dSMarkus Hoffrogge    {
622b08c3d51SMarkus Hoffrogge        if ($message === null) {
623b08c3d51SMarkus Hoffrogge            $message = $tag;
624b08c3d51SMarkus Hoffrogge        }
625b08c3d51SMarkus Hoffrogge        $msgfile = GitBackedUtil::createMessageFile($message);
626b08c3d51SMarkus Hoffrogge        try {
627b08c3d51SMarkus Hoffrogge            return $this->run("tag -a $tag --file=" . $msgfile);
628b08c3d51SMarkus Hoffrogge        } finally {
629b08c3d51SMarkus Hoffrogge            unlink($msgfile);
630b08c3d51SMarkus Hoffrogge        }
631b08c3d51SMarkus Hoffrogge    }
632b08c3d51SMarkus Hoffrogge
633b08c3d51SMarkus Hoffrogge    /**
634b08c3d51SMarkus Hoffrogge     * List all the available repository tags.
635b08c3d51SMarkus Hoffrogge     *
636b08c3d51SMarkus Hoffrogge     * Optionally, accept a shell wildcard pattern and return only tags matching it.
637b08c3d51SMarkus Hoffrogge     *
638b08c3d51SMarkus Hoffrogge     * @access  public
639b08c3d51SMarkus Hoffrogge     * @param   string $pattern Shell wildcard pattern to match tags against.
640b08c3d51SMarkus Hoffrogge     * @return  array           Available repository tags.
641b08c3d51SMarkus Hoffrogge     */
6422762023dSMarkus Hoffrogge    public function listTags($pattern = null)
6432762023dSMarkus Hoffrogge    {
644b08c3d51SMarkus Hoffrogge        $tagArray = explode("\n", $this->run("tag -l $pattern"));
645b08c3d51SMarkus Hoffrogge        foreach ($tagArray as $i => &$tag) {
646b08c3d51SMarkus Hoffrogge            $tag = trim($tag);
647b08c3d51SMarkus Hoffrogge            if ($tag == '') {
648b08c3d51SMarkus Hoffrogge                unset($tagArray[$i]);
649b08c3d51SMarkus Hoffrogge            }
650b08c3d51SMarkus Hoffrogge        }
651b08c3d51SMarkus Hoffrogge
652b08c3d51SMarkus Hoffrogge        return $tagArray;
653b08c3d51SMarkus Hoffrogge    }
654b08c3d51SMarkus Hoffrogge
655b08c3d51SMarkus Hoffrogge    /**
656b08c3d51SMarkus Hoffrogge     * Push specific branch to a remote
657b08c3d51SMarkus Hoffrogge     *
658b08c3d51SMarkus Hoffrogge     * Accepts the name of the remote and local branch
659b08c3d51SMarkus Hoffrogge     *
660b08c3d51SMarkus Hoffrogge     * @param string $remote
661b08c3d51SMarkus Hoffrogge     * @param string $branch
662b08c3d51SMarkus Hoffrogge     * @return string
663b08c3d51SMarkus Hoffrogge     */
6642762023dSMarkus Hoffrogge    public function push($remote, $branch)
6652762023dSMarkus Hoffrogge    {
666b08c3d51SMarkus Hoffrogge        return $this->run("push --tags $remote $branch");
667b08c3d51SMarkus Hoffrogge    }
668b08c3d51SMarkus Hoffrogge
669b08c3d51SMarkus Hoffrogge    /**
670b08c3d51SMarkus Hoffrogge     * Pull specific branch from remote
671b08c3d51SMarkus Hoffrogge     *
672b08c3d51SMarkus Hoffrogge     * Accepts the name of the remote and local branch
673b08c3d51SMarkus Hoffrogge     *
674b08c3d51SMarkus Hoffrogge     * @param string $remote
675b08c3d51SMarkus Hoffrogge     * @param string $branch
676b08c3d51SMarkus Hoffrogge     * @return string
677b08c3d51SMarkus Hoffrogge     */
6782762023dSMarkus Hoffrogge    public function pull($remote, $branch)
6792762023dSMarkus Hoffrogge    {
680b08c3d51SMarkus Hoffrogge        return $this->run("pull $remote $branch");
681b08c3d51SMarkus Hoffrogge    }
682b08c3d51SMarkus Hoffrogge
683b08c3d51SMarkus Hoffrogge    /**
684b08c3d51SMarkus Hoffrogge     * List log entries.
685b08c3d51SMarkus Hoffrogge     *
686b08c3d51SMarkus Hoffrogge     * @param strgin $format
687b08c3d51SMarkus Hoffrogge     * @return string
688b08c3d51SMarkus Hoffrogge     */
6892762023dSMarkus Hoffrogge    public function log($format = null)
6902762023dSMarkus Hoffrogge    {
6912762023dSMarkus Hoffrogge        if ($format === null) {
692b08c3d51SMarkus Hoffrogge            return $this->run('log');
6932762023dSMarkus Hoffrogge        } else {
694b08c3d51SMarkus Hoffrogge            return $this->run('log --pretty=format:"' . $format . '"');
695b08c3d51SMarkus Hoffrogge        }
6962762023dSMarkus Hoffrogge    }
697b08c3d51SMarkus Hoffrogge
698b08c3d51SMarkus Hoffrogge    /**
699b08c3d51SMarkus Hoffrogge     * Sets the project description.
700b08c3d51SMarkus Hoffrogge     *
701b08c3d51SMarkus Hoffrogge     * @param string $new
702b08c3d51SMarkus Hoffrogge     */
7032762023dSMarkus Hoffrogge    public function setDescription($new)
7042762023dSMarkus Hoffrogge    {
7052762023dSMarkus Hoffrogge        $path = $this->gitDirectoryPath();
706b08c3d51SMarkus Hoffrogge        file_put_contents($path . "/description", $new);
707b08c3d51SMarkus Hoffrogge    }
708b08c3d51SMarkus Hoffrogge
709b08c3d51SMarkus Hoffrogge    /**
710b08c3d51SMarkus Hoffrogge     * Gets the project description.
711b08c3d51SMarkus Hoffrogge     *
712b08c3d51SMarkus Hoffrogge     * @return string
713b08c3d51SMarkus Hoffrogge     */
7142762023dSMarkus Hoffrogge    public function getDescription()
7152762023dSMarkus Hoffrogge    {
7162762023dSMarkus Hoffrogge        $path = $this->gitDirectoryPath();
717b08c3d51SMarkus Hoffrogge        return file_get_contents($path . "/description");
718b08c3d51SMarkus Hoffrogge    }
719b08c3d51SMarkus Hoffrogge
720b08c3d51SMarkus Hoffrogge    /**
721b08c3d51SMarkus Hoffrogge     * Sets custom environment options for calling Git
722b08c3d51SMarkus Hoffrogge     *
723b08c3d51SMarkus Hoffrogge     * @param string key
724b08c3d51SMarkus Hoffrogge     * @param string value
725b08c3d51SMarkus Hoffrogge     */
7262762023dSMarkus Hoffrogge    public function setenv($key, $value)
7272762023dSMarkus Hoffrogge    {
728b08c3d51SMarkus Hoffrogge        $this->envopts[$key] = $value;
729b08c3d51SMarkus Hoffrogge    }
730b08c3d51SMarkus Hoffrogge}
731b08c3d51SMarkus Hoffrogge
732b08c3d51SMarkus Hoffrogge/* End of file */
733