-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathgitcheckout.php
More file actions
184 lines (168 loc) · 5.42 KB
/
gitcheckout.php
File metadata and controls
184 lines (168 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
<?php
/**
* PHP Git
*
* Pure-PHP class to read GIT repositories. It allows to
* perform read-only operations such as get commit history
* get files, get branches, and so forth.
*
* PHP version 5
*
* @category VersionControl
* @package PHP-Git
* @author César D. Rodas <crodas@member.fsf.org>
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @link http://cesar.la/git
*/
define("CE_NAMEMASK", 0x0fff);
define("CE_STAGEMASK", 0x3000);
define("CE_EXTENDED", 0x4000);
define("CE_VALID", 0x8000);
define("CE_STAGESHIFT", 12);
/**
* Git Checkout
*
* This abstract class can be use to do simple checkout with
* existent branches or tags.
*
* @category VersionControl
* @package PHP-Git
* @author César D. Rodas <crodas@member.fsf.org>
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @link http://cesar.la/git
*
*/
abstract class GitCheckout extends GitBase
{
/**
* _checkoutTree
*
* This function put files from an $id tree into a $prefix
* folder, and store it into the $files array.
*
* @param string $id Tree id.
* @param string $prefix Where to unpack the files.
* @param array &$files All unpacked files are stored here.
*
* @return nothing
*/
final private function _checkoutTree($id, $prefix,&$files)
{
$tree = $this->getObject($id, $type);
foreach ($tree as $file) {
if (!$file->is_dir) {
$content = $this->getObject($file->id);
$files[$file->id] = $prefix.$file->name;
file_put_contents($prefix.$file->name, $content);
chmod($prefix.$file->name, $file->perm);
} else {
$dir = "$prefix{$file->name}/";
@mkdir($dir);
$this->_checkoutTree($file->id, $dir, $files);
}
}
}
/**
* Checkout
*
* This function checkouts a given $commit id into $dir.
*
* @param string $dir Working directory
* @param string $commit Commit ID.
*
* @return bool True if success or an exception.
*/
final function checkout($dir, $commit)
{
$prevdir = getcwd();
chdir($dir) or $this->throwException("Imposible to chdir");;
$commit = $this->getObject($commit, $type);
if ($type != OBJ_COMMIT) {
return;
}
$this->_checkoutTree($commit['tree'], '', $files);
$index = "DIRC";
$index .= pack("N*", 2, count($files));
foreach ($files as $id => $file) {
$stat = stat($file);
$finfo = pack("N*", $stat['ctime'], 0, $stat['mtime'],
0, $stat['dev'], $stat['ino'], $stat['mode'],
$stat['uid'], $stat['gid'], $stat['size']);
$finfo .= $this->hexToSha1($id);
$finfo .= pack("n", strlen($file) | (0 << 12));
$finfo .= $file.chr(0);
while (strlen($finfo) % 8 != 0) {
$finfo .= chr(0);
}
$index .= $finfo;
}
$index .= $this->hexToSha1(sha1($index));
file_put_contents(".git/index", $index);
chdir($prevdir);
return true;
}
/**
* getIndexInfo
*
* This function read and parse information of the
* cache info, the working dir.
*
* @param string $filename Filename
*
* @return array Array of files on the working dir
*
* @experimental
*/
function getIndexInfo($filename)
{
$text = file_get_contents($filename);
$file_sha = sha1(substr($text, 0, strlen($text)-20));
if ($this->sha1ToHex(substr($text, -20)) != $file_sha) {
$this->throwException("Index file corrupt");
}
if (substr($text, 0, 4) !== "DIRC") {
$this->throwException("$filename is not a valid index file");
}
$info = unpack("N*", substr($text, 4, 8));
$version = $info[1];
$nrofiles = $info[2];
if ($version != 2 && $version != 3) {
return false;
}
$return = array();
$offset = 12;
$null = chr(0);
for ($i=0; $i < $nrofiles; $i++) {
$start = $offset;
$info = unpack("N*", substr($text, $offset, 40));
$offset += 40;
$sha1 = $this->sha1ToHex(substr($text, $offset, 20));
$offset += 20;
$flags = unpack("n*", substr($text, $offset, 4));
$offset += 2;
if ($flags[1] & CE_EXTENDED) {
$offset += 2;
}
$end = strpos($text, $null, $offset);
$file_name = substr($text, $offset, $end - $offset);
$offset += strlen($file_name)+1;
$return[] = array(
"ctime" => $info[1],
"mtime" => $info[3],
"idev" => $info[5],
"inode" => $info[6],
"mode" => $info[7],
"uid" => $info[8],
"gid" => $info[9],
"size" => $info[10],
"sha1" => $sha1,
"flags" => $flags,
"filename" => $file_name
);
while( ($offset - $start) % 8 != 0 && $offset++);
}
while ($text[$offset] == $null && $offset++);
return $return;
}
}
?>