Skip to content

Commit

Permalink
Merge branch 'lt/rev-list-interactive'
Browse files Browse the repository at this point in the history
* lt/rev-list-interactive:
  Fix parent rewriting in --early-output
  revision walker: mini clean-up
  Enhance --early-output format
  Add "--early-output" log flag for interactive GUI use
  Simplify topo-sort logic
  • Loading branch information
Junio C Hamano committed Nov 19, 2007
2 parents e6cb314 + 7dc0fe3 commit 761e856
Show file tree
Hide file tree
Showing 7 changed files with 286 additions and 176 deletions.
2 changes: 1 addition & 1 deletion builtin-fmt-merge-msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ static void shortlog(const char *name, unsigned char *sha1,
struct commit *commit;
struct object *branch;
struct list subjects = { NULL, NULL, 0, 0 };
int flags = UNINTERESTING | TREECHANGE | SEEN | SHOWN | ADDED;
int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;

branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
if (!branch || branch->type != OBJ_COMMIT)
Expand Down
123 changes: 123 additions & 0 deletions builtin-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,134 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
}
}

/*
* This gives a rough estimate for how many commits we
* will print out in the list.
*/
static int estimate_commit_count(struct rev_info *rev, struct commit_list *list)
{
int n = 0;

while (list) {
struct commit *commit = list->item;
unsigned int flags = commit->object.flags;
list = list->next;
if (!(flags & (TREESAME | UNINTERESTING)))
n++;
}
return n;
}

static void show_early_header(struct rev_info *rev, const char *stage, int nr)
{
if (rev->shown_one) {
rev->shown_one = 0;
if (rev->commit_format != CMIT_FMT_ONELINE)
putchar(rev->diffopt.line_termination);
}
printf("Final output: %d %s\n", nr, stage);
}

struct itimerval early_output_timer;

static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
int i = revs->early_output;
int show_header = 1;

sort_in_topological_order(&list, revs->lifo);
while (list && i) {
struct commit *commit = list->item;
switch (simplify_commit(revs, commit)) {
case commit_show:
if (show_header) {
int n = estimate_commit_count(revs, list);
show_early_header(revs, "incomplete", n);
show_header = 0;
}
log_tree_commit(revs, commit);
i--;
break;
case commit_ignore:
break;
case commit_error:
return;
}
list = list->next;
}

/* Did we already get enough commits for the early output? */
if (!i)
return;

/*
* ..if no, then repeat it twice a second until we
* do.
*
* NOTE! We don't use "it_interval", because if the
* reader isn't listening, we want our output to be
* throttled by the writing, and not have the timer
* trigger every second even if we're blocked on a
* reader!
*/
early_output_timer.it_value.tv_sec = 0;
early_output_timer.it_value.tv_usec = 500000;
setitimer(ITIMER_REAL, &early_output_timer, NULL);
}

static void early_output(int signal)
{
show_early_output = log_show_early;
}

static void setup_early_output(struct rev_info *rev)
{
struct sigaction sa;

/*
* Set up the signal handler, minimally intrusively:
* we only set a single volatile integer word (not
* using sigatomic_t - trying to avoid unnecessary
* system dependencies and headers), and using
* SA_RESTART.
*/
memset(&sa, 0, sizeof(sa));
sa.sa_handler = early_output;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGALRM, &sa, NULL);

/*
* If we can get the whole output in less than a
* tenth of a second, don't even bother doing the
* early-output thing..
*
* This is a one-time-only trigger.
*/
early_output_timer.it_value.tv_sec = 0;
early_output_timer.it_value.tv_usec = 100000;
setitimer(ITIMER_REAL, &early_output_timer, NULL);
}

static void finish_early_output(struct rev_info *rev)
{
int n = estimate_commit_count(rev, rev->commits);
signal(SIGALRM, SIG_IGN);
show_early_header(rev, "done", n);
}

static int cmd_log_walk(struct rev_info *rev)
{
struct commit *commit;

if (rev->early_output)
setup_early_output(rev);

prepare_revision_walk(rev);

if (rev->early_output)
finish_early_output(rev);

while ((commit = get_revision(rev)) != NULL) {
log_tree_commit(rev, commit);
if (!rev->reflog_info) {
Expand Down
16 changes: 8 additions & 8 deletions builtin-rev-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static int count_distance(struct commit_list *entry)

if (commit->object.flags & (UNINTERESTING | COUNTED))
break;
if (!revs.prune_fn || (commit->object.flags & TREECHANGE))
if (!(commit->object.flags & TREESAME))
nr++;
commit->object.flags |= COUNTED;
p = commit->parents;
Expand Down Expand Up @@ -209,7 +209,7 @@ static inline int halfway(struct commit_list *p, int nr)
/*
* Don't short-cut something we are not going to return!
*/
if (revs.prune_fn && !(p->item->object.flags & TREECHANGE))
if (p->item->object.flags & TREESAME)
return 0;
if (DEBUG_BISECT)
return 0;
Expand Down Expand Up @@ -245,7 +245,7 @@ static void show_list(const char *debug, int counted, int nr,
char *ep, *sp;

fprintf(stderr, "%c%c%c ",
(flags & TREECHANGE) ? 'T' : ' ',
(flags & TREESAME) ? ' ' : 'T',
(flags & UNINTERESTING) ? 'U' : ' ',
(flags & COUNTED) ? 'C' : ' ');
if (commit->util)
Expand Down Expand Up @@ -279,7 +279,7 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr)
int distance;
unsigned flags = p->item->object.flags;

if (revs.prune_fn && !(flags & TREECHANGE))
if (flags & TREESAME)
continue;
distance = weight(p);
if (nr - distance < distance)
Expand Down Expand Up @@ -319,7 +319,7 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n
int distance;
unsigned flags = p->item->object.flags;

if (revs.prune_fn && !(flags & TREECHANGE))
if (flags & TREESAME)
continue;
distance = weight(p);
if (nr - distance < distance)
Expand Down Expand Up @@ -373,7 +373,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
p->item->util = &weights[n++];
switch (count_interesting_parents(commit)) {
case 0:
if (!revs.prune_fn || (flags & TREECHANGE)) {
if (!(flags & TREESAME)) {
weight_set(p, 1);
counted++;
show_list("bisection 2 count one",
Expand Down Expand Up @@ -446,7 +446,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
* add one for p itself if p is to be counted,
* otherwise inherit it from q directly.
*/
if (!revs.prune_fn || (flags & TREECHANGE)) {
if (!(flags & TREESAME)) {
weight_set(p, weight(q)+1);
counted++;
show_list("bisection 2 count one",
Expand Down Expand Up @@ -493,7 +493,7 @@ static struct commit_list *find_bisection(struct commit_list *list,
continue;
p->next = last;
last = p;
if (!revs.prune_fn || (flags & TREECHANGE))
if (!(flags & TREESAME))
nr++;
on_list++;
}
Expand Down
Loading

0 comments on commit 761e856

Please sign in to comment.