mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-10-31 14:47:32 +00:00 
			
		
		
		
	revwalk: allow simplifying by first-parent
When enabled, only the first parent of each commit will be queued, enabling a simple way of using first-parent simplification.
This commit is contained in:
		
							parent
							
								
									ef6389ad50
								
							
						
					
					
						commit
						15f7b9b8d9
					
				| @ -231,6 +231,14 @@ GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode); | ||||
|  */ | ||||
| GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range); | ||||
| 
 | ||||
| /**
 | ||||
|  * Simplify the history by first-parent | ||||
|  * | ||||
|  * No parents other than the first for each commit will be enqueued. | ||||
|  */ | ||||
| GIT_EXTERN(void) git_revwalk_simplify_first_parent(git_revwalk *walk); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Free a revision walker previously allocated. | ||||
|  * | ||||
|  | ||||
| @ -99,10 +99,14 @@ static int process_commit(git_revwalk *walk, git_commit_list_node *commit, int h | ||||
| 
 | ||||
| static int process_commit_parents(git_revwalk *walk, git_commit_list_node *commit) | ||||
| { | ||||
| 	unsigned short i; | ||||
| 	unsigned short i, max; | ||||
| 	int error = 0; | ||||
| 
 | ||||
| 	for (i = 0; i < commit->out_degree && !error; ++i) | ||||
| 	max = commit->out_degree; | ||||
| 	if (walk->first_parent && commit->out_degree) | ||||
| 		max = 1; | ||||
| 
 | ||||
| 	for (i = 0; i < max && !error; ++i) | ||||
| 		error = process_commit(walk, commit->parents[i], commit->uninteresting); | ||||
| 
 | ||||
| 	return error; | ||||
| @ -333,7 +337,7 @@ static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk | ||||
| static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk *walk) | ||||
| { | ||||
| 	git_commit_list_node *next; | ||||
| 	unsigned short i; | ||||
| 	unsigned short i, max; | ||||
| 
 | ||||
| 	for (;;) { | ||||
| 		next = git_commit_list_pop(&walk->iterator_topo); | ||||
| @ -347,7 +351,12 @@ static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		for (i = 0; i < next->out_degree; ++i) { | ||||
| 
 | ||||
| 		max = next->out_degree; | ||||
| 		if (walk->first_parent && next->out_degree) | ||||
| 			max = 1; | ||||
| 
 | ||||
| 		for (i = 0; i < max; ++i) { | ||||
| 			git_commit_list_node *parent = next->parents[i]; | ||||
| 
 | ||||
| 			if (--parent->in_degree == 0 && parent->topo_delay) { | ||||
| @ -505,6 +514,11 @@ void git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void git_revwalk_simplify_first_parent(git_revwalk *walk) | ||||
| { | ||||
| 	walk->first_parent = 1; | ||||
| } | ||||
| 
 | ||||
| int git_revwalk_next(git_oid *oid, git_revwalk *walk) | ||||
| { | ||||
| 	int error; | ||||
|  | ||||
| @ -31,7 +31,8 @@ struct git_revwalk { | ||||
| 	int (*get_next)(git_commit_list_node **, git_revwalk *); | ||||
| 	int (*enqueue)(git_revwalk *, git_commit_list_node *); | ||||
| 
 | ||||
| 	unsigned walking:1; | ||||
| 	unsigned walking:1, | ||||
| 		first_parent: 1; | ||||
| 	unsigned int sorting; | ||||
| 
 | ||||
| 	/* merge base calculation */ | ||||
|  | ||||
							
								
								
									
										51
									
								
								tests-clar/revwalk/simplify.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								tests-clar/revwalk/simplify.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| #include "clar_libgit2.h" | ||||
| 
 | ||||
| /*
 | ||||
| 	*   a4a7dce [0] Merge branch 'master' into br2 | ||||
| 	|\ | ||||
| 	| * 9fd738e [1] a fourth commit | ||||
| 	| * 4a202b3 [2] a third commit | ||||
| 	* | c47800c [3] branch commit one | ||||
| 	|/ | ||||
| 	* 5b5b025 [5] another commit | ||||
| 	* 8496071 [4] testing | ||||
| */ | ||||
| static const char *commit_head = "a4a7dce85cf63874e984719f4fdd239f5145052f"; | ||||
| 
 | ||||
| static const char *expected_str[] = { | ||||
| 	"a4a7dce85cf63874e984719f4fdd239f5145052f", /* 0 */ | ||||
| 	"c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */ | ||||
| 	"8496071c1b46c854b31185ea97743be6a8774479", /* 4 */ | ||||
| 	"5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */ | ||||
| }; | ||||
| 
 | ||||
| void test_revwalk_simplify__first_parent(void) | ||||
| { | ||||
| 	git_repository *repo; | ||||
| 	git_revwalk *walk; | ||||
| 	git_oid id, expected[4]; | ||||
| 	int i, error; | ||||
| 
 | ||||
| 	for (i = 0; i < 4; i++) { | ||||
| 		git_oid_fromstr(&expected[i], expected_str[i]); | ||||
| 	} | ||||
| 
 | ||||
| 	repo = cl_git_sandbox_init("testrepo.git"); | ||||
| 	cl_git_pass(git_revwalk_new(&walk, repo)); | ||||
| 
 | ||||
| 	git_oid_fromstr(&id, commit_head); | ||||
| 	cl_git_pass(git_revwalk_push(walk, &id)); | ||||
| 	git_revwalk_simplify_first_parent(walk); | ||||
| 
 | ||||
| 	i = 0; | ||||
| 	while ((error = git_revwalk_next(&id, walk)) == 0) { | ||||
| 		git_oid_cmp(&id, &expected[i]); | ||||
| 		i++; | ||||
| 	} | ||||
| 
 | ||||
| 	cl_assert_equal_i(i, 4); | ||||
| 	cl_assert_equal_i(error, GIT_ITEROVER); | ||||
| 
 | ||||
| 	git_revwalk_free(walk); | ||||
| 	git_repository_free(repo); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carlos Martín Nieto
						Carlos Martín Nieto