2f098f4a70ac653bdcb6bae7513269d69b6ec462
[phpgit.git] / library / Git.php
blob2f098f4a70ac653bdcb6bae7513269d69b6ec462
1 <?php
3 require_once dirname(__FILE__) . '/Git/Lazy.php';
4 require_once dirname(__FILE__) . '/Git/Actor.php';
5 require_once dirname(__FILE__) . '/Git/Commit.php';
6 require_once dirname(__FILE__) . '/Git/Exception.php';
7 require_once dirname(__FILE__) . '/Git/Repo.php';
8 require_once dirname(__FILE__) . '/Git/Tree.php';
9 require_once dirname(__FILE__) . '/Git/Blob.php';
11 /**
12 * Wrapper for Git executable. Lowest level interface.
14 class Git
17 const S = DIRECTORY_SEPARATOR;
19 static protected $executeKwargs = array(
20 'istream', 'with_keep_cwd', 'with_extended_output',
21 'with_exceptions', 'with_raw_output'
24 /**
25 * Git executable to invoke. You can replace this with a full path
26 * to your Git executable/wrapper script, but be sure to escape
27 * everything properly!
29 static public $git = 'git';
31 /**
32 * Current working directory.
34 protected $dir;
36 /**
37 * @param $dir Current working directory.
39 public function __construct($dir) {
40 $this->dir = $dir;
43 /**
44 * Returns current working directory.
46 public function getDir() {return $this->dir;}
48 /**
49 * Executes a command on shell and returns output.
51 public function execute($command) {
52 return shell_exec($command);
55 /**
56 * Transforms an associative array of arguments to command line options.
57 * Arguments can be like 'r' or 'no-commit'.
58 * @note Original Python version kwargs used 'no_commit'
59 * form due to Python conventions. We decided to use a more direct
60 * approach because our associative array allow them.
62 public function transformArgs($kwargs) {
63 $args = array();
64 foreach ($kwargs as $k => $v) {
65 if (strlen($k) == 1) {
66 if ($v === true) $args[] = "-$k";
67 else $args[] = "-$k $v";
68 } else {
69 // $k = dashify($k);
70 if ($v === true) $args[] = "--$k";
71 else $args[] = "--$k=$v";
74 return $args;
77 /**
78 * Runs a given Git command with the specified arguments and return
79 * the result as a string.
80 * @param $method Name of command, but camelCased instead of dash-ified.
81 * @param $args Array of arguments. There is actually only one argument,
82 * which is an array of associative and numerically indexed
83 * parameters.
84 * @return String output.
86 public function __call($method, $raw_args) {
87 // split out "kwargs" (to be converted to options) from regular
88 // "args" (which get inserted normally)
89 $args = array();
90 $kwargs = array();
91 foreach ($raw_args as $raw) {
92 if (is_array($raw)) $kwargs = $raw;
93 else $args[] = $raw;
95 for ($i = 0; isset($kwargs[$i]); $i++) {
96 $args[] = $kwargs[$i];
97 unset($kwargs[$i]);
99 // $args and $kwargs are interesting
100 $opt_args = $this->transformArgs($kwargs);
101 // parse through $args again to determine which ones are actually kwargs
102 $ext_args = array();
103 foreach ($args as $v) {
104 if ($v == '--') $ext_args[] = $v;
105 else $ext_args[] = $this->escape($v);
107 // Full arguments
108 $args = array_merge($opt_args, $ext_args);
109 // Convert methodName to method-name (our equivalent of dashify).
110 // This is kind of inefficient.
111 $command = '';
112 for ($i = 0, $max = strlen($method); $i < $max; $i++) {
113 $c = $method[$i];
114 $command .= ctype_upper($c) ? '-' . strtolower($c) : $c;
116 $call = self::$git . " --git-dir={$this->dir} $command " . implode(' ', $args);
117 // var_dump($call);
118 $result = $this->execute($call);
119 return $result;
123 * Escape argument for shell. I don't think this actually works properly
124 * on Windows.
126 public function escape($v) {
127 return str_replace("'", "\\\\'", $v);