summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@gmail.com>2013-05-23 21:51:34 +0100
committerRichard Maw <richard.maw@gmail.com>2013-05-27 14:38:17 +0100
commitd726b2b35c633a82428055a3d1081a4eafd02a7a (patch)
tree120d0e297ac453076f5b4b7f6849206ce3df6784
parentd3b151d89c0b0342eeb54291ded9304dcea767fa (diff)
downloadgitano-d726b2b35c633a82428055a3d1081a4eafd02a7a.tar.gz
repository: add a copy_to method
This will create a repository in a different path, so it does not appear until the copy is complete.
-rw-r--r--lib/gitano/repository.lua51
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/gitano/repository.lua b/lib/gitano/repository.lua
index e6f4fee..36f9579 100644
--- a/lib/gitano/repository.lua
+++ b/lib/gitano/repository.lua
@@ -507,6 +507,57 @@ function repo_method:rename_to(somename)
return true
end
+function repo_method:copy_to(target)
+ local ok, err
+
+ if not target.is_nascent then
+ return false, "Target repository is not Nascent"
+ end
+
+ local newpath = target:fs_path()
+ -- copy to a different path so it does not appear until finished
+ local temp_path = newpath .. ".in_progress"
+
+ if not util.mkdir_p(util.dirname(temp_path)) then
+ return false, "Cannot prepare path leading to repository."
+ end
+
+ local from = self:fs_path()
+ local function filter(parent, name, info)
+ return parent == from and name == "objects"
+ or util.copy_dir_filter_base(parent, name, info)
+ end
+ -- copy non-objects parts of the git repository
+ ok, err = util.copy_dir(from, temp_path, nil, filter)
+ if not ok then
+ log.error("Failed to copy repository", from, "to", temp_path, err)
+ util.rm_rf(temp_path)
+ return false, "Failed to copy repository"
+ end
+ -- Hardlink the objects tree
+ local cbs = util.deep_copy(util.copy_dir_copy_callbacks)
+ cbs[luxio.DT_REG] = util.hardlink_file
+ ok, err = util.copy_dir(util.path_join(from, 'objects'),
+ util.path_join(temp_path, 'objects'),
+ cbs)
+ if not ok then
+ log.error("Failed to hardlink objects of", from, "to", temp_path, err)
+ util.rm_rf(temp_path)
+ return ok, "Failed to copy repository"
+ end
+
+ -- rename into place
+ ok, err = luxio.rename(temp_path, newpath)
+ if ok ~= 0 then
+ log.error("Failed to rename repository", temp_path, "to",
+ newpath, luxio.strerror(err))
+ util.rm_rf(temp_path)
+ return false, "Failed to copy repository"
+ end
+
+ return true
+end
+
function repo_method:update_modified_date(shas)
-- Update the info/web/last-modified
local dirpath = self:fs_path() .. "/info/web"