Fix up Git_Repo->log() to actually work.
[phpgit.git] / library / Git.php
blob4e3cdcd41950ecf363bd8c088f63152e418d540d
1 <?php
3 require_once 'Git/Actor.php';
4 require_once 'Git/Commit.php';
5 require_once 'Git/Exception.php';
6 require_once 'Git/Repo.php';
8 /**
9 * Wrapper for Git executable. Lowest level interface.
11 class Git
14 const S = DIRECTORY_SEPARATOR;
16 /**
17 * Git executable to invoke. You can replace this with a full path
18 * to your Git executable/wrapper script, but be sure to escape
19 * everything properly!
21 static public $git = 'git';
23 /**
24 * Current working directory.
26 protected $dir;
28 /**
29 * @param $dir Current working directory
31 public function __construct($dir) {
32 $this->dir = $dir;
35 /**
36 * Executes a command on shell and returns output.
38 public function execute($command) {
39 return shell_exec($command);
42 /**
43 * Transforms an associative array of arguments to command line options.
44 * Arguments can be like 'r' or 'no-commit'.
45 * @note Original Python version kwargs used 'no_commit'
46 * form due to Python conventions. We decided to use a more direct
47 * approach because our associative array allow them.
49 public function transformArgs($kwargs) {
50 $args = array();
51 foreach ($kwargs as $k => $v) {
52 if (strlen($k) == 1) {
53 if ($v === true) $args[] = "-$k";
54 else $args[] = "-$k $v";
55 } else {
56 // $k = dashify($k);
57 if ($v === true) $args[] = "--$k";
58 else $args[] = "--$k=$v";
61 return $args;
64 /**
65 * Runs a given Git command with the specified arguments and return
66 * the result as a string.
67 * @param $method Name of command, but camelCased instead of dash-ified.
68 * @param $args Array of arguments. There is actually only one argument,
69 * which is an array of associative and numerically indexed
70 * parameters.
71 * @return String output.
73 public function __call($method, $raw_args) {
74 // split out "kwargs" (to be converted to options) from regular
75 // "args" (which get inserted normally)
76 $args = array();
77 $kwargs = array();
78 foreach ($raw_args as $raw) {
79 if (is_array($raw)) $kwargs = $raw;
80 else $args[] = $raw;
82 for ($i = 0; isset($kwargs[$i]); $i++) {
83 $args[] = $kwargs[$i];
84 unset($kwargs[$i]);
86 // $args and $kwargs are interesting
87 $opt_args = $this->transformArgs($kwargs);
88 // parse through $args again to determine which ones are actually kwargs
89 $ext_args = array();
90 foreach ($args as $v) {
91 if ($v == '--') $ext_args[] = $v;
92 else $ext_args[] = $this->escape($v);
94 // Full arguments
95 $args = array_merge($opt_args, $ext_args);
96 // Convert methodName to method-name (our equivalent of dashify).
97 // This is kind of inefficient.
98 $command = '';
99 for ($i = 0, $max = strlen($method); $i < $max; $i++) {
100 $c = $method[$i];
101 $command .= ctype_upper($c) ? '-' . strtolower($c) : $c;
103 $call = self::$git . " --git-dir={$this->dir} $command " . implode(' ', $args);
104 // var_dump($call);
105 $result = $this->execute($call);
106 return $result;
110 * Escape argument for shell. I don't think this actually works properly
111 * on Windows.
113 public function escape($v) {
114 return str_replace("'", "\\\\'", $v);