]> git.proxmox.com Git - libgit2.git/commitdiff
Add new move function, `gitfo_mv_force`
authorVicent Marti <tanoku@gmail.com>
Thu, 3 Mar 2011 17:53:17 +0000 (19:53 +0200)
committerVicent Marti <tanoku@gmail.com>
Thu, 3 Mar 2011 18:23:51 +0000 (20:23 +0200)
Forces a move by creating the folder for the destination file, if it
doesn't exist.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
src/filebuf.c
src/fileops.c
src/fileops.h
src/odb_loose.c
src/refs.c

index a71c57a470f31afabf708ef6e4fb1d4e53b20ded..73f0a70f4504bce17a7b000f7d4ae65f765410d9 100644 (file)
@@ -192,7 +192,7 @@ int git_filebuf_commit(git_filebuf *file)
        gitfo_close(file->fd);
        file->fd = -1;
 
-       error = gitfo_move_file(file->path_lock, file->path_original);
+       error = gitfo_mv(file->path_lock, file->path_original);
 
 cleanup:
        git_filebuf_cleanup(file);
index 9938011d76eba113766698022dfd4e232bfcff63..7691129f62ad1bc585a6d3a221933cf9718d34dc 100644 (file)
@@ -142,7 +142,7 @@ void gitfo_free_buf(gitfo_buf *obj)
        obj->data = NULL;
 }
 
-int gitfo_move_file(char *from, char *to)
+int gitfo_mv(const char *from, const char *to)
 {
 #ifdef GIT_WIN32
        /*
@@ -165,6 +165,29 @@ int gitfo_move_file(char *from, char *to)
 #endif
 }
 
+int gitfo_mv_force(const char *from, const char *to)
+{
+       const int mode = 0755; /* or 0777 ? */
+       int error = GIT_SUCCESS;
+       char target_folder_path[GIT_PATH_MAX];
+
+       error = git__dirname_r(target_folder_path, sizeof(target_folder_path), to);
+       if (error < GIT_SUCCESS)
+               return error;
+
+       /* Does the containing folder exist? */
+       if (gitfo_isdir(target_folder_path)) {
+               git__joinpath(target_folder_path, target_folder_path, ""); /* Ensure there's a trailing slash */
+
+               /* Let's create the tree structure */
+               error = gitfo_mkdir_recurs(target_folder_path, mode);
+               if (error < GIT_SUCCESS)
+                       return error;
+       }
+
+       return gitfo_mv(from, to);
+}
+
 int gitfo_map_ro(git_map *out, git_file fd, git_off_t begin, size_t len)
 {
        if (git__mmap(out, len, GIT_PROT_READ, GIT_MAP_SHARED, fd, begin) < GIT_SUCCESS)
index 16e71038bcad7c2135e9f60e6959056437ca11b3..fd150df5ec7e0df61358382d9d77e2300b60acba 100644 (file)
@@ -68,7 +68,13 @@ extern git_off_t gitfo_size(git_file fd);
 
 extern int gitfo_read_file(gitfo_buf *obj, const char *path);
 extern void gitfo_free_buf(gitfo_buf *obj);
-extern int gitfo_move_file(char *from, char *to);
+
+/* Move (rename) a file; this operation is atomic */
+extern int gitfo_mv(const char *from, const char *to);
+
+/* Move a file (forced); this will create the destination
+ * path if it doesn't exist */
+extern int gitfo_mv_force(const char *from, const char *to);
 
 #define gitfo_stat(p,b) stat(p, b)
 #define gitfo_fstat(f,b) fstat(f, b)
index 735d9394f7620ab17d1d5f2f345a00dc687d8deb..4e2d9a639924f47b7500fe957e2648d5d0a4d1b1 100644 (file)
@@ -528,7 +528,7 @@ static int write_obj(gitfo_buf *buf, git_oid *id, loose_backend *backend)
        gitfo_close(fd);
        gitfo_chmod(temp, 0444);
 
-       if (gitfo_move_file(temp, file) < 0) {
+       if (gitfo_mv(temp, file) < 0) {
                gitfo_unlink(temp);
                return GIT_EOSERR;
        }
index 19f5406a4fc48e70e7c7afaa4b16de56330ebf41..5bbc7770e8c2c46cb5465762c2ee2861d382ce76 100644 (file)
@@ -1183,7 +1183,7 @@ int git_reference_rename(git_reference *ref, const char *new_name)
                git__joinpath(old_path, ref->owner->path_repository, old_name);
                git__joinpath(new_path, ref->owner->path_repository, ref->name);
 
-               error = gitfo_move_file(old_path, new_path);
+               error = gitfo_mv_force(old_path, new_path);
                if (error < GIT_SUCCESS)
                        goto cleanup;
 
@@ -1218,7 +1218,7 @@ rename_loose_to_old_name:
        git__joinpath(new_path, ref->owner->path_repository, old_name);
 
        /* No error checking. We'll return the initial error */
-       gitfo_move_file(old_path, new_path);
+       gitfo_mv_force(old_path, new_path);
 
        /* restore the old name */
        free(ref->name);