mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-10-31 19:11:31 +00:00 
			
		
		
		
	Merge pull request #833 from carlosmn/odb-one
odb: allow creating an ODB backend from a packfile index
This commit is contained in:
		
						commit
						bfb5916468
					
				| @ -100,6 +100,7 @@ struct git_odb_stream { | ||||
| 
 | ||||
| GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir); | ||||
| GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync); | ||||
| GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **backend_out, const char *index_file); | ||||
| 
 | ||||
| GIT_END_DECL | ||||
| 
 | ||||
|  | ||||
| @ -35,6 +35,19 @@ GIT_BEGIN_DECL | ||||
|  */ | ||||
| GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path); | ||||
| 
 | ||||
| /**
 | ||||
|  * Create a "fake" repository to wrap an object database | ||||
|  * | ||||
|  * Create a repository object to wrap an object database to be used | ||||
|  * with the API when all you have is an object database. This doesn't | ||||
|  * have any paths associated with it, so use with care. | ||||
|  * | ||||
|  * @param repository pointer to the repo | ||||
|  * @param odb the object database to wrap | ||||
|  * @return 0 or an error code | ||||
|  */ | ||||
| GIT_EXTERN(int) git_repository_wrap_odb(git_repository **repository, git_odb *odb); | ||||
| 
 | ||||
| /**
 | ||||
|  * Look for a git repository and copy its path in the given buffer. | ||||
|  * The lookup start from base_path and walk across parent directories | ||||
|  | ||||
| @ -458,6 +458,41 @@ static void pack_backend__free(git_odb_backend *_backend) | ||||
| 	git__free(backend); | ||||
| } | ||||
| 
 | ||||
| int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx) | ||||
| { | ||||
| 	struct pack_backend *backend = NULL; | ||||
| 	struct git_pack_file *packfile = NULL; | ||||
| 
 | ||||
| 	if (git_packfile_check(&packfile, idx) < 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	backend = git__calloc(1, sizeof(struct pack_backend)); | ||||
| 	GITERR_CHECK_ALLOC(backend); | ||||
| 
 | ||||
| 	if (git_vector_init(&backend->packs, 1, NULL) < 0) | ||||
| 		goto on_error; | ||||
| 
 | ||||
| 	if (git_vector_insert(&backend->packs, packfile) < 0) | ||||
| 		goto on_error; | ||||
| 
 | ||||
| 	backend->parent.read = &pack_backend__read; | ||||
| 	backend->parent.read_prefix = &pack_backend__read_prefix; | ||||
| 	backend->parent.read_header = NULL; | ||||
| 	backend->parent.exists = &pack_backend__exists; | ||||
| 	backend->parent.foreach = &pack_backend__foreach; | ||||
| 	backend->parent.free = &pack_backend__free; | ||||
| 
 | ||||
| 	*backend_out = (git_odb_backend *)backend; | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| on_error: | ||||
| 	git_vector_free(&backend->packs); | ||||
| 	git__free(backend); | ||||
| 	git__free(packfile); | ||||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) | ||||
| { | ||||
| 	struct pack_backend *backend = NULL; | ||||
|  | ||||
| @ -388,6 +388,19 @@ int git_repository_open(git_repository **repo_out, const char *path) | ||||
| 		repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL); | ||||
| } | ||||
| 
 | ||||
| int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb) | ||||
| { | ||||
| 	git_repository *repo; | ||||
| 
 | ||||
| 	repo = repository_alloc(); | ||||
| 	GITERR_CHECK_ALLOC(repo); | ||||
| 
 | ||||
| 	git_repository_set_odb(repo, odb); | ||||
| 	*repo_out = repo; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int git_repository_discover( | ||||
| 	char *repository_path, | ||||
| 	size_t size, | ||||
|  | ||||
| @ -7,12 +7,6 @@ static git_odb *_odb; | ||||
| static git_repository *_repo; | ||||
| static int nobj; | ||||
| 
 | ||||
| void test_odb_foreach__initialize(void) | ||||
| { | ||||
| 	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); | ||||
| 	git_repository_odb(&_odb, _repo); | ||||
| } | ||||
| 
 | ||||
| void test_odb_foreach__cleanup(void) | ||||
| { | ||||
| 	git_odb_free(_odb); | ||||
| @ -41,6 +35,23 @@ static int foreach_cb(git_oid *oid, void *data) | ||||
|  */ | ||||
| void test_odb_foreach__foreach(void) | ||||
| { | ||||
| 	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); | ||||
| 	git_repository_odb(&_odb, _repo); | ||||
| 
 | ||||
| 	cl_git_pass(git_odb_foreach(_odb, foreach_cb, NULL)); | ||||
| 	cl_assert_equal_i(43 + 1640, nobj); /* count + in-pack */ | ||||
| } | ||||
| 
 | ||||
| void test_odb_foreach__one_pack(void) | ||||
| { | ||||
| 	git_odb_backend *backend = NULL; | ||||
| 
 | ||||
| 	cl_git_pass(git_odb_new(&_odb)); | ||||
| 	cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"))); | ||||
| 	cl_git_pass(git_odb_add_backend(_odb, backend, 1)); | ||||
| 	_repo = NULL; | ||||
| 
 | ||||
| 	nobj = 0; | ||||
| 	cl_git_pass(git_odb_foreach(_odb, foreach_cb, NULL)); | ||||
| 	cl_assert(nobj == 1628); | ||||
| } | ||||
|  | ||||
							
								
								
									
										19
									
								
								tests-clar/odb/pack_data_one.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests-clar/odb/pack_data_one.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| /* Just a few to make sure it's working, the rest is tested already */ | ||||
| static const char *packed_objects_one[] = { | ||||
| 	"9fcf811e00fa469688943a9152c16d4ee90fb9a9", | ||||
| 	"a93f42a5b5e9de40fa645a9ff1e276a021c9542b", | ||||
| 	"12bf5f3e3470d90db177ccf1b5e8126409377fc6", | ||||
| 	"ed1ea164cdbe3c4b200fb4fa19861ea90eaee222", | ||||
| 	"dfae6ed8f6dd8acc3b40a31811ea316239223559", | ||||
| 	"aefe66d192771201e369fde830530f4475beec30", | ||||
| 	"775e4b4c1296e9e3104f2a36ca9cf9356a130959", | ||||
| 	"412ec4e4a6a7419bc1be00561fe474e54cb499fe", | ||||
| 	"236e7579fed7763be77209efb8708960982f3cb3", | ||||
| 	"09fe9364461cf60dd1c46b0e9545b1e47bb1a297", | ||||
| 	"d76d8a6390d1cf32138d98a91b1eb7e0275a12f5", | ||||
| 	"d0fdf2dcff2f548952eec536ccc6d266550041bc", | ||||
| 	"a20d733a9fa79fa5b4cbb9639864f93325ec27a6", | ||||
| 	"785d3fe8e7db5ade2c2242fecd46c32a7f4dc59f", | ||||
| 	"4d8d0fd9cb6045075385701c3f933ec13345e9c4", | ||||
| 	"0cfd861bd547b6520d1fc2e190e8359e0a9c9b90" | ||||
| }; | ||||
							
								
								
									
										58
									
								
								tests-clar/odb/packed_one.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								tests-clar/odb/packed_one.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| #include "clar_libgit2.h" | ||||
| #include "odb.h" | ||||
| #include "pack_data_one.h" | ||||
| #include "pack.h" | ||||
| 
 | ||||
| static git_odb *_odb; | ||||
| 
 | ||||
| void test_odb_packed_one__initialize(void) | ||||
| { | ||||
| 	git_odb_backend *backend = NULL; | ||||
| 
 | ||||
| 	cl_git_pass(git_odb_new(&_odb)); | ||||
| 	cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"))); | ||||
| 	cl_git_pass(git_odb_add_backend(_odb, backend, 1)); | ||||
| } | ||||
| 
 | ||||
| void test_odb_packed_one__cleanup(void) | ||||
| { | ||||
| 	git_odb_free(_odb); | ||||
| } | ||||
| 
 | ||||
| void test_odb_packed_one__mass_read(void) | ||||
| { | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	for (i = 0; i < ARRAY_SIZE(packed_objects_one); ++i) { | ||||
| 		git_oid id; | ||||
| 		git_odb_object *obj; | ||||
| 
 | ||||
| 		cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i])); | ||||
| 		cl_assert(git_odb_exists(_odb, &id) == 1); | ||||
| 		cl_git_pass(git_odb_read(&obj, _odb, &id)); | ||||
| 
 | ||||
| 		git_odb_object_free(obj); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void test_odb_packed_one__read_header_0(void) | ||||
| { | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	for (i = 0; i < ARRAY_SIZE(packed_objects_one); ++i) { | ||||
| 		git_oid id; | ||||
| 		git_odb_object *obj; | ||||
| 		size_t len; | ||||
| 		git_otype type; | ||||
| 
 | ||||
| 		cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i])); | ||||
| 
 | ||||
| 		cl_git_pass(git_odb_read(&obj, _odb, &id)); | ||||
| 		cl_git_pass(git_odb_read_header(&len, &type, _odb, &id)); | ||||
| 
 | ||||
| 		cl_assert(obj->raw.len == len); | ||||
| 		cl_assert(obj->raw.type == type); | ||||
| 
 | ||||
| 		git_odb_object_free(obj); | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Vicent Martí
						Vicent Martí