3 * concept is to merge commits from a live or working tree
4 * into the 'release tree'
7 * step 1 = render the log of differences..
11 * -- our doc commit changes loads of files.. and makes the layout pointless.
12 * -- ?? grouping by day??? // expand/collapse..
17 require_once 'Pman.php';
19 class Pman_MTrack_Merger extends Pman {
22 var $release = 'github';
25 // function getAuth() - from log..
29 $au = $this->getAuthUser();
30 if (!$au || $au->company()->comptype != 'OWNER') {
33 $this->authUser = $au;
41 $this->pi = 'default/roojs1'; // fixme..
43 $this->repo = DB_DataObject::factory('mtrack_repos');
44 $this->filename = $this->repo->loadFromPath($this->pi);
46 if (!$this->repo->id) {
47 $this->err("invalid repo");
50 //if (!$this->projectPerm($this->repo->project_id, 'MTrack.Repos', 'S')) {
51 // $this->err("no perm for this repo ");
53 if (isset($_REQUEST['_tree'])) {
57 if (isset($_REQUEST['_changedFiles'])) {
58 $this->changedFiles($_REQUEST['_changedFiles']);
60 if (isset($_REQUEST['_preview'])) {
61 $this->preview($_REQUEST['_preview']);
63 if (isset($_REQUEST['_merge'])) {
64 $this->merge($_REQUEST['_merge']);
66 $this->jerr("invalid url");
72 return $this->get($pi);
81 $this->repo->debug = 1;
82 $ar = $this->repo->history("/", null, "rev", "{$this->release}..{$this->live}");
84 // the point of this is to extract all the revisions, and group them.
88 //echo '<PRE>';print_R($ar);
90 // need to get a 2 dimensional array of
91 // files along top, and commints down.
94 foreach($ar as $commit) {
96 $files = $commit->files;
97 $day = date("Y-m-d", strtotime($commit->ctime));
98 if (!isset($days[$day])) {
102 'children' => array()
105 $time= date("H:i:s", strtotime($commit->ctime));
106 if (!isset($days[$day]['children'][$time])) {
107 $days[$day]['children'][$time] = array(
109 'rev' => $day . ' ' . $time,
113 $days[$day]['children'][$time]['children'][] = array(
114 'text'=> $commit->changelog,
115 'rev' => $commit->rev,
121 foreach($days as $d=>$do) {
122 $dcn = $do['children'];
123 $do['children'] = array();
124 foreach($dcn as $t=>$to) {
125 $to['rev'] = $to['children'][0]['rev'];
126 $do['children'][] = $to;
128 $do['rev'] = $do['children'][0]['rev'];
142 function changedFiles($rev)
144 // list the files that have changed..
145 // in theory you could click a number of them and only merge those changes..
146 // need to do a git diff.. and just get a list of files..
148 $rev = preg_replace('/[^a-z0-9]+/', '',$rev);
149 //$this->repo->impl()->debug = 1;
150 $fh = $this->repo->impl()->git('diff', '--numstat' , "{$this->release}..{$rev}", '--', "");
151 // returns ADDED \t REMOVED \t NAME (might include rename/etc. info)
154 while (false !== ($line = fgets($fh))) {
156 $ar = explode("\t", trim($line));
160 'filename' => $ar[2],
173 function preview($rev)
175 // list the files that have changed..
176 // in theory you could click a number of them and only merge those changes..
177 // need to do a git diff.. and just get a list of files..
179 $rev = preg_replace('/[^a-z0-9]+/', '',$rev);
180 //$this->repo->impl()->debug = 1;
182 if (!empty($_POST['files'])) {
183 $files = json_decode($_POST['files']);
187 $fh = $this->repo->impl()->git('diff', "-w", "{$this->release}..{$rev}", '--', $files);
188 echo "<PRE> Commit: " . $rev ."</PRE>";
189 echo '<PRE>' . htmlspecialchars(stream_get_contents($fh)) . '</PRE>';
200 $mi = $this->repo->history("/", 1, "rev", $rev);
201 // echo '<PRE>';print_R($mi);exit;
206 $wd = $this->repo->getWorkingCopy();
207 $wd->git('checkout', '-b', $this->release, 'remotes/origin/'. $this->release);
211 $patchfile = $this->tempName('txt');
214 if (!empty($_POST['files'])) {
217 // if we select all the files, we should do a merge, rather than a commit..
218 $files = $_POST['files'] == '_all_' ? '_all_' : json_decode($_POST['files']);
222 if (is_array($files)) {
224 $fh = $this->repo->impl()->git('diff', "{$this->release}..{$rev}", '--', $files);
225 $of = fopen($patchfile, 'w');
226 stream_copy_to_stream($fh, $of);
227 fclose($of); fclose($fh);
229 $patch = System::which('patch');
231 $cmd = "$patch -p1 < " . $patchfile;
232 `$cmd`; //eg . patch -p1 < /var/lib/php5/MTrackTMPgZFeAN.txt
234 $wd->git('merge', '--squash' , $rev);
239 $commit = (object) array(
240 'when' => $mi[0]->ctime,
241 'reason' => $_REQUEST['message'],
242 'name' => $this->authUser->name,
243 'email' => $this->authUser->email,
246 $res = $wd->commit($commit);
247 if (!is_array($files)) {
248 // we do an actually merge commit seperatly from the merge diff, so that
249 // our logs show a nice history in each of those commits.
250 // not sure if this is a good idea or not..
251 $wd->git('merge', '-m', "Merge Commit with working branch (no code changed)" , $rev);
258 // $wd->checkout($this->release);
259 // generate the patch
261 // commit with message..