getAuthUser(); if (!$au || $au->company()->comptype != 'OWNER') { $this->jautherr(); } $this->authUser = $au; return true; } function get($pi, $opts= array()) { $this->pi = 'default/roojs1'; // fixme.. $this->repo = DB_DataObject::factory('mtrack_repos'); $this->filename = $this->repo->loadFromPath($this->pi); if (!$this->repo->id) { $this->err("invalid repo"); }; //if (!$this->projectPerm($this->repo->project_id, 'MTrack.Repos', 'S')) { // $this->err("no perm for this repo "); //} if (isset($_REQUEST['_tree'])) { $this->tree(); } if (isset($_REQUEST['_changedFiles'])) { $this->changedFiles($_REQUEST['_changedFiles']); } if (isset($_REQUEST['_preview'])) { $this->preview($_REQUEST['_preview']); } if (isset($_REQUEST['_merge'])) { $this->merge($_REQUEST['_merge']); } $this->jerr("invalid url"); exit; } function post($pi) { return $this->get($pi); } function tree() { $live = 'master'; $release = 'github'; $this->repo->debug = 1; $ar = $this->repo->history("/", null, "rev", "{$this->release}..{$this->live}"); // the point of this is to extract all the revisions, and group them. //echo '
';print_R($ar);
        
        // need to get a 2 dimensional array of
        // files along top, and commints down.
        $cfiles = array();
        $rows = array();
        foreach($ar as $commit) {
            
            $files = $commit->files;
            $day = date("Y-m-d", strtotime($commit->ctime));
            if (!isset($days[$day])) { 
                $days[$day] = array(
                    'text' => $day,
                    'rev' => $day,
                    'children' => array()
                );
            }
            $time= date("H:i:s", strtotime($commit->ctime));
            if (!isset($days[$day]['children'][$time])) { 
                $days[$day]['children'][$time] = array(
                    'text' => $time,
                    'rev' => $day . ' ' . $time,
                    'commits' =>array(),
                );
            }
            $days[$day]['children'][$time]['children'][] = array(
                'text'=> $commit->changelog,
                'rev' => $commit->rev,
                'leaf' => true
            );
        }
        $out = array();
        
        foreach($days as $d=>$do) {
            $dcn = $do['children'];
            $do['children'] = array();
            foreach($dcn as $t=>$to) {
                $to['rev']  = $to['children'][0]['rev'];
                $do['children'][] = $to;
            }
            $do['rev'] = $do['children'][0]['rev'];
            $out[] = $do;
        }
        
        $this->jdata($out);
        
         
        
    }
    
    



    function changedFiles($rev)
    {
        // list the files that have changed..
        // in theory you could click a number of them and only merge those changes..
        // need to do a git diff.. and just get a list of files..
        
        $rev = preg_replace('/[^a-z0-9]+/', '',$rev);
        //$this->repo->impl()->debug = 1;
        $fh = $this->repo->impl()->git('diff', '--numstat' ,  "{$this->release}..{$rev}", '--', "");
        // returns ADDED \t REMOVED \t NAME (might include rename/etc. info)
        $rows = array();
        
        while (false !== ($line = fgets($fh))) {
            //var_Dump($line);
            $ar = explode("\t", trim($line));
            $rows[] = array(
                'added' => $ar[0],
                'removed' => $ar[1],
                'filename' => $ar[2],
            );
            
            
        }
        fclose($fh);
        $this->jdata($rows);
         

    }
    
    

    function preview($rev)
    {
        // list the files that have changed..
        // in theory you could click a number of them and only merge those changes..
        // need to do a git diff.. and just get a list of files..
        
        $rev = preg_replace('/[^a-z0-9]+/', '',$rev);
        //$this->repo->impl()->debug = 1;
        $files = '';
        if (!empty($_POST['files'])) {
            $files = json_decode($_POST['files']);
        }
        
        
        $fh = $this->repo->impl()->git('diff', "-w", "{$this->release}..{$rev}", '--', $files);
        echo "
 Commit: " . $rev ."
"; echo '
' . htmlspecialchars(stream_get_contents($fh)) . '
'; fclose($fh); exit; } function merge($rev) { $mi = $this->repo->history("/", 1, "rev", $rev); // echo '
';print_R($mi);exit;
        

        
        
        $wd = $this->repo->getWorkingCopy();
        $wd->git('checkout', '-b', $this->release, 'remotes/origin/'. $this->release);
        
        
        
        $patchfile = $this->tempName('txt');
        
        $files = '';
        if (!empty($_POST['files'])) {
            
           
            // if we select all the files, we should do a merge, rather than a commit..
            $files = $_POST['files'] == '_all_' ? '_all_' : json_decode($_POST['files']);
        }
        
        
        if (is_array($files)) { 
            
            $fh = $this->repo->impl()->git('diff',   "{$this->release}..{$rev}", '--', $files);
            $of = fopen($patchfile, 'w');
            stream_copy_to_stream($fh, $of);
            fclose($of); fclose($fh);
            //var_dump($patch);
            $patch = System::which('patch');
            chdir($wd->dir);
            $cmd = "$patch -p1 < " . $patchfile;
            `$cmd`;  //eg . patch -p1 < /var/lib/php5/MTrackTMPgZFeAN.txt
        } else { 
            $wd->git('merge', '--squash' , $rev);
        }
          
        //echo $cmd;
        
        $commit = (object) array(
            'when' =>  $mi[0]->ctime,
            'reason' => $_REQUEST['message'],
            'name'  => $this->authUser->name,
            'email' => $this->authUser->email,
        );
        
        $res = $wd->commit($commit);
        if (!is_array($files)) {
            // we do an actually merge commit seperatly from the merge diff, so that
            // our logs show a nice history in each of those commits.
            // not sure if this is a good idea or not..
            $wd->git('merge', '-m', "Merge Commit with working branch (no code changed)" , $rev);
        }
        
        
        $res .= $wd->push();
        $this->jok($res);
        
       // $wd->checkout($this->release);
        // generate the patch
        // apply the patch
        // commit with message..
        // push
        
        
        
        
        
        
        
        
        
    }
    
    
    
    
}