summaryrefslogtreecommitdiffstats
path: root/src/files.ml
diff options
context:
space:
mode:
authorJérôme Vouillon <vouillon@pps.jussieu.fr>2009-07-19 20:07:54 +0000
committerJérôme Vouillon <vouillon@pps.jussieu.fr>2009-07-19 20:07:54 +0000
commit06be21b9c7d207030f8b91106e6ec346ba3583c7 (patch)
tree63134ff5ec74b8a71a3a9cc602d3f34e7031e91e /src/files.ml
parentaa6a952fb56239c1feab44cea6ebfccef097e141 (diff)
downloadunison-06be21b9c7d207030f8b91106e6ec346ba3583c7.zip
unison-06be21b9c7d207030f8b91106e6ec346ba3583c7.tar.gz
unison-06be21b9c7d207030f8b91106e6ec346ba3583c7.tar.bz2
* Bumped version number: incompatible protocol changes
* Create parent directories (with correct permissions) during transport for paths which point to non-existent locations in the destination replica. * Keep track of which file contents are being transferred, and delay the transfer of a file when another file with the same contents is currently being transferred. This way, the second transfer can be skipped and replaced by a local copy. * Changes to the implementation of the rsync algorithm: - use longer blocks for large files (the size of a block is the square root of the size of the file for large files); - transmit less checksum information per block (we still have less than one chance in a hundred million of transferring a file incorrectly, and Unison will catch any transfer error when fingerprinting the whole file) - avoid transfer overhead (which was 4 bytes per block) For a 1G file, the first optimization saves a factor 50 on the amount of data transferred from the target to the source (blocks are 32768 bytes rather than just 700 bytes). The two other optimizations save another factor of 2 (from 24 bytes per block down to 10). * New "links" preference. When set to false, Unison will report an error on symlinks during update detection. (This is the default when one host is running Windows but not Cygwin.) This is better than failing during propagation. * Added a preference "halfduplex" to force half-duplex communication with the server. This may be useful on unreliable links (as a more efficient alternative to "maxthreads = 1"). * Renamed preference "pretendwin" to "ignoreinodenumbers" (an alias is kept for backwards compatibility). * GTK UI: display estimated remaining time and transfer rate on the progress bar * GTK UI: some polishing; in particular: - stop statistics window updates when idle (save power on laptops) - some ok and cancel buttons were in the wrong order * Added some support for making it easier to extend Unison without breaking backwards compatibility. - Possibility to mark a preference as local. Such a preference is propagated if possible but will not result in an error if it is not found server-side. This make it possible to add new functionalities client-side without breaking compatibility. - Added a function [Remove.commandAvailable] which tests whether a command is available on a given root. * Removed hack in findUpdates that would update the archive in a visible way for the sake of path translation: it is no longer needed.
Diffstat (limited to 'src/files.ml')
-rw-r--r--src/files.ml45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/files.ml b/src/files.ml
index ee27b4e..a034400 100644
--- a/src/files.ml
+++ b/src/files.ml
@@ -319,6 +319,36 @@ let setupTargetPathsLocal (fspath, path) =
let setupTargetPaths =
Remote.registerRootCmd "setupTargetPaths" setupTargetPathsLocal
+let rec createDirectories fspath localPath props =
+ match props with
+ [] ->
+ ()
+ | desc :: rem ->
+ match Path.deconstructRev localPath with
+ None ->
+ assert false
+ | Some (_, parentPath) ->
+ createDirectories fspath parentPath rem;
+ try
+ let absolutePath = Fspath.concat fspath parentPath in
+ Fs.mkdir absolutePath (Props.perms desc)
+ (* The directory may have already been created
+ if there are several paths with the same prefix *)
+ with Unix.Unix_error (Unix.EEXIST, _, _) -> ()
+
+let setupTargetPathsAndCreateParentDirectoryLocal (fspath, (path, props)) =
+ let localPath = Update.translatePathLocal fspath path in
+ Util.convertUnixErrorsToTransient
+ "creating parent directories"
+ (fun () -> createDirectories fspath localPath props);
+ let (workingDir,realPath) = Fspath.findWorkingDir fspath localPath in
+ let tempPath = Os.tempPath ~fresh:false workingDir realPath in
+ Lwt.return (workingDir, realPath, tempPath, localPath)
+
+let setupTargetPathsAndCreateParentDirectory =
+ Remote.registerRootCmd "setupTargetPathsAndCreateParentDirectory"
+ setupTargetPathsAndCreateParentDirectoryLocal
+
(* ------------------------------------------------------------ *)
let updateSourceArchiveLocal (fspathFrom, (localPathFrom, uiFrom, errPaths)) =
@@ -376,6 +406,15 @@ let deleteSpuriousChildrenLocal (_, (fspathTo, pathTo, archChildren)) =
let deleteSpuriousChildren =
Remote.registerRootCmd "deleteSpuriousChildren" deleteSpuriousChildrenLocal
+let rec normalizePropsRec propsFrom propsTo =
+ match propsFrom, propsTo with
+ d :: r, d' :: r' -> normalizePropsRec r r'
+ | _, [] -> propsFrom
+ | [], _ :: _ -> assert false
+
+let normalizeProps propsFrom propsTo =
+ normalizePropsRec (Safelist.rev propsFrom) (Safelist.rev propsTo)
+
(* ------------------------------------------------------------ *)
let copyReg = Lwt_util.make_region 50
@@ -385,10 +424,13 @@ let copy
rootFrom pathFrom (* copy from here... *)
uiFrom (* (and then check that this updateItem still
describes the current state of the src replica) *)
+ propsFrom (* the properties of the parent directories, in
+ case we need to propagate them *)
rootTo pathTo (* ...to here *)
uiTo (* (but, before committing the copy, check that
this updateItem still describes the current
state of the target replica) *)
+ propsTo (* the properties of the parent directories *)
id = (* for progress display *)
debug (fun() ->
Util.msg
@@ -396,7 +438,8 @@ let copy
(root2string rootFrom) (Path.toString pathFrom)
(root2string rootTo) (Path.toString pathTo));
(* Calculate target paths *)
- setupTargetPaths rootTo pathTo
+ setupTargetPathsAndCreateParentDirectory rootTo
+ (pathTo, normalizeProps propsFrom propsTo)
>>= fun (workingDir, realPathTo, tempPathTo, localPathTo) ->
(* When in Unicode case-insensitive mode, we want to create files
with NFC normal-form filenames. *)