mirror of
https://git.proxmox.com/git/libgit2
synced 2025-07-16 09:29:29 +00:00
More filemode cleanups for FAT on MacOS
This cleans up some additional issues. The main change is that on a filesystem that doesn't support mode bits, libgit2 will now create new blobs with GIT_FILEMODE_BLOB always instead of being at the mercy to the filesystem driver to report executable or not. This means that if "core.filemode" lies and claims that filemode is not supported, then we will ignore the executable bit from the filesystem. Previously we would have allowed it. This adds an option to the new git_repository_reset_filesystem to recurse through submodules if desired. There may be other types of APIs that would like a "recurse submodules" option, but this one is particularly useful. This also has a number of cleanups, etc., for related things including trying to give better error messages when problems come up from the filesystem. For example, the FAT filesystem driver on MacOS appears to return errno EINVAL if you attempt to write a filename with invalid UTF-8 in it. We try to capture that with a better error message now.
This commit is contained in:
parent
5173ea921d
commit
14997dc5f6
@ -299,10 +299,12 @@ GIT_EXTERN(int) git_repository_init_ext(
|
|||||||
* properties to compensate for the current filesystem of the repo.
|
* properties to compensate for the current filesystem of the repo.
|
||||||
*
|
*
|
||||||
* @param repo A repository object
|
* @param repo A repository object
|
||||||
|
* @param recurse_submodules Should submodules be reset recursively
|
||||||
* @returrn 0 on success, < 0 on error
|
* @returrn 0 on success, < 0 on error
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_repository_reset_filesystem(
|
GIT_EXTERN(int) git_repository_reset_filesystem(
|
||||||
git_repository *repo);
|
git_repository *repo,
|
||||||
|
int recurse_submodules);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve and resolve the reference pointed at by HEAD.
|
* Retrieve and resolve the reference pointed at by HEAD.
|
||||||
|
@ -783,7 +783,8 @@ static int checkout_update_index(
|
|||||||
|
|
||||||
memset(&entry, 0, sizeof(entry));
|
memset(&entry, 0, sizeof(entry));
|
||||||
entry.path = (char *)file->path; /* cast to prevent warning */
|
entry.path = (char *)file->path; /* cast to prevent warning */
|
||||||
git_index_entry__init_from_stat(&entry, st);
|
git_index_entry__init_from_stat(
|
||||||
|
&entry, st, !(git_index_caps(data->index) & GIT_INDEXCAP_NO_FILEMODE));
|
||||||
git_oid_cpy(&entry.oid, &file->oid);
|
git_oid_cpy(&entry.oid, &file->oid);
|
||||||
|
|
||||||
return git_index_add(data->index, &entry);
|
return git_index_add(data->index, &entry);
|
||||||
|
@ -116,4 +116,3 @@ const git_error *giterr_last(void)
|
|||||||
{
|
{
|
||||||
return GIT_GLOBAL->last_error;
|
return GIT_GLOBAL->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,11 +78,8 @@ int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, con
|
|||||||
int git_futils_open_ro(const char *path)
|
int git_futils_open_ro(const char *path)
|
||||||
{
|
{
|
||||||
int fd = p_open(path, O_RDONLY);
|
int fd = p_open(path, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0)
|
||||||
if (errno == ENOENT || errno == ENOTDIR)
|
return git_path_set_error(errno, path, "open");
|
||||||
fd = GIT_ENOTFOUND;
|
|
||||||
giterr_set(GITERR_OS, "Failed to open '%s'", path);
|
|
||||||
}
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +135,6 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
|
|||||||
int git_futils_readbuffer_updated(
|
int git_futils_readbuffer_updated(
|
||||||
git_buf *buf, const char *path, time_t *mtime, size_t *size, int *updated)
|
git_buf *buf, const char *path, time_t *mtime, size_t *size, int *updated)
|
||||||
{
|
{
|
||||||
int error = 0;
|
|
||||||
git_file fd;
|
git_file fd;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
@ -148,13 +144,8 @@ int git_futils_readbuffer_updated(
|
|||||||
if (updated != NULL)
|
if (updated != NULL)
|
||||||
*updated = 0;
|
*updated = 0;
|
||||||
|
|
||||||
if (p_stat(path, &st) < 0) {
|
if (p_stat(path, &st) < 0)
|
||||||
error = errno;
|
return git_path_set_error(errno, path, "stat");
|
||||||
giterr_set(GITERR_OS, "Failed to stat '%s'", path);
|
|
||||||
if (error == ENOENT || error == ENOTDIR)
|
|
||||||
return GIT_ENOTFOUND;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISDIR(st.st_mode) || !git__is_sizet(st.st_size+1)) {
|
if (S_ISDIR(st.st_mode) || !git__is_sizet(st.st_size+1)) {
|
||||||
giterr_set(GITERR_OS, "Invalid regular file stat for '%s'", path);
|
giterr_set(GITERR_OS, "Invalid regular file stat for '%s'", path);
|
||||||
@ -441,66 +432,60 @@ static int futils__rm_first_parent(git_buf *path, const char *ceiling)
|
|||||||
|
|
||||||
static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
|
static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
|
||||||
futils__rmdir_data *data = opaque;
|
futils__rmdir_data *data = opaque;
|
||||||
|
int error = data->error;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
if (data->depth > FUTILS_MAX_DEPTH) {
|
if (data->depth > FUTILS_MAX_DEPTH)
|
||||||
data->error =
|
error = futils__error_cannot_rmdir(
|
||||||
futils__error_cannot_rmdir(path->ptr, "directory nesting too deep");
|
path->ptr, "directory nesting too deep");
|
||||||
}
|
|
||||||
|
|
||||||
else if ((data->error = p_lstat_posixly(path->ptr, &st)) < 0) {
|
else if ((error = p_lstat_posixly(path->ptr, &st)) < 0) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
data->error = 0;
|
error = 0;
|
||||||
else if (errno == ENOTDIR) {
|
else if (errno == ENOTDIR) {
|
||||||
/* asked to remove a/b/c/d/e and a/b is a normal file */
|
/* asked to remove a/b/c/d/e and a/b is a normal file */
|
||||||
if ((data->flags & GIT_RMDIR_REMOVE_BLOCKERS) != 0)
|
if ((data->flags & GIT_RMDIR_REMOVE_BLOCKERS) != 0)
|
||||||
data->error = futils__rm_first_parent(path, data->base);
|
error = futils__rm_first_parent(path, data->base);
|
||||||
else
|
else
|
||||||
futils__error_cannot_rmdir(
|
futils__error_cannot_rmdir(
|
||||||
path->ptr, "parent is not directory");
|
path->ptr, "parent is not directory");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
futils__error_cannot_rmdir(path->ptr, "cannot access");
|
error = git_path_set_error(errno, path->ptr, "rmdir");
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (S_ISDIR(st.st_mode)) {
|
else if (S_ISDIR(st.st_mode)) {
|
||||||
data->depth++;
|
data->depth++;
|
||||||
|
|
||||||
{
|
error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data);
|
||||||
int error =
|
if (error < 0)
|
||||||
git_path_direach(path, 0, futils__rmdir_recurs_foreach, data);
|
return (error == GIT_EUSER) ? data->error : error;
|
||||||
if (error < 0)
|
|
||||||
return (error == GIT_EUSER) ? data->error : error;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->depth--;
|
data->depth--;
|
||||||
|
|
||||||
if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0)
|
if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0)
|
||||||
return data->error;
|
return data->error;
|
||||||
|
|
||||||
data->error = p_rmdir(path->ptr);
|
if ((error = p_rmdir(path->ptr)) < 0) {
|
||||||
|
|
||||||
if (data->error < 0) {
|
|
||||||
if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 &&
|
if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 &&
|
||||||
(errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY))
|
(errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY))
|
||||||
data->error = 0;
|
error = 0;
|
||||||
else
|
else
|
||||||
futils__error_cannot_rmdir(path->ptr, NULL);
|
error = git_path_set_error(errno, path->ptr, "rmdir");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((data->flags & GIT_RMDIR_REMOVE_FILES) != 0) {
|
else if ((data->flags & GIT_RMDIR_REMOVE_FILES) != 0) {
|
||||||
data->error = p_unlink(path->ptr);
|
if (p_unlink(path->ptr) < 0)
|
||||||
|
error = git_path_set_error(errno, path->ptr, "remove");
|
||||||
if (data->error < 0)
|
|
||||||
futils__error_cannot_rmdir(path->ptr, "cannot be removed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0)
|
else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0)
|
||||||
data->error = futils__error_cannot_rmdir(path->ptr, "still present");
|
error = futils__error_cannot_rmdir(path->ptr, "still present");
|
||||||
|
|
||||||
return data->error;
|
data->error = error;
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
|
static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
|
||||||
@ -523,7 +508,7 @@ static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
|
|||||||
giterr_clear();
|
giterr_clear();
|
||||||
error = GIT_ITEROVER;
|
error = GIT_ITEROVER;
|
||||||
} else {
|
} else {
|
||||||
futils__error_cannot_rmdir(git_buf_cstr(path), NULL);
|
error = git_path_set_error(errno, git_buf_cstr(path), "rmdir");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -818,11 +803,8 @@ int git_futils_cp(const char *from, const char *to, mode_t filemode)
|
|||||||
return ifd;
|
return ifd;
|
||||||
|
|
||||||
if ((ofd = p_open(to, O_WRONLY | O_CREAT | O_EXCL, filemode)) < 0) {
|
if ((ofd = p_open(to, O_WRONLY | O_CREAT | O_EXCL, filemode)) < 0) {
|
||||||
if (errno == ENOENT || errno == ENOTDIR)
|
|
||||||
ofd = GIT_ENOTFOUND;
|
|
||||||
giterr_set(GITERR_OS, "Failed to open '%s' for writing", to);
|
|
||||||
p_close(ifd);
|
p_close(ifd);
|
||||||
return ofd;
|
return git_path_set_error(errno, to, "open for writing");
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp_by_fd(ifd, ofd, true);
|
return cp_by_fd(ifd, ofd, true);
|
||||||
@ -905,15 +887,14 @@ static int _cp_r_callback(void *ref, git_buf *from)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_lstat(info->to.ptr, &to_st) < 0) {
|
if (!(error = git_path_lstat(info->to.ptr, &to_st)))
|
||||||
if (errno != ENOENT && errno != ENOTDIR) {
|
|
||||||
giterr_set(GITERR_OS,
|
|
||||||
"Could not access %s while copying files", info->to.ptr);
|
|
||||||
error = -1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
exists = true;
|
exists = true;
|
||||||
|
else if (error != GIT_ENOTFOUND)
|
||||||
|
goto exit;
|
||||||
|
else {
|
||||||
|
giterr_clear();
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((error = git_path_lstat(from->ptr, &from_st)) < 0)
|
if ((error = git_path_lstat(from->ptr, &from_st)) < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -579,7 +579,8 @@ const git_index_entry *git_index_get_bypath(
|
|||||||
return git_index_get_byindex(index, pos);
|
return git_index_get_byindex(index, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_index_entry__init_from_stat(git_index_entry *entry, struct stat *st)
|
void git_index_entry__init_from_stat(
|
||||||
|
git_index_entry *entry, struct stat *st, bool trust_mode)
|
||||||
{
|
{
|
||||||
entry->ctime.seconds = (git_time_t)st->st_ctime;
|
entry->ctime.seconds = (git_time_t)st->st_ctime;
|
||||||
entry->mtime.seconds = (git_time_t)st->st_mtime;
|
entry->mtime.seconds = (git_time_t)st->st_mtime;
|
||||||
@ -587,7 +588,8 @@ void git_index_entry__init_from_stat(git_index_entry *entry, struct stat *st)
|
|||||||
/* entry->ctime.nanoseconds = st->st_ctimensec; */
|
/* entry->ctime.nanoseconds = st->st_ctimensec; */
|
||||||
entry->dev = st->st_rdev;
|
entry->dev = st->st_rdev;
|
||||||
entry->ino = st->st_ino;
|
entry->ino = st->st_ino;
|
||||||
entry->mode = index_create_mode(st->st_mode);
|
entry->mode = (!trust_mode && S_ISREG(st->st_mode)) ?
|
||||||
|
index_create_mode(0666) : index_create_mode(st->st_mode);
|
||||||
entry->uid = st->st_uid;
|
entry->uid = st->st_uid;
|
||||||
entry->gid = st->st_gid;
|
entry->gid = st->st_gid;
|
||||||
entry->file_size = st->st_size;
|
entry->file_size = st->st_size;
|
||||||
@ -631,7 +633,7 @@ static int index_entry_init(
|
|||||||
entry = git__calloc(1, sizeof(git_index_entry));
|
entry = git__calloc(1, sizeof(git_index_entry));
|
||||||
GITERR_CHECK_ALLOC(entry);
|
GITERR_CHECK_ALLOC(entry);
|
||||||
|
|
||||||
git_index_entry__init_from_stat(entry, &st);
|
git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
|
||||||
|
|
||||||
entry->oid = oid;
|
entry->oid = oid;
|
||||||
entry->path = git__strdup(rel_path);
|
entry->path = git__strdup(rel_path);
|
||||||
|
@ -48,7 +48,7 @@ struct git_index_conflict_iterator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void git_index_entry__init_from_stat(
|
extern void git_index_entry__init_from_stat(
|
||||||
git_index_entry *entry, struct stat *st);
|
git_index_entry *entry, struct stat *st, bool trust_mode);
|
||||||
|
|
||||||
extern size_t git_index__prefix_position(git_index *index, const char *path);
|
extern size_t git_index__prefix_position(git_index *index, const char *path);
|
||||||
|
|
||||||
|
@ -1175,7 +1175,7 @@ static int fs_iterator__update_entry(fs_iterator *fi)
|
|||||||
return GIT_ITEROVER;
|
return GIT_ITEROVER;
|
||||||
|
|
||||||
fi->entry.path = ps->path;
|
fi->entry.path = ps->path;
|
||||||
git_index_entry__init_from_stat(&fi->entry, &ps->st);
|
git_index_entry__init_from_stat(&fi->entry, &ps->st, true);
|
||||||
|
|
||||||
/* need different mode here to keep directories during iteration */
|
/* need different mode here to keep directories during iteration */
|
||||||
fi->entry.mode = git_futils_canonical_mode(ps->st.st_mode);
|
fi->entry.mode = git_futils_canonical_mode(ps->st.st_mode);
|
||||||
|
33
src/path.c
33
src/path.c
@ -538,16 +538,35 @@ bool git_path_is_empty_dir(const char *path)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int git_path_set_error(int errno_value, const char *path, const char *action)
|
||||||
|
{
|
||||||
|
switch (errno_value) {
|
||||||
|
case ENOENT:
|
||||||
|
case ENOTDIR:
|
||||||
|
giterr_set(GITERR_OS, "Could not find '%s' to %s", path, action);
|
||||||
|
return GIT_ENOTFOUND;
|
||||||
|
|
||||||
|
case EINVAL:
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
giterr_set(GITERR_OS, "Invalid path for filesystem '%s'", path);
|
||||||
|
return GIT_EINVALIDSPEC;
|
||||||
|
|
||||||
|
case EEXIST:
|
||||||
|
giterr_set(GITERR_OS, "Failed %s - '%s' already exists", action, path);
|
||||||
|
return GIT_EEXISTS;
|
||||||
|
|
||||||
|
default:
|
||||||
|
giterr_set(GITERR_OS, "Could not %s '%s'", action, path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int git_path_lstat(const char *path, struct stat *st)
|
int git_path_lstat(const char *path, struct stat *st)
|
||||||
{
|
{
|
||||||
int err = 0;
|
if (p_lstat(path, st) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (p_lstat(path, st) < 0) {
|
return git_path_set_error(errno, path, "stat");
|
||||||
err = (errno == ENOENT) ? GIT_ENOTFOUND : -1;
|
|
||||||
giterr_set(GITERR_OS, "Failed to stat file '%s'", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _check_dir_contents(
|
static bool _check_dir_contents(
|
||||||
|
@ -358,6 +358,10 @@ extern int git_path_dirload_with_stat(
|
|||||||
const char *end_stat,
|
const char *end_stat,
|
||||||
git_vector *contents);
|
git_vector *contents);
|
||||||
|
|
||||||
|
/* translate errno to libgit2 error code and set error message */
|
||||||
|
extern int git_path_set_error(
|
||||||
|
int errno_value, const char *path, const char *action);
|
||||||
|
|
||||||
/* check if non-ascii characters are present in filename */
|
/* check if non-ascii characters are present in filename */
|
||||||
extern bool git_path_has_non_ascii(const char *path, size_t pathlen);
|
extern bool git_path_has_non_ascii(const char *path, size_t pathlen);
|
||||||
|
|
||||||
|
199
src/repository.c
199
src/repository.c
@ -961,80 +961,121 @@ static int create_empty_file(const char *path, mode_t mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int repo_local_config(
|
||||||
|
git_config **out,
|
||||||
|
git_buf *config_dir,
|
||||||
|
git_repository *repo,
|
||||||
|
const char *repo_dir)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
git_config *parent;
|
||||||
|
const char *cfg_path;
|
||||||
|
|
||||||
|
if (git_buf_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
|
||||||
|
return -1;
|
||||||
|
cfg_path = git_buf_cstr(config_dir);
|
||||||
|
|
||||||
|
/* make LOCAL config if missing */
|
||||||
|
if (!git_path_isfile(cfg_path) &&
|
||||||
|
(error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
/* if no repo, just open that file directly */
|
||||||
|
if (!repo)
|
||||||
|
return git_config_open_ondisk(out, cfg_path);
|
||||||
|
|
||||||
|
/* otherwise, open parent config and get that level */
|
||||||
|
if ((error = git_repository_config__weakptr(&parent, repo)) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL) < 0) {
|
||||||
|
giterr_clear();
|
||||||
|
|
||||||
|
if (!(error = git_config_add_file_ondisk(
|
||||||
|
parent, cfg_path, GIT_CONFIG_LEVEL_LOCAL, false)))
|
||||||
|
error = git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
git_config_free(parent);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int repo_init_fs_configs(
|
||||||
|
git_config *cfg,
|
||||||
|
const char *cfg_path,
|
||||||
|
const char *repo_dir,
|
||||||
|
const char *work_dir,
|
||||||
|
bool update_ignorecase)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
if (!work_dir)
|
||||||
|
work_dir = repo_dir;
|
||||||
|
|
||||||
|
if ((error = git_config_set_bool(
|
||||||
|
cfg, "core.filemode", is_chmod_supported(cfg_path))) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (!are_symlinks_supported(work_dir)) {
|
||||||
|
if ((error = git_config_set_bool(cfg, "core.symlinks", false)) < 0)
|
||||||
|
return error;
|
||||||
|
} else if (git_config_delete_entry(cfg, "core.symlinks") < 0)
|
||||||
|
giterr_clear();
|
||||||
|
|
||||||
|
if (update_ignorecase) {
|
||||||
|
if (is_filesystem_case_insensitive(repo_dir)) {
|
||||||
|
if ((error = git_config_set_bool(cfg, "core.ignorecase", true)) < 0)
|
||||||
|
return error;
|
||||||
|
} else if (git_config_delete_entry(cfg, "core.ignorecase") < 0)
|
||||||
|
giterr_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GIT_USE_ICONV
|
||||||
|
if ((error = git_config_set_bool(
|
||||||
|
cfg, "core.precomposeunicode",
|
||||||
|
does_fs_decompose_unicode_paths(work_dir))) < 0)
|
||||||
|
return error;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int repo_init_config(
|
static int repo_init_config(
|
||||||
git_config *parent,
|
|
||||||
const char *repo_dir,
|
const char *repo_dir,
|
||||||
const char *work_dir,
|
const char *work_dir,
|
||||||
uint32_t flags,
|
uint32_t flags,
|
||||||
uint32_t mode)
|
uint32_t mode)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
git_buf buf = GIT_BUF_INIT;
|
git_buf cfg_path = GIT_BUF_INIT;
|
||||||
const char *cfg_path = NULL;
|
|
||||||
git_config *config = NULL;
|
git_config *config = NULL;
|
||||||
bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
|
bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
|
||||||
|
bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
|
||||||
|
|
||||||
#define SET_REPO_CONFIG(TYPE, NAME, VAL) do {\
|
if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (is_reinit && (error = check_repositoryformatversion(config)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
#define SET_REPO_CONFIG(TYPE, NAME, VAL) do { \
|
||||||
if ((error = git_config_set_##TYPE(config, NAME, VAL)) < 0) \
|
if ((error = git_config_set_##TYPE(config, NAME, VAL)) < 0) \
|
||||||
goto cleanup; } while (0)
|
goto cleanup; } while (0)
|
||||||
|
|
||||||
if (git_buf_joinpath(&buf, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
|
SET_REPO_CONFIG(bool, "core.bare", is_bare);
|
||||||
return -1;
|
SET_REPO_CONFIG(int32, "core.repositoryformatversion", GIT_REPO_VERSION);
|
||||||
cfg_path = git_buf_cstr(&buf);
|
|
||||||
|
|
||||||
if (!git_path_isfile(cfg_path) &&
|
if ((error = repo_init_fs_configs(
|
||||||
(error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0)
|
config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!parent)
|
|
||||||
error = git_config_open_ondisk(&config, cfg_path);
|
|
||||||
else if ((error = git_config_open_level(
|
|
||||||
&config, parent, GIT_CONFIG_LEVEL_LOCAL)) < 0)
|
|
||||||
{
|
|
||||||
giterr_clear();
|
|
||||||
|
|
||||||
if (!(error = git_config_add_file_ondisk(
|
|
||||||
parent, cfg_path, GIT_CONFIG_LEVEL_LOCAL, false)))
|
|
||||||
error = git_config_open_level(
|
|
||||||
&config, parent, GIT_CONFIG_LEVEL_LOCAL);
|
|
||||||
}
|
|
||||||
if (error < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0 &&
|
|
||||||
(error = check_repositoryformatversion(config)) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
SET_REPO_CONFIG(
|
|
||||||
bool, "core.bare", is_bare);
|
|
||||||
SET_REPO_CONFIG(
|
|
||||||
int32, "core.repositoryformatversion", GIT_REPO_VERSION);
|
|
||||||
SET_REPO_CONFIG(
|
|
||||||
bool, "core.filemode", is_chmod_supported(cfg_path));
|
|
||||||
|
|
||||||
#ifdef GIT_USE_ICONV
|
|
||||||
SET_REPO_CONFIG(
|
|
||||||
bool, "core.precomposeunicode",
|
|
||||||
does_fs_decompose_unicode_paths(is_bare ? repo_dir : work_dir));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!are_symlinks_supported(is_bare ? repo_dir : work_dir))
|
|
||||||
SET_REPO_CONFIG(bool, "core.symlinks", false);
|
|
||||||
|
|
||||||
/* core git does not do this on a reinit, but it is a property of
|
|
||||||
* the filesystem, so I think we should...
|
|
||||||
*/
|
|
||||||
if (!(flags & GIT_REPOSITORY_INIT__IS_REINIT) &&
|
|
||||||
is_filesystem_case_insensitive(repo_dir))
|
|
||||||
SET_REPO_CONFIG(bool, "core.ignorecase", true);
|
|
||||||
|
|
||||||
if (!is_bare) {
|
if (!is_bare) {
|
||||||
SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
|
SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
|
||||||
|
|
||||||
if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) {
|
if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD))
|
||||||
SET_REPO_CONFIG(string, "core.worktree", work_dir);
|
SET_REPO_CONFIG(string, "core.worktree", work_dir);
|
||||||
}
|
else if (is_reinit) {
|
||||||
else if ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0) {
|
|
||||||
if (git_config_delete_entry(config, "core.worktree") < 0)
|
if (git_config_delete_entry(config, "core.worktree") < 0)
|
||||||
giterr_clear();
|
giterr_clear();
|
||||||
}
|
}
|
||||||
@ -1050,38 +1091,44 @@ static int repo_init_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
git_buf_free(&buf);
|
git_buf_free(&cfg_path);
|
||||||
git_config_free(config);
|
git_config_free(config);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_repository_reset_filesystem(git_repository *repo)
|
static int repo_reset_submodule_fs(git_submodule *sm, const char *n, void *p)
|
||||||
|
{
|
||||||
|
git_repository *smrepo = NULL;
|
||||||
|
GIT_UNUSED(n); GIT_UNUSED(p);
|
||||||
|
|
||||||
|
if (git_submodule_open(&smrepo, sm) < 0 ||
|
||||||
|
git_repository_reset_filesystem(smrepo, true) < 0)
|
||||||
|
giterr_clear();
|
||||||
|
git_repository_free(smrepo);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int git_repository_reset_filesystem(git_repository *repo, int recurse)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
uint32_t flags = 0;
|
git_buf path = GIT_BUF_INIT;
|
||||||
const char *repo_dir, *work_dir;
|
git_config *config = NULL;
|
||||||
git_config *cfg;
|
const char *repo_dir = git_repository_path(repo);
|
||||||
|
|
||||||
assert(repo);
|
if (!(error = repo_local_config(&config, &path, repo, repo_dir)))
|
||||||
|
error = repo_init_fs_configs(
|
||||||
|
config, path.ptr, repo_dir, git_repository_workdir(repo), true);
|
||||||
|
|
||||||
repo_dir = git_repository_path(repo);
|
git_config_free(config);
|
||||||
work_dir = git_repository_workdir(repo);
|
git_buf_free(&path);
|
||||||
|
|
||||||
if (git_repository_is_bare(repo))
|
|
||||||
flags |= GIT_REPOSITORY_INIT_BARE;
|
|
||||||
else if (!git__prefixcmp(repo_dir, work_dir) &&
|
|
||||||
!strcmp(repo_dir + strlen(work_dir), DOT_GIT "/"))
|
|
||||||
flags |= GIT_REPOSITORY_INIT__NATURAL_WD;
|
|
||||||
|
|
||||||
if ((error = git_repository_config(&cfg, repo)) < 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
error = repo_init_config(cfg, repo_dir, work_dir, flags, 0);
|
|
||||||
|
|
||||||
git_config_free(cfg);
|
|
||||||
git_repository__cvar_cache_clear(repo);
|
git_repository__cvar_cache_clear(repo);
|
||||||
|
|
||||||
|
if (!repo->is_bare && recurse)
|
||||||
|
(void)git_submodule_foreach(repo, repo_reset_submodule_fs, NULL);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1473,7 +1520,7 @@ int git_repository_init_ext(
|
|||||||
opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
|
opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
|
||||||
|
|
||||||
error = repo_init_config(
|
error = repo_init_config(
|
||||||
NULL, repo_path.ptr, wd_path.ptr, opts->flags, opts->mode);
|
repo_path.ptr, wd_path.ptr, opts->flags, opts->mode);
|
||||||
|
|
||||||
/* TODO: reinitialize the templates */
|
/* TODO: reinitialize the templates */
|
||||||
}
|
}
|
||||||
@ -1481,7 +1528,7 @@ int git_repository_init_ext(
|
|||||||
if (!(error = repo_init_structure(
|
if (!(error = repo_init_structure(
|
||||||
repo_path.ptr, wd_path.ptr, opts)) &&
|
repo_path.ptr, wd_path.ptr, opts)) &&
|
||||||
!(error = repo_init_config(
|
!(error = repo_init_config(
|
||||||
NULL, repo_path.ptr, wd_path.ptr, opts->flags, opts->mode)))
|
repo_path.ptr, wd_path.ptr, opts->flags, opts->mode)))
|
||||||
error = repo_init_create_head(
|
error = repo_init_create_head(
|
||||||
repo_path.ptr, opts->initial_head);
|
repo_path.ptr, opts->initial_head);
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,8 @@ int git_submodule_add_to_index(git_submodule *sm, int write_index)
|
|||||||
|
|
||||||
memset(&entry, 0, sizeof(entry));
|
memset(&entry, 0, sizeof(entry));
|
||||||
entry.path = sm->path;
|
entry.path = sm->path;
|
||||||
git_index_entry__init_from_stat(&entry, &st);
|
git_index_entry__init_from_stat(
|
||||||
|
&entry, &st, !(git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE));
|
||||||
|
|
||||||
/* calling git_submodule_open will have set sm->wd_oid if possible */
|
/* calling git_submodule_open will have set sm->wd_oid if possible */
|
||||||
if ((sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) == 0) {
|
if ((sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) == 0) {
|
||||||
|
@ -125,8 +125,8 @@ static int do_lstat(
|
|||||||
|
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
|
|
||||||
/* We need POSIX behavior, then ENOTDIR must set when any of the folders in the
|
/* To match POSIX behavior, set ENOTDIR when any of the folders in the
|
||||||
* file path is a regular file,otherwise ENOENT must be set.
|
* file path is a regular file, otherwise set ENOENT.
|
||||||
*/
|
*/
|
||||||
if (posix_enotdir) {
|
if (posix_enotdir) {
|
||||||
/* scan up path until we find an existing item */
|
/* scan up path until we find an existing item */
|
||||||
|
@ -191,7 +191,7 @@ git_repository *cl_git_sandbox_init(const char *sandbox)
|
|||||||
cl_git_pass(git_repository_open(&_cl_repo, sandbox));
|
cl_git_pass(git_repository_open(&_cl_repo, sandbox));
|
||||||
|
|
||||||
/* Adjust configs after copying to new filesystem */
|
/* Adjust configs after copying to new filesystem */
|
||||||
cl_git_pass(git_repository_reset_filesystem(_cl_repo));
|
cl_git_pass(git_repository_reset_filesystem(_cl_repo, 0));
|
||||||
|
|
||||||
return _cl_repo;
|
return _cl_repo;
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
|
|||||||
git_repository_set_config(g_repo, cfg);
|
git_repository_set_config(g_repo, cfg);
|
||||||
git_config_free(cfg);
|
git_config_free(cfg);
|
||||||
|
|
||||||
git_repository_reset_filesystem(g_repo);
|
git_repository_reset_filesystem(g_repo, false);
|
||||||
|
|
||||||
cl_git_pass(
|
cl_git_pass(
|
||||||
git_futils_readbuffer(&old_content, "renames/songof7cities.txt"));
|
git_futils_readbuffer(&old_content, "renames/songof7cities.txt"));
|
||||||
@ -524,7 +524,7 @@ void test_diff_patch__line_counts_with_eofnl(void)
|
|||||||
git_repository_set_config(g_repo, cfg);
|
git_repository_set_config(g_repo, cfg);
|
||||||
git_config_free(cfg);
|
git_config_free(cfg);
|
||||||
|
|
||||||
git_repository_reset_filesystem(g_repo);
|
git_repository_reset_filesystem(g_repo, false);
|
||||||
|
|
||||||
cl_git_pass(git_futils_readbuffer(&content, "renames/songof7cities.txt"));
|
cl_git_pass(git_futils_readbuffer(&content, "renames/songof7cities.txt"));
|
||||||
|
|
||||||
|
@ -761,16 +761,7 @@ void test_diff_workdir__submodules(void)
|
|||||||
git_diff_list *diff = NULL;
|
git_diff_list *diff = NULL;
|
||||||
diff_expects exp;
|
diff_expects exp;
|
||||||
|
|
||||||
g_repo = cl_git_sandbox_init("submod2");
|
g_repo = setup_fixture_submod2();
|
||||||
|
|
||||||
cl_fixture_sandbox("submod2_target");
|
|
||||||
p_rename("submod2_target/.gitted", "submod2_target/.git");
|
|
||||||
|
|
||||||
rewrite_gitmodules(git_repository_workdir(g_repo));
|
|
||||||
p_rename("submod2/not-submodule/.gitted", "submod2/not-submodule/.git");
|
|
||||||
p_rename("submod2/not/.gitted", "submod2/not/.git");
|
|
||||||
|
|
||||||
cl_fixture_cleanup("submod2_target");
|
|
||||||
|
|
||||||
a = resolve_commit_oid_to_tree(g_repo, a_commit);
|
a = resolve_commit_oid_to_tree(g_repo, a_commit);
|
||||||
|
|
||||||
|
@ -111,8 +111,9 @@ static void check_stat_data(git_index *index, const char *path, bool match)
|
|||||||
cl_assert(st.st_gid == entry->gid);
|
cl_assert(st.st_gid == entry->gid);
|
||||||
cl_assert_equal_i_fmt(
|
cl_assert_equal_i_fmt(
|
||||||
GIT_MODE_TYPE(st.st_mode), GIT_MODE_TYPE(entry->mode), "%07o");
|
GIT_MODE_TYPE(st.st_mode), GIT_MODE_TYPE(entry->mode), "%07o");
|
||||||
cl_assert_equal_b(
|
if (cl_is_chmod_supported())
|
||||||
GIT_PERMS_IS_EXEC(st.st_mode), GIT_PERMS_IS_EXEC(entry->mode));
|
cl_assert_equal_b(
|
||||||
|
GIT_PERMS_IS_EXEC(st.st_mode), GIT_PERMS_IS_EXEC(entry->mode));
|
||||||
} else {
|
} else {
|
||||||
/* most things will still match */
|
/* most things will still match */
|
||||||
cl_assert(st.st_size != entry->file_size);
|
cl_assert(st.st_size != entry->file_size);
|
||||||
|
@ -74,7 +74,6 @@ static void add_and_check_mode_(
|
|||||||
void test_index_filemodes__untrusted(void)
|
void test_index_filemodes__untrusted(void)
|
||||||
{
|
{
|
||||||
git_index *index;
|
git_index *index;
|
||||||
bool can_filemode = cl_is_chmod_supported();
|
|
||||||
|
|
||||||
cl_repo_set_bool(g_repo, "core.filemode", false);
|
cl_repo_set_bool(g_repo, "core.filemode", false);
|
||||||
|
|
||||||
@ -97,20 +96,15 @@ void test_index_filemodes__untrusted(void)
|
|||||||
replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
|
replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
|
||||||
add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);
|
add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);
|
||||||
|
|
||||||
/* these tests of newly added files won't give predictable results on
|
/* 5 - add new 0644 -> expect 0644 */
|
||||||
* filesystems without actual filemode support, so skip them.
|
cl_git_write2file("filemodes/new_off", "blah", 0,
|
||||||
*/
|
O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
if (can_filemode) {
|
add_and_check_mode(index, "new_off", GIT_FILEMODE_BLOB);
|
||||||
/* 5 - add new 0644 -> expect 0644 */
|
|
||||||
cl_git_write2file("filemodes/new_off", "blah", 0,
|
|
||||||
O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
||||||
add_and_check_mode(index, "new_off", GIT_FILEMODE_BLOB);
|
|
||||||
|
|
||||||
/* 6 - add new 0755 -> expect 0755 */
|
/* 6 - add new 0755 -> expect 0644 if core.filemode == false */
|
||||||
cl_git_write2file("filemodes/new_on", "blah", 0,
|
cl_git_write2file("filemodes/new_on", "blah", 0,
|
||||||
O_WRONLY | O_CREAT | O_TRUNC, 0755);
|
O_WRONLY | O_CREAT | O_TRUNC, 0755);
|
||||||
add_and_check_mode(index, "new_on", GIT_FILEMODE_BLOB_EXECUTABLE);
|
add_and_check_mode(index, "new_on", GIT_FILEMODE_BLOB);
|
||||||
}
|
|
||||||
|
|
||||||
git_index_free(index);
|
git_index_free(index);
|
||||||
}
|
}
|
||||||
|
@ -22,23 +22,38 @@ void test_refs_unicode__create_and_lookup(void)
|
|||||||
git_reference *ref0, *ref1, *ref2;
|
git_reference *ref0, *ref1, *ref2;
|
||||||
git_repository *repo2;
|
git_repository *repo2;
|
||||||
|
|
||||||
const char *REFNAME = "refs/heads/" "\305" "ngstr" "\366" "m";
|
const char *REFNAME = "refs/heads/" "\303\205" "ngstr" "\303\266" "m";
|
||||||
|
const char *REFNAME_DECOMPOSED =
|
||||||
|
"refs/heads/" "A" "\314\212" "ngstro" "\314\210" "m";
|
||||||
const char *master = "refs/heads/master";
|
const char *master = "refs/heads/master";
|
||||||
|
|
||||||
/* Create the reference */
|
/* Create the reference */
|
||||||
cl_git_pass(git_reference_lookup(&ref0, repo, master));
|
cl_git_pass(git_reference_lookup(&ref0, repo, master));
|
||||||
cl_git_pass(git_reference_create(&ref1, repo, REFNAME, git_reference_target(ref0), 0));
|
cl_git_pass(git_reference_create(&ref1, repo, REFNAME, git_reference_target(ref0), 0));
|
||||||
cl_assert_equal_s(REFNAME, git_reference_name(ref1));
|
cl_assert_equal_s(REFNAME, git_reference_name(ref1));
|
||||||
|
git_reference_free(ref0);
|
||||||
|
|
||||||
/* Lookup the reference in a different instance of the repository */
|
/* Lookup the reference in a different instance of the repository */
|
||||||
cl_git_pass(git_repository_open(&repo2, "testrepo.git"));
|
cl_git_pass(git_repository_open(&repo2, "testrepo.git"));
|
||||||
|
|
||||||
cl_git_pass(git_reference_lookup(&ref2, repo2, REFNAME));
|
cl_git_pass(git_reference_lookup(&ref2, repo2, REFNAME));
|
||||||
|
cl_assert_equal_i(
|
||||||
cl_assert(git_oid_cmp(git_reference_target(ref1), git_reference_target(ref2)) == 0);
|
0, git_oid_cmp(git_reference_target(ref1), git_reference_target(ref2)));
|
||||||
cl_assert_equal_s(REFNAME, git_reference_name(ref2));
|
cl_assert_equal_s(REFNAME, git_reference_name(ref2));
|
||||||
|
|
||||||
git_reference_free(ref0);
|
|
||||||
git_reference_free(ref1);
|
|
||||||
git_reference_free(ref2);
|
git_reference_free(ref2);
|
||||||
|
|
||||||
|
#if GIT_USE_ICONV
|
||||||
|
/* Lookup reference by decomposed unicode name */
|
||||||
|
|
||||||
|
cl_git_pass(git_reference_lookup(&ref2, repo2, REFNAME_DECOMPOSED));
|
||||||
|
cl_assert_equal_i(
|
||||||
|
0, git_oid_cmp(git_reference_target(ref1), git_reference_target(ref2)));
|
||||||
|
cl_assert_equal_s(REFNAME, git_reference_name(ref2));
|
||||||
|
git_reference_free(ref2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
|
||||||
|
git_reference_free(ref1);
|
||||||
git_repository_free(repo2);
|
git_repository_free(repo2);
|
||||||
}
|
}
|
||||||
|
@ -7,20 +7,7 @@ static git_repository *g_repo = NULL;
|
|||||||
|
|
||||||
void test_submodule_lookup__initialize(void)
|
void test_submodule_lookup__initialize(void)
|
||||||
{
|
{
|
||||||
g_repo = cl_git_sandbox_init("submod2");
|
g_repo = setup_fixture_submod2();
|
||||||
|
|
||||||
cl_fixture_sandbox("submod2_target");
|
|
||||||
p_rename("submod2_target/.gitted", "submod2_target/.git");
|
|
||||||
|
|
||||||
/* must create submod2_target before rewrite so prettify will work */
|
|
||||||
rewrite_gitmodules(git_repository_workdir(g_repo));
|
|
||||||
p_rename("submod2/not-submodule/.gitted", "submod2/not-submodule/.git");
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_submodule_lookup__cleanup(void)
|
|
||||||
{
|
|
||||||
cl_git_sandbox_cleanup();
|
|
||||||
cl_fixture_cleanup("submod2_target");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_submodule_lookup__simple_lookup(void)
|
void test_submodule_lookup__simple_lookup(void)
|
||||||
|
@ -11,20 +11,7 @@ static git_repository *g_repo = NULL;
|
|||||||
|
|
||||||
void test_submodule_modify__initialize(void)
|
void test_submodule_modify__initialize(void)
|
||||||
{
|
{
|
||||||
g_repo = cl_git_sandbox_init("submod2");
|
g_repo = setup_fixture_submod2();
|
||||||
|
|
||||||
cl_fixture_sandbox("submod2_target");
|
|
||||||
p_rename("submod2_target/.gitted", "submod2_target/.git");
|
|
||||||
|
|
||||||
/* must create submod2_target before rewrite so prettify will work */
|
|
||||||
rewrite_gitmodules(git_repository_workdir(g_repo));
|
|
||||||
p_rename("submod2/not-submodule/.gitted", "submod2/not-submodule/.git");
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_submodule_modify__cleanup(void)
|
|
||||||
{
|
|
||||||
cl_git_sandbox_cleanup();
|
|
||||||
cl_fixture_cleanup("submod2_target");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_submodule_modify__add(void)
|
void test_submodule_modify__add(void)
|
||||||
|
@ -102,6 +102,8 @@ git_repository *setup_fixture_submodules(void)
|
|||||||
|
|
||||||
cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");
|
cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_reset_filesystem(repo, 1));
|
||||||
|
|
||||||
return repo;
|
return repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,5 +120,7 @@ git_repository *setup_fixture_submod2(void)
|
|||||||
|
|
||||||
cl_set_cleanup(cleanup_fixture_submodules, "submod2_target");
|
cl_set_cleanup(cleanup_fixture_submodules, "submod2_target");
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_reset_filesystem(repo, 1));
|
||||||
|
|
||||||
return repo;
|
return repo;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user