Beispiel #1
0
 public function get_tag_rev($file, $tag)
 {
     $sth = dbh_query_bind("SELECT revision FROM file_tag WHERE file = ? AND tag = ?", $file, $tag);
     $row = $sth->fetch(PDO::FETCH_NUM);
     $sth->closeCursor();
     $tag_rev = null;
     if (!empty($row)) {
         list($tag_rev) = $row;
     }
     return $tag_rev;
 }
Beispiel #2
0
 public function updateEntireRepoAction($tag, $user)
 {
     set_time_limit(0);
     $cmd = '';
     $command_output = '';
     ###  Prepare for a MASS HEAD update if updating to HEAD
     $doing_indiv_dir_update = array();
     if ($tag == 'HEAD') {
         $head_update_cmd = "svn update";
         START_TIMER('REPO_CMD', PROJECT_PROJECT_TIMERS);
         $this->log_repo_action($head_update_cmd, 'entire_repo', $user);
         $command_output .= shell_exec($this->stage->config('repo_cmd_prefix') . "{$head_update_cmd} 2>&1 | cat -");
         END_TIMER('REPO_CMD', PROJECT_PROJECT_TIMERS);
         $cmd .= "\n" . (strlen($cmd) ? ' ; ' : '') . $head_update_cmd;
     } else {
         #############################
         ###  Step 1 : First find any files that we have tags for but don't exist
         ###  Start out by updating all rows in the tag table as mass_edit=1
         ###    as we delete and update, the ones that have tags will be set back to 0
         $rv = dbh_do_bind("UPDATE file_tag SET mass_edit=1 AND tag=?", $tag);
         $command_output = '';
         $status = $this->get_dir_status();
         foreach (preg_split('/\\n/', $status) as $line) {
             if (preg_match('/^\\s*[A-Z]?\\s*\\d+\\s+(\\d+)\\s+\\S+\\s+(\\S.*)$/', $line, $m)) {
                 $cur_rev = $m[1];
                 $file = rtrim($m[2], "\n\r");
                 ///  Override this with the SLOW, but accurate alternate.  This turns a 2 min update into a 2+ hour update
                 list($cur_rev) = $this->get_current_rev($file);
                 ###  Skip dirs in SVN (for now)...
                 if (is_dir($this->stage->env()->repo_base . '/' . $file)) {
                     continue;
                 }
                 ###  We could be cache-ing the tags here, but in some repos with long file paths and hundreds of thousands of files, we would run out of memory
                 #                    ###  See what the tag is...
                 #                    $sth = dbh_query_bind("SELECT revision FROM file_tag WHERE file = ? AND tag = ?", $file, $tag);
                 #                    $old_rev = $sth->fetch(PDO::FETCH_NUM);
                 #                    $sth->closeCursor();
                 ###  ALL we are doing for the files that exist for this loop is marking mass_edit as off
                 $rv = dbh_do_bind("UPDATE file_tag SET mass_edit=0 WHERE file = ? AND tag = ?", $file, $tag);
             }
         }
         #############################
         ###  Step 2 : Update the files that didn't exist...
         ###  The rows the mass_edit still need to be Un-tagged...
         ###  See what the tag was before...
         $sth = dbh_query_bind("SELECT file,revision FROM file_tag WHERE mass_edit=1 AND tag=?", $tag);
         while (list($file, $rev) = $sth->fetch(PDO::FETCH_NUM)) {
             ///  Each loop, do a $individual_file_rev_updates instead of globally
             $individual_file_rev_updates = array();
             $dir_test = $file;
             ###  Before we do Inidividual Tag updates on files the containing dirs must exist
             $dirs_to_update = array();
             while (!empty($dir_test) && !is_dir(dirname($this->stage->env()->repo_base . "/{$dir_test}")) && $this->stage->env()->repo_base != dirname($this->stage->env()->repo_base . "/{$dir_test}") && !array_key_exists(dirname($dir_test), $doing_indiv_dir_update)) {
                 $dir = dirname($dir_test);
                 $dirs_to_update[] = $dir;
                 $doing_indiv_dir_update[$dir] = true;
                 $dir_test = $dir;
                 // iterate backwards
             }
             ///  Need to add in parent-first order
             ///    NOTE: we only need to do the parent one, because the in-between ones will be included
             if (count($dirs_to_update)) {
                 $individual_file_rev_updates[] = array(array_pop($dirs_to_update), $rev);
             }
             $individual_file_rev_updates[] = array($file, $rev);
             foreach ($individual_file_rev_updates as $update) {
                 list($up_file, $up_rev) = $update;
                 $indiv_update_cmd = "svn update -r{$up_rev} " . escapeshellcmd($up_file);
                 START_TIMER('REPO_CMD', PROJECT_PROJECT_TIMERS);
                 $this->log_repo_action($indiv_update_cmd, 'entire_repo', $user);
                 $command_output .= shell_exec($this->stage->config('repo_cmd_prefix') . "{$indiv_update_cmd} 2>&1 | cat -");
                 END_TIMER('REPO_CMD', PROJECT_PROJECT_TIMERS);
                 $cmd .= "\n" . (strlen($cmd) ? ' ; ' : '') . $indiv_update_cmd;
             }
         }
         $sth->closeCursor();
         $rv = dbh_do_bind("UPDATE file_tag SET mass_edit=0 WHERE tag=?", $tag);
         #############################
         ###  Step 3 : NOW, get a new Status output, and go through again, now that all files are present and set everything to the right tags
         ###  Reset Cache on dir status
         unset($this->repo_cache['dir_status']['*ROOTDIR*']);
         $status = $this->get_dir_status();
         foreach (preg_split('/\\n/', $status) as $line) {
             if (preg_match('/^\\s*[A-Z]?\\s*\\d+\\s+(\\d+)\\s+\\S+\\s+(\\S.*)$/', $line, $m)) {
                 $cur_rev = $m[1];
                 $file = rtrim($m[2], "\n\r");
                 if (is_dir($this->stage->env()->repo_base . "/{$file}")) {
                     continue;
                 }
                 ///  Each loop, do a $individual_file_rev_updates instead of globally
                 $individual_file_rev_updates = array();
                 ###  Get the tag rev for this file...
                 $sth = dbh_query_bind("SELECT revision FROM file_tag WHERE file = ? AND tag = ?", $file, $tag);
                 $rev = $sth->fetch(PDO::FETCH_NUM);
                 $sth->closeCursor();
                 if (!empty($rev)) {
                     $dir_test = $file;
                     ###  Before we do Inidividual Tag updates on files the containing dirs must exist
                     $dirs_to_update = array();
                     while (!empty($dir_test) && !is_dir(dirname($this->stage->env()->repo_base . "/{$dir_test}")) && $this->stage->env()->repo_base != dirname($this->stage->env()->repo_base . "/{$dir_test}") && !array_key_exists(dirname($dir_test), $doing_indiv_dir_update)) {
                         $dir = dirname($dir_test);
                         $dirs_to_update[] = $dir;
                         $doing_indiv_dir_update[$dir] = true;
                         $dir_test = $dir;
                         // iterate backwards
                     }
                     ///  Need to add in parent-first order
                     ///    NOTE: we only need to do the parent one, because the in-between ones will be included
                     if (count($dirs_to_update)) {
                         #                            bug("Parent Dir update", $file);
                         $individual_file_rev_updates[] = array(array_pop($dirs_to_update), $rev[0]);
                     } else {
                         if ($cur_rev != $rev[0]) {
                             #                            bug("Regular update", $file);
                             $individual_file_rev_updates[] = array($file, $rev[0]);
                         }
                     }
                 } else {
                     list($first_rev, $error) = $this->get_first_rev($file);
                     #                         bug("NO TAG, intent-to-rm update", $file, $first_rev);
                     if (empty($error)) {
                         $rev_before_first = $first_rev - 1;
                         $individual_file_rev_updates[] = array($file, $rev_before_first);
                     }
                 }
                 ///  Do updates...
                 foreach ($individual_file_rev_updates as $update) {
                     list($up_file, $up_rev) = $update;
                     $indiv_update_cmd = "svn update -r{$up_rev} " . escapeshellcmd($up_file);
                     START_TIMER('REPO_CMD', PROJECT_PROJECT_TIMERS);
                     $this->log_repo_action($indiv_update_cmd, 'entire_repo', $user);
                     $command_output .= shell_exec($this->stage->config('repo_cmd_prefix') . "{$indiv_update_cmd} 2>&1 | cat -");
                     END_TIMER('REPO_CMD', PROJECT_PROJECT_TIMERS);
                     $cmd .= "\n" . (strlen($cmd) ? ' ; ' : '') . $indiv_update_cmd;
                 }
             }
         }
     }
     if (empty($command_output)) {
         $command_output = '</xmp><i>No output</i>';
     }
     return array($cmd, $command_output);
 }