? drush-940688.patch
? includes/table.inc
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.9
diff -u -r1.9 backup.inc
--- commands/pm/version_control/backup.inc	2 Dec 2010 12:27:59 -0000	1.9
+++ commands/pm/version_control/backup.inc	2 Dec 2010 12:47:51 -0000
@@ -19,13 +19,21 @@
       $backup_target = $backup_target . '/'. $project['name'];
       // Save for rollback or notifications.
       $project['backup_target'] = $backup_target;
-      if (!drush_move_dir($project['full_project_path'], $backup_target)) {
-        return drush_set_error('DRUSH_PM_BACKUP_FAILED', dt('Failed to backup project directory !project to !backup_target', array('!project' => $project['full_project_path'], '!backup_target' => $backup_target)));
+
+      // Move or copy to backup target based in package-handler.
+      $ph = drush_get_option('package-handler', 'wget');
+      if ($ph == 'wget') {
+        if (drush_move_dir($project['full_project_path'], $backup_target)) {
+          return TRUE;
+        }
       }
-      return TRUE;  
-    }
-    else {
-      return FALSE;
+      // cvs or git.
+      else {
+        if (drush_copy_dir($project['full_project_path'], $backup_target)) {
+          return TRUE;
+        }
+      }
+      return drush_set_error('DRUSH_PM_BACKUP_FAILED', dt('Failed to backup project directory !project to !backup_target', array('!project' => $project['full_project_path'], '!backup_target' => $backup_target)));
     }
   }
 
Index: includes/drush.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/drush.inc,v
retrieving revision 1.151
diff -u -r1.151 drush.inc
--- includes/drush.inc	1 Dec 2010 21:02:21 -0000	1.151
+++ includes/drush.inc	2 Dec 2010 12:47:52 -0000
@@ -578,6 +578,56 @@
 }
 
 /**
+ * Copy $src to $dest.
+ *
+ * If cp fails, we'll try rsync.
+ *
+ * @param $src
+ *   The directory to copy.
+ * @param $dest
+ *   The destination to copy the source to, including the new name of
+ *   the directory.  To copy directory "a" from "/b" to "/c", then
+ *   $src = "/b/a" and $dest = "/c/a".  To copy "a" to "/c" and rename
+ *   it to "d", then $dest = "/c/d".
+ * @param $overwrite
+ *   If TRUE, the destination will be deleted if it exists.
+ * @return
+ *   TRUE on success, FALSE on failure.
+ */
+function drush_copy_dir($src, $dest, $overwrite = FALSE) {
+  // Preflight based on $overwrite if $dest exists.
+  if (file_exists($dest)) {
+    if ($overwrite) {
+      drush_op('drush_delete_dir', $dest);
+    }
+    else {
+      return drush_set_error('DRUSH_DESTINATION_EXISTS', dt('Destination directory !dest already exists.', array('!dest' => $dest)));
+    }
+  }
+  // $src readable?
+  if (!is_readable($src)) {
+    return drush_set_error('DRUSH_SOURCE_NOT_EXISTS', dt('Source directory !dest is not readable or does not exist.', array('!src' => $src)));
+  }
+  // $dest writable?
+  if (!is_writable(dirname($dest))) {
+    return drush_set_error('DRUSH_DESTINATION_NOT_WRITABLE', dt('Destination directory !dest is not writable.', array('!dest' => dirname($dest))));
+  }
+  // Try cp.
+  if (drush_shell_exec('cp -a %s %s', $src, $dest)) {
+    return TRUE;
+  }
+
+  // Try rsync.
+  drush_op('mkdir', $dest);
+  $exec = 'rsync -raz ' . $src . '/ ' . $dest;
+  if (drush_shell_exec($exec)) {
+    return TRUE;
+  }
+
+  return drush_set_error('DRUSH_COPY_DIR_FAILURE', dt('Unable to copy !src to !dest.', array('src' => $src, 'dest' => $dest)));
+}
+
+/**
  * Move $src to $dest.
  *
  * If the php 'rename' function doesn't work, then we'll try mv and if
