? includes/table.inc
Index: commands/pm/updatecode.pm.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/updatecode.pm.inc,v
retrieving revision 1.7
diff -u -p -r1.7 updatecode.pm.inc
--- commands/pm/updatecode.pm.inc	19 Mar 2010 14:29:42 -0000	1.7
+++ commands/pm/updatecode.pm.inc	31 Mar 2010 14:28:18 -0000
@@ -137,7 +137,7 @@ function drush_pm_updatecode() {
  *   A list of the non-core modules that are enabled.  These must be disabled
  *   before core can be updated.
  */
-function _pm_update_core($project, $module_list = array()) {
+function _pm_update_core(&$project, $module_list = array()) {
   drush_include_engine('package_handler', drush_get_option('package-handler', 'wget'));
   $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
   
@@ -151,7 +151,9 @@ function _pm_update_core($project, $modu
   // Create a directory 'core' if it does not already exist
   $project['path'] = 'drupal-' . $project['candidate_version'];
   $project['full_project_path'] = $drupal_root . '/' . $project['path'];
-  mkdir($project['full_project_path']);
+  if (!is_dir($project['full_project_path'])) {
+    mkdir($project['full_project_path']);
+  }
   
   // Create a list of files and folders that are user-customized or otherwise
   // not part of the update process
@@ -161,9 +163,25 @@ function _pm_update_core($project, $modu
   // except for the items in the skip list
   _pm_update_move_files($drupal_root, $project['full_project_path'], $project['skip_list']);
   
+  // Set a context variable to indicate that rollback should reverse
+  // the _pm_update_move_files above.
+  drush_set_context('DRUSH_PM_DRUPAL_CORE', $project);
+
+  if (!$version_control = drush_pm_include_version_control($project['full_project_path'])) {
+    return FALSE;
+  }
+  
+  // Make a list of every item at the root of core except 'sites'
+  $items_to_test = drush_scan_directory($project['full_project_path'], '/.*/', array('.', '..', 'sites', '.svn'), 0, FALSE, 'basename', 0, 0, TRUE);
+
+  $project['base_project_path'] = dirname($project['full_project_path']);
+  // Check we have a version control system, and it clears its pre-flight.
+  if (!$version_control->pre_update($project, $items_to_test)) {
+    return FALSE;
+  }
+  
   // Update core. 
-  $version_control = pm_update_project($project);
-  if ($version_control === FALSE) {
+  if (pm_update_project($project, $version_control) === FALSE) {
     return FALSE;
   }
   
@@ -189,7 +207,7 @@ function _pm_update_core($project, $modu
  * Move some files from one location to another
  */
 function _pm_update_move_files($src_dir, $dest_dir, $skip_list, $remove_conflicts = TRUE) {
-  $items_to_move = drush_scan_directory($src_dir, '/.*/', array_merge(array('.', '..', 'CVS'), $skip_list), 0, FALSE);
+  $items_to_move = drush_scan_directory($src_dir, '/.*/', array_merge(array('.', '..'), $skip_list), 0, FALSE, 'filename', 0, 0, TRUE);
   foreach ($items_to_move as $filename => $info) {
     if ($remove_conflicts) {
       drush_delete_dir($dest_dir . '/' . basename($filename));
@@ -238,9 +256,16 @@ function pm_update_packages($projects) {
     if (stripos($project['path'], $project['project_type']) === FALSE || !is_dir($project['full_project_path'])) {
       return drush_set_error('DRUSH_PM_UPDATING_PATH_NOT_FOUND', dt('The !project directory could not be found within the !types directory at !full_project_path, perhaps the project is enabled but has been deleted from disk.', array('!project' => $project['name'], '!type' => $project['project_type'], '!full_project_path' => $project['full_project_path'])));
     }
+    if (!$version_control = drush_pm_include_version_control($project['full_project_path'])) {
+      return FALSE;
+    }
+    $project['base_project_path'] = dirname($project['full_project_path']);
+    // Check we have a version control system, and it clears its pre-flight.
+    if (!$version_control->pre_update($project)) {
+      return FALSE;
+    }
     // Run update on one project
-    $version_control = pm_update_project($project);
-    if ($update_status === FALSE) {
+    if (pm_update_project($project, $version_control) === FALSE) {
       return FALSE;
     }
     pm_update_complete($project, $version_control);
@@ -256,15 +281,7 @@ function pm_update_packages($projects) {
  *   The project to upgrade.  $project['full_project_path'] must be set
  *   to the location where this project is stored.
  */
-function pm_update_project($project) {
-  $project['base_project_path'] = dirname($project['full_project_path']);
-  // Check we have a version control system, and it clears it's pre-flight.
-  if (!$version_control = drush_pm_include_version_control($project['full_project_path'])) {
-    return FALSE;
-  }
-  if (!$version_control->pre_update($project)) {
-    return FALSE;
-  }
+function pm_update_project($project, $version_control) {
   // Add the project to a context so we can roll back if needed.
   $updated = drush_get_context('DRUSH_PM_UPDATED');
   $updated[] = $project;
@@ -274,7 +291,7 @@ function pm_update_project($project) {
     return drush_set_error('DRUSH_PM_UPDATING_FAILED', dt('Updating project !project failed. Attempting to roll back to previously installed version.', array('!project' => $project['name'])));
   }
   
-  return $version_control;
+  return TRUE;
 }
 
 /**
@@ -296,13 +313,14 @@ function drush_pm_updatecode_rollback() 
       return FALSE;
     }
     $version_control->rollback($project);
-    
-    // Post rollback, we will do additional repair if the project is drupal core.
-    if ($project['name'] == 'drupal') {
-      $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
-      _pm_update_move_files($project['full_project_path'], $drupal_root, $project['skip_list']);
-      drush_delete_dir($project['full_project_path']);
-    }
+  }
+
+  // Post rollback, we will do additional repair if the project is drupal core.
+  $drupal_core = drush_get_context('DRUSH_PM_DRUPAL_CORE');
+  if (isset($drupal_core)) {
+    $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
+    _pm_update_move_files($drupal_core['full_project_path'], $drupal_root, $drupal_core['skip_list']);
+    drush_delete_dir($drupal_core['full_project_path']);
   }
 }
 
Index: commands/pm/version_control/backup.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/version_control/backup.inc,v
retrieving revision 1.3
diff -u -p -r1.3 backup.inc
--- commands/pm/version_control/backup.inc	19 Jan 2010 21:25:28 -0000	1.3
+++ commands/pm/version_control/backup.inc	31 Mar 2010 14:28:18 -0000
@@ -10,7 +10,7 @@ class drush_pm_version_control_backup im
   /**
    * Implementation of pre_update().
    */
-  public function pre_update(&$project) {
+  public function pre_update(&$project, $items_to_test = array()) {
     $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
 
     // Save the date to be used in the backup directory's path name.
Index: commands/pm/version_control/bzr.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/version_control/bzr.inc,v
retrieving revision 1.5
diff -u -p -r1.5 bzr.inc
--- commands/pm/version_control/bzr.inc	27 Jan 2010 16:29:19 -0000	1.5
+++ commands/pm/version_control/bzr.inc	31 Mar 2010 14:28:18 -0000
@@ -25,7 +25,7 @@ class drush_pm_version_control_bzr imple
   /**
    * Implementation of pre_update().
    */
-  public function pre_update(&$project) {
+  public function pre_update(&$project, $items_to_test = array()) {
     // TODO: Add similar checks to SVN?
   }
 
Index: commands/pm/version_control/svn.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/version_control/svn.inc,v
retrieving revision 1.10
diff -u -p -r1.10 svn.inc
--- commands/pm/version_control/svn.inc	27 Jan 2010 16:29:19 -0000	1.10
+++ commands/pm/version_control/svn.inc	31 Mar 2010 14:28:18 -0000
@@ -10,9 +10,13 @@ class drush_pm_version_control_svn imple
   /**
    * Implementation of pre_update().
    */
-  public function pre_update(&$project) {
+  public function pre_update(&$project, $items_to_test = array()) {
+    // If items to test is empty, test everything; otherwise, pass just
+    // the list of files to test to svn status.
+    $status_files = implode(' ', array_keys($items_to_test));
+    
     // Check the project directory looks clean
-    if (drush_shell_exec('svn status '. drush_get_option('svnstatusparams') .' '. $project['full_project_path'])) {
+    if (drush_shell_exec('cd ' . $project['full_project_path'] . ' && svn status '. drush_get_option('svnstatusparams') .' '. $status_files)) {
       $output = drush_shell_exec_output();
       if (!empty($output)) {
         return drush_set_error('DRUSH_PM_SVN_LOCAL_CHANGES', dt("The SVN working copy at !path appears to have uncommmitted changes (see below). Please commit or revert these changes before continuing:\n!output", array('!path' => $project['full_project_path'], '!output' => implode("\n", $output))));
@@ -21,8 +25,9 @@ class drush_pm_version_control_svn imple
     else {
       return drush_set_error('DRUSH_PM_SVN_NOT_FOUND', dt("Drush was unable to get the svn status on !path. Check that you have Subversion \ninstalled and that this directory is a subversion working copy.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output()))));
     }
+    
     // Check for incoming updates
-    if (drush_shell_exec('svn status -u '. drush_get_option('svnstatusparams') .' '. $project['full_project_path'])) {
+    if (drush_shell_exec('cd ' . $project['full_project_path'] . ' && svn status -u '. drush_get_option('svnstatusparams') .' '. $status_files)) {
       $output = preg_grep('/^Status against revision:\s*[0-9]*$/', drush_shell_exec_output(), PREG_GREP_INVERT);
       if (!empty($output)) {
         return drush_set_error('DRUSH_PM_SVN_REMOTE_CHANGES', dt("The SVN working copy at !path appears to be out of date with the repository (see below). Please run 'svn update' to pull down changes before continuing:\n!output", array('!path' => $project['full_project_path'], '!output' => implode("\n", $output))));
Index: includes/command.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/command.inc,v
retrieving revision 1.69
diff -u -p -r1.69 command.inc
--- includes/command.inc	29 Mar 2010 23:24:58 -0000	1.69
+++ includes/command.inc	31 Mar 2010 14:28:19 -0000
@@ -697,13 +697,13 @@ function drush_command_hook($commandfile
  *   "path", "basename", and "name" members corresponding to the
  *   matching files.
  */
-function drush_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0) {
+function drush_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0, $include_dot_files = FALSE) {
   $key = (in_array($key, array('filename', 'basename', 'name')) ? $key : 'filename');
   $files = array();
 
   if (is_dir($dir) && $handle = opendir($dir)) {
     while (FALSE !== ($file = readdir($handle))) {
-      if (!in_array($file, $nomask) && $file[0] != '.') {
+      if (!in_array($file, $nomask) && (($include_dot_files && (!preg_match("/\.\+/",$file))) || ($file[0] != '.'))) {
         if (is_dir("$dir/$file") && $recurse) {
           // Give priority to files in this folder by merging them in after any subdirectory files.
           $files = array_merge(drush_scan_directory("$dir/$file", $mask, $nomask, $callback, $recurse, $key, $min_depth, $depth + 1), $files);
