mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 06:47:53 +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