diff options
author | Richard Maw <richard.maw@gmail.com> | 2013-05-23 21:51:34 +0100 |
---|---|---|
committer | Richard Maw <richard.maw@gmail.com> | 2013-05-27 14:38:17 +0100 |
commit | d726b2b35c633a82428055a3d1081a4eafd02a7a (patch) | |
tree | 120d0e297ac453076f5b4b7f6849206ce3df6784 | |
parent | d3b151d89c0b0342eeb54291ded9304dcea767fa (diff) | |
download | gitano-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.lua | 51 |
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" |