--- bzr-1.16.1/bzrlib/transport/ftp/__init__.py Fri Jun 26 10:42:37 2009 +++ bzr-1.16.1.nd/bzrlib/transport/ftp/__init__.py Mon Jul 13 23:22:17 2009 @@ -99,6 +99,8 @@ self.is_active = True else: self.is_active = False + + self._has_append = True def _get_FTP(self): """Return the ftplib.FTP instance for this object.""" @@ -387,6 +389,8 @@ """Append the text in the file-like object into the final location. """ + text = f.read() + abspath = self._remote_path(relpath) if self.has(relpath): ftp = self._get_FTP() @@ -394,8 +398,11 @@ else: result = 0 - mutter("FTP appe to %s", abspath) - self._try_append(relpath, f.read(), mode) + if self._has_append: + mutter("FTP appe to %s", abspath) + self._try_append(relpath, text, mode) + else: + self._fallback_append(relpath, text, mode) return result @@ -416,8 +423,9 @@ self._setmode(relpath, mode) ftp.getresp() except ftplib.error_perm, e: - self._translate_perm_error(e, abspath, extra='error appending', - unknown_exc=errors.NoSuchFile) + self._has_append = False + self._fallback_append(relpath, text, mode) + except ftplib.error_temp, e: if retries > _number_of_retries: raise errors.TransportError("FTP temporary error during APPEND %s." \ @@ -426,6 +434,13 @@ warning("FTP temporary error: %s. Retrying.", str(e)) self._reconnect() self._try_append(relpath, text, mode, retries+1) + + def _fallback_append(self, relpath, text, mode = None): + remote = self.get(relpath) + remote.seek(0, 2) + remote.write(text) + remote.seek(0, 0) + return self.put_file(relpath, remote, mode) def _setmode(self, relpath, mode): """Set permissions on a path.