mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-11-04 07:09:14 +00:00 
			
		
		
		
	Merge pull request #683 from arrbee/better-repo-init
Improve repo initialization to be more like git
This commit is contained in:
		
						commit
						b72969e064
					
				@ -684,6 +684,59 @@ static int repo_init_config(const char *git_dir, int is_bare)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define GIT_HOOKS_DIR "hooks/"
 | 
			
		||||
#define GIT_HOOKS_DIR_MODE 0755
 | 
			
		||||
 | 
			
		||||
#define GIT_HOOKS_README_FILE GIT_HOOKS_DIR "README.sample"
 | 
			
		||||
#define GIT_HOOKS_README_MODE 0755
 | 
			
		||||
#define GIT_HOOKS_README_CONTENT \
 | 
			
		||||
"#!/bin/sh\n"\
 | 
			
		||||
"#\n"\
 | 
			
		||||
"# Place appropriately named executable hook scripts into this directory\n"\
 | 
			
		||||
"# to intercept various actions that git takes.  See `git help hooks` for\n"\
 | 
			
		||||
"# more information.\n"
 | 
			
		||||
 | 
			
		||||
#define GIT_INFO_DIR "info/"
 | 
			
		||||
#define GIT_INFO_DIR_MODE 0755
 | 
			
		||||
 | 
			
		||||
#define GIT_INFO_EXCLUDE_FILE GIT_INFO_DIR "exclude"
 | 
			
		||||
#define GIT_INFO_EXCLUDE_MODE 0644
 | 
			
		||||
#define GIT_INFO_EXCLUDE_CONTENT \
 | 
			
		||||
"# File patterns to ignore; see `git help ignore` for more information.\n"\
 | 
			
		||||
"# Lines that start with '#' are comments.\n"
 | 
			
		||||
 | 
			
		||||
#define GIT_DESC_FILE "description"
 | 
			
		||||
#define GIT_DESC_MODE 0644
 | 
			
		||||
#define GIT_DESC_CONTENT "Unnamed repository; edit this file 'description' to name the repository.\n"
 | 
			
		||||
 | 
			
		||||
static int repo_write_template(
 | 
			
		||||
	const char *git_dir, const char *file, mode_t mode, const char *content)
 | 
			
		||||
{
 | 
			
		||||
	git_buf path = GIT_BUF_INIT;
 | 
			
		||||
	int fd, error = 0;
 | 
			
		||||
 | 
			
		||||
	if (git_buf_joinpath(&path, git_dir, file) < 0)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	fd = p_open(git_buf_cstr(&path), O_WRONLY | O_CREAT | O_EXCL, mode);
 | 
			
		||||
 | 
			
		||||
	if (fd >= 0) {
 | 
			
		||||
		error = p_write(fd, content, strlen(content));
 | 
			
		||||
 | 
			
		||||
		p_close(fd);
 | 
			
		||||
	}
 | 
			
		||||
	else if (errno != EEXIST)
 | 
			
		||||
		error = fd;
 | 
			
		||||
 | 
			
		||||
	git_buf_free(&path);
 | 
			
		||||
 | 
			
		||||
	if (error)
 | 
			
		||||
		giterr_set(GITERR_OS,
 | 
			
		||||
			"Failed to initialize repository with template '%s'", file);
 | 
			
		||||
 | 
			
		||||
	return error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int repo_init_structure(const char *git_dir, int is_bare)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
@ -692,8 +745,16 @@ static int repo_init_structure(const char *git_dir, int is_bare)
 | 
			
		||||
		{ GIT_OBJECTS_PACK_DIR, GIT_OBJECT_DIR_MODE }, /* '/objects/pack/' */
 | 
			
		||||
		{ GIT_REFS_HEADS_DIR, GIT_REFS_DIR_MODE },     /* '/refs/heads/' */
 | 
			
		||||
		{ GIT_REFS_TAGS_DIR, GIT_REFS_DIR_MODE },      /* '/refs/tags/' */
 | 
			
		||||
		{ GIT_HOOKS_DIR, GIT_HOOKS_DIR_MODE },         /* '/hooks/' */
 | 
			
		||||
		{ GIT_INFO_DIR, GIT_INFO_DIR_MODE },           /* '/info/' */
 | 
			
		||||
		{ NULL, 0 }
 | 
			
		||||
	};
 | 
			
		||||
	struct { const char *file; mode_t mode; const char *content; } tmpl[] = {
 | 
			
		||||
		{ GIT_DESC_FILE, GIT_DESC_MODE, GIT_DESC_CONTENT },
 | 
			
		||||
		{ GIT_HOOKS_README_FILE, GIT_HOOKS_README_MODE, GIT_HOOKS_README_CONTENT },
 | 
			
		||||
		{ GIT_INFO_EXCLUDE_FILE, GIT_INFO_EXCLUDE_MODE, GIT_INFO_EXCLUDE_CONTENT },
 | 
			
		||||
		{ NULL, 0, NULL }
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/* Make the base directory */
 | 
			
		||||
	if (git_futils_mkdir_r(git_dir, NULL, is_bare ? GIT_BARE_DIR_MODE : GIT_DIR_MODE) < 0)
 | 
			
		||||
@ -716,7 +777,13 @@ static int repo_init_structure(const char *git_dir, int is_bare)
 | 
			
		||||
			return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* TODO: what's left? templates? */
 | 
			
		||||
	/* Make template files as needed */
 | 
			
		||||
	for (i = 0; tmpl[i].file != NULL; ++i) {
 | 
			
		||||
		if (repo_write_template(
 | 
			
		||||
				git_dir, tmpl[i].file, tmpl[i].mode, tmpl[i].content) < 0)
 | 
			
		||||
			return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -141,3 +141,27 @@ void test_repo_init__reinit_too_recent_bare_repo(void)
 | 
			
		||||
 | 
			
		||||
	cl_fixture_cleanup("reinit.git");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_repo_init__additional_templates(void)
 | 
			
		||||
{
 | 
			
		||||
	git_buf path = GIT_BUF_INIT;
 | 
			
		||||
 | 
			
		||||
	cl_set_cleanup(&cleanup_repository, "tester");
 | 
			
		||||
 | 
			
		||||
	ensure_repository_init("tester", 0, "tester/.git/", "tester/");
 | 
			
		||||
 | 
			
		||||
	cl_git_pass(
 | 
			
		||||
		git_buf_joinpath(&path, git_repository_path(_repo), "description"));
 | 
			
		||||
	cl_assert(git_path_isfile(git_buf_cstr(&path)));
 | 
			
		||||
 | 
			
		||||
	cl_git_pass(
 | 
			
		||||
		git_buf_joinpath(&path, git_repository_path(_repo), "info/exclude"));
 | 
			
		||||
	cl_assert(git_path_isfile(git_buf_cstr(&path)));
 | 
			
		||||
 | 
			
		||||
	cl_git_pass(
 | 
			
		||||
		git_buf_joinpath(&path, git_repository_path(_repo), "hooks"));
 | 
			
		||||
	cl_assert(git_path_isdir(git_buf_cstr(&path)));
 | 
			
		||||
	/* won't confirm specific contents of hooks dir since it may vary */
 | 
			
		||||
 | 
			
		||||
	git_buf_free(&path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user