git-rev-list: use proper lazy reachability analysis
This mean sthat you can give a beginning/end pair to git-rev-list, and it will show all entries that are reachable from the beginning but not the end. For example git-rev-list v2.6.12-rc5 v2.6.12-rc4 shows all commits that are in -rc5 but are not in -rc4.
This commit is contained in:
55
rev-list.c
55
rev-list.c
@ -1,6 +1,10 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
|
|
||||||
|
#define SEEN (1u << 0)
|
||||||
|
#define INTERESTING (1u << 1)
|
||||||
|
#define UNINTERESTING (1u << 2)
|
||||||
|
|
||||||
static const char rev_list_usage[] =
|
static const char rev_list_usage[] =
|
||||||
"usage: git-rev-list [OPTION] commit-id <commit-id>\n"
|
"usage: git-rev-list [OPTION] commit-id <commit-id>\n"
|
||||||
" --max-count=nr\n"
|
" --max-count=nr\n"
|
||||||
@ -8,6 +12,29 @@ static const char rev_list_usage[] =
|
|||||||
" --min-age=epoch\n"
|
" --min-age=epoch\n"
|
||||||
" --header";
|
" --header";
|
||||||
|
|
||||||
|
static void mark_parents_uninteresting(struct commit *commit)
|
||||||
|
{
|
||||||
|
struct commit_list *parents = commit->parents;
|
||||||
|
|
||||||
|
while (parents) {
|
||||||
|
struct commit *commit = parents->item;
|
||||||
|
commit->object.flags |= UNINTERESTING;
|
||||||
|
parents = parents->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int everybody_uninteresting(struct commit_list *list)
|
||||||
|
{
|
||||||
|
while (list) {
|
||||||
|
struct commit *commit = list->item;
|
||||||
|
list = list->next;
|
||||||
|
if (commit->object.flags & UNINTERESTING)
|
||||||
|
continue;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int nr_sha;
|
int nr_sha;
|
||||||
@ -60,11 +87,29 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
commit_list_insert(commit, &list);
|
commit_list_insert(commit, &list);
|
||||||
do {
|
if (end) {
|
||||||
struct commit *commit = pop_most_recent_commit(&list, 0x1);
|
struct commit_list *newlist = NULL;
|
||||||
|
struct commit_list **p = &newlist;
|
||||||
|
do {
|
||||||
|
struct commit *commit = pop_most_recent_commit(&list, SEEN);
|
||||||
|
struct object *obj = &commit->object;
|
||||||
|
|
||||||
if (commit == end)
|
if (commit == end || (obj->flags & UNINTERESTING)) {
|
||||||
break;
|
mark_parents_uninteresting(commit);
|
||||||
|
if (everybody_uninteresting(list))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p = &commit_list_insert(commit, p)->next;
|
||||||
|
} while (list);
|
||||||
|
list = newlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (list) {
|
||||||
|
struct commit *commit = pop_most_recent_commit(&list, SEEN);
|
||||||
|
|
||||||
|
if (commit->object.flags & UNINTERESTING)
|
||||||
|
continue;
|
||||||
if (min_age != -1 && (commit->date > min_age))
|
if (min_age != -1 && (commit->date > min_age))
|
||||||
continue;
|
continue;
|
||||||
if (max_age != -1 && (commit->date < max_age))
|
if (max_age != -1 && (commit->date < max_age))
|
||||||
@ -74,6 +119,6 @@ int main(int argc, char **argv)
|
|||||||
printf("%s\n", sha1_to_hex(commit->object.sha1));
|
printf("%s\n", sha1_to_hex(commit->object.sha1));
|
||||||
if (verbose_header)
|
if (verbose_header)
|
||||||
printf("%s%c", commit->buffer, 0);
|
printf("%s%c", commit->buffer, 0);
|
||||||
} while (list);
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user