mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 04:30:48 +00:00
Fix creation of deeply-rooted references
Use a new `gitfo_creat_force` that will create the full path to a file before creating it. Signed-off-by: Vicent Marti <tanoku@gmail.com>
This commit is contained in:
parent
246eba80af
commit
55ffebe377
@ -39,7 +39,12 @@ static int lock_file(git_filebuf *file, int flags)
|
||||
return GIT_EOSERR;
|
||||
}
|
||||
|
||||
file->fd = gitfo_creat(file->path_lock, 0644);
|
||||
/* create path to the file buffer is required */
|
||||
if (flags & GIT_FILEBUF_FORCE) {
|
||||
file->fd = gitfo_creat_force(file->path_lock, 0644);
|
||||
} else {
|
||||
file->fd = gitfo_creat(file->path_lock, 0644);
|
||||
}
|
||||
|
||||
if (file->fd < 0)
|
||||
return GIT_EOSERR;
|
||||
|
@ -2,6 +2,29 @@
|
||||
#include "fileops.h"
|
||||
#include <ctype.h>
|
||||
|
||||
static int force_path(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 GIT_SUCCESS;
|
||||
}
|
||||
|
||||
int gitfo_open(const char *path, int flags)
|
||||
{
|
||||
int fd = open(path, flags | O_BINARY);
|
||||
@ -14,6 +37,14 @@ int gitfo_creat(const char *path, int mode)
|
||||
return fd >= 0 ? fd : GIT_EOSERR;
|
||||
}
|
||||
|
||||
int gitfo_creat_force(const char *path, int mode)
|
||||
{
|
||||
if (force_path(path) < GIT_SUCCESS)
|
||||
return GIT_EOSERR;
|
||||
|
||||
return gitfo_creat(path, mode);
|
||||
}
|
||||
|
||||
int gitfo_read(git_file fd, void *buf, size_t cnt)
|
||||
{
|
||||
char *b = buf;
|
||||
@ -167,23 +198,8 @@ int gitfo_mv(const char *from, const char *to)
|
||||
|
||||
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;
|
||||
}
|
||||
if (force_path(to) < GIT_SUCCESS)
|
||||
return GIT_EOSERR;
|
||||
|
||||
return gitfo_mv(from, to);
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ typedef struct { /* file io buffer */
|
||||
extern int gitfo_exists(const char *path);
|
||||
extern int gitfo_open(const char *path, int flags);
|
||||
extern int gitfo_creat(const char *path, int mode);
|
||||
extern int gitfo_creat_force(const char *path, int mode);
|
||||
extern int gitfo_isdir(const char *path);
|
||||
extern int gitfo_mkdir_recurs(const char *path, int mode);
|
||||
#define gitfo_close(fd) close(fd)
|
||||
|
@ -291,7 +291,7 @@ static int loose_write(git_reference *ref)
|
||||
|
||||
git__joinpath(ref_path, ref->owner->path_repository, ref->name);
|
||||
|
||||
if ((error = git_filebuf_open(&file, ref_path, 0)) < GIT_SUCCESS)
|
||||
if ((error = git_filebuf_open(&file, ref_path, GIT_FILEBUF_FORCE)) < GIT_SUCCESS)
|
||||
return error;
|
||||
|
||||
if (ref->type & GIT_REF_OID) {
|
||||
|
Loading…
Reference in New Issue
Block a user