Пример #1
0
void show_log(struct rev_info *opt)
{
	struct strbuf msgbuf = STRBUF_INIT;
	struct log_info *log = opt->loginfo;
	struct commit *commit = log->commit, *parent = log->parent;
	int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
	const char *extra_headers = opt->extra_headers;
	struct pretty_print_context ctx = {0};

	opt->loginfo = NULL;
	if (!opt->verbose_header) {
		graph_show_commit(opt->graph);

		if (!opt->graph)
			put_revision_mark(opt, commit);
		fputs(find_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
		if (opt->print_parents)
			show_parents(commit, abbrev_commit);
		if (opt->children.name)
			show_children(opt, commit, abbrev_commit);
		show_decorations(opt, commit);
		if (opt->graph && !graph_is_commit_finished(opt->graph)) {
			putchar('\n');
			graph_show_remainder(opt->graph);
		}
		putchar(opt->diffopt.line_termination);
		return;
	}

	/*
	 * If use_terminator is set, we already handled any record termination
	 * at the end of the last record.
	 * Otherwise, add a diffopt.line_termination character before all
	 * entries but the first.  (IOW, as a separator between entries)
	 */
	if (opt->shown_one && !opt->use_terminator) {
		/*
		 * If entries are separated by a newline, the output
		 * should look human-readable.  If the last entry ended
		 * with a newline, print the graph output before this
		 * newline.  Otherwise it will end up as a completely blank
		 * line and will look like a gap in the graph.
		 *
		 * If the entry separator is not a newline, the output is
		 * primarily intended for programmatic consumption, and we
		 * never want the extra graph output before the entry
		 * separator.
		 */
		if (opt->diffopt.line_termination == '\n' &&
		    !opt->missing_newline)
			graph_show_padding(opt->graph);
		putchar(opt->diffopt.line_termination);
	}
	opt->shown_one = 1;

	/*
	 * If the history graph was requested,
	 * print the graph, up to this commit's line
	 */
	graph_show_commit(opt->graph);

	/*
	 * Print header line of header..
	 */

	if (opt->commit_format == CMIT_FMT_EMAIL) {
		log_write_email_headers(opt, commit, &ctx.subject, &extra_headers,
					&ctx.need_8bit_cte);
	} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
		fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
		if (opt->commit_format != CMIT_FMT_ONELINE)
			fputs("commit ", stdout);

		if (!opt->graph)
			put_revision_mark(opt, commit);
		fputs(find_unique_abbrev(commit->object.sha1, abbrev_commit),
		      stdout);
		if (opt->print_parents)
			show_parents(commit, abbrev_commit);
		if (opt->children.name)
			show_children(opt, commit, abbrev_commit);
		if (parent)
			printf(" (from %s)",
			       find_unique_abbrev(parent->object.sha1,
						  abbrev_commit));
		fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), stdout);
		show_decorations(opt, commit);
		if (opt->commit_format == CMIT_FMT_ONELINE) {
			putchar(' ');
		} else {
			putchar('\n');
			graph_show_oneline(opt->graph);
		}
		if (opt->reflog_info) {
			/*
			 * setup_revisions() ensures that opt->reflog_info
			 * and opt->graph cannot both be set,
			 * so we don't need to worry about printing the
			 * graph info here.
			 */
			show_reflog_message(opt->reflog_info,
					    opt->commit_format == CMIT_FMT_ONELINE,
					    opt->date_mode,
					    opt->date_mode_explicit);
			if (opt->commit_format == CMIT_FMT_ONELINE)
				return;
		}
	}

	if (opt->show_signature) {
		show_signature(opt, commit);
		show_mergetag(opt, commit);
	}

	if (!commit->buffer)
		return;

	if (opt->show_notes) {
		int raw;
		struct strbuf notebuf = STRBUF_INIT;

		raw = (opt->commit_format == CMIT_FMT_USERFORMAT);
		format_display_notes(commit->object.sha1, &notebuf,
				     get_log_output_encoding(), raw);
		ctx.notes_message = notebuf.len
			? strbuf_detach(&notebuf, NULL)
			: xcalloc(1, 1);
	}

	/*
	 * And then the pretty-printed message itself
	 */
	if (ctx.need_8bit_cte >= 0 && opt->add_signoff)
		ctx.need_8bit_cte =
			has_non_ascii(fmt_name(getenv("GIT_COMMITTER_NAME"),
					       getenv("GIT_COMMITTER_EMAIL")));
	ctx.date_mode = opt->date_mode;
	ctx.date_mode_explicit = opt->date_mode_explicit;
	ctx.abbrev = opt->diffopt.abbrev;
	ctx.after_subject = extra_headers;
	ctx.preserve_subject = opt->preserve_subject;
	ctx.reflog_info = opt->reflog_info;
	ctx.fmt = opt->commit_format;
	ctx.mailmap = opt->mailmap;
	ctx.color = opt->diffopt.use_color;
	ctx.output_encoding = get_log_output_encoding();
	if (opt->from_ident.mail_begin && opt->from_ident.name_begin)
		ctx.from_ident = &opt->from_ident;
	pretty_print_commit(&ctx, commit, &msgbuf);

	if (opt->add_signoff)
		append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP);

	if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
	    ctx.notes_message && *ctx.notes_message) {
		if (ctx.fmt == CMIT_FMT_EMAIL) {
			strbuf_addstr(&msgbuf, "---\n");
			opt->shown_dashes = 1;
		}
		strbuf_addstr(&msgbuf, ctx.notes_message);
	}

	if (opt->show_log_size) {
		printf("log size %i\n", (int)msgbuf.len);
		graph_show_oneline(opt->graph);
	}

	/*
	 * Set opt->missing_newline if msgbuf doesn't
	 * end in a newline (including if it is empty)
	 */
	if (!msgbuf.len || msgbuf.buf[msgbuf.len - 1] != '\n')
		opt->missing_newline = 1;
	else
		opt->missing_newline = 0;

	if (opt->graph)
		graph_show_commit_msg(opt->graph, &msgbuf);
	else
		fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
	if (opt->use_terminator) {
		if (!opt->missing_newline)
			graph_show_padding(opt->graph);
		putchar(opt->diffopt.line_termination);
	}

	strbuf_release(&msgbuf);
	free(ctx.notes_message);
}
Пример #2
0
static void show_commit(struct commit *commit, void *data)
{
	struct rev_list_info *info = data;
	struct rev_info *revs = info->revs;

	graph_show_commit(revs->graph);

	if (info->show_timestamp)
		printf("%lu ", commit->date);
	if (info->header_prefix)
		fputs(info->header_prefix, stdout);

	if (!revs->graph) {
		if (commit->object.flags & BOUNDARY)
			putchar('-');
		else if (commit->object.flags & UNINTERESTING)
			putchar('^');
		else if (revs->left_right) {
			if (commit->object.flags & SYMMETRIC_LEFT)
				putchar('<');
			else
				putchar('>');
		}
	}
	if (revs->abbrev_commit && revs->abbrev)
		fputs(find_unique_abbrev(commit->object.sha1, revs->abbrev),
		      stdout);
	else
		fputs(sha1_to_hex(commit->object.sha1), stdout);
	if (revs->print_parents) {
		struct commit_list *parents = commit->parents;
		while (parents) {
			printf(" %s", sha1_to_hex(parents->item->object.sha1));
			parents = parents->next;
		}
	}
	if (revs->children.name) {
		struct commit_list *children;

		children = lookup_decoration(&revs->children, &commit->object);
		while (children) {
			printf(" %s", sha1_to_hex(children->item->object.sha1));
			children = children->next;
		}
	}
	show_decorations(revs, commit);
	if (revs->commit_format == CMIT_FMT_ONELINE)
		putchar(' ');
	else
		putchar('\n');

	if (revs->verbose_header && commit->buffer) {
		struct strbuf buf = STRBUF_INIT;
		pretty_print_commit(revs->commit_format, commit,
				    &buf, revs->abbrev, NULL, NULL,
				    revs->date_mode, 0);
		if (revs->graph) {
			if (buf.len) {
				if (revs->commit_format != CMIT_FMT_ONELINE)
					graph_show_oneline(revs->graph);

				graph_show_commit_msg(revs->graph, &buf);

				/*
				 * Add a newline after the commit message.
				 *
				 * Usually, this newline produces a blank
				 * padding line between entries, in which case
				 * we need to add graph padding on this line.
				 *
				 * However, the commit message may not end in a
				 * newline.  In this case the newline simply
				 * ends the last line of the commit message,
				 * and we don't need any graph output.  (This
				 * always happens with CMIT_FMT_ONELINE, and it
				 * happens with CMIT_FMT_USERFORMAT when the
				 * format doesn't explicitly end in a newline.)
				 */
				if (buf.len && buf.buf[buf.len - 1] == '\n')
					graph_show_padding(revs->graph);
				putchar('\n');
			} else {
				/*
				 * If the message buffer is empty, just show
				 * the rest of the graph output for this
				 * commit.
				 */
				if (graph_show_remainder(revs->graph))
					putchar('\n');
			}
		} else {
			if (buf.len)
				printf("%s%c", buf.buf, info->hdr_termination);
		}
		strbuf_release(&buf);
	} else {
		if (graph_show_remainder(revs->graph))
			putchar('\n');
	}
	maybe_flush_or_die(stdout, "stdout");
	finish_commit(commit, data);
}
Пример #3
0
Файл: log-tree.c Проект: ktf/git
void show_log(struct rev_info *opt)
{
    struct strbuf msgbuf = STRBUF_INIT;
    struct log_info *log = opt->loginfo;
    struct commit *commit = log->commit, *parent = log->parent;
    int abbrev = opt->diffopt.abbrev;
    int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
    const char *subject = NULL, *extra_headers = opt->extra_headers;
    int need_8bit_cte = 0;

    opt->loginfo = NULL;
    if (!opt->verbose_header) {
        graph_show_commit(opt->graph);

        if (!opt->graph) {
            if (commit->object.flags & BOUNDARY)
                putchar('-');
            else if (commit->object.flags & UNINTERESTING)
                putchar('^');
            else if (opt->left_right) {
                if (commit->object.flags & SYMMETRIC_LEFT)
                    putchar('<');
                else
                    putchar('>');
            }
        }
        fputs(find_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
        if (opt->print_parents)
            show_parents(commit, abbrev_commit);
        show_decorations(opt, commit);
        if (opt->graph && !graph_is_commit_finished(opt->graph)) {
            putchar('\n');
            graph_show_remainder(opt->graph);
        }
        putchar(opt->diffopt.line_termination);
        return;
    }

    /*
     * If use_terminator is set, we already handled any record termination
     * at the end of the last record.
     * Otherwise, add a diffopt.line_termination character before all
     * entries but the first.  (IOW, as a separator between entries)
     */
    if (opt->shown_one && !opt->use_terminator) {
        /*
         * If entries are separated by a newline, the output
         * should look human-readable.  If the last entry ended
         * with a newline, print the graph output before this
         * newline.  Otherwise it will end up as a completely blank
         * line and will look like a gap in the graph.
         *
         * If the entry separator is not a newline, the output is
         * primarily intended for programmatic consumption, and we
         * never want the extra graph output before the entry
         * separator.
         */
        if (opt->diffopt.line_termination == '\n' &&
                !opt->missing_newline)
            graph_show_padding(opt->graph);
        putchar(opt->diffopt.line_termination);
    }
    opt->shown_one = 1;

    /*
     * If the history graph was requested,
     * print the graph, up to this commit's line
     */
    graph_show_commit(opt->graph);

    /*
     * Print header line of header..
     */

    if (opt->commit_format == CMIT_FMT_EMAIL) {
        log_write_email_headers(opt, commit, &subject, &extra_headers,
                                &need_8bit_cte);
    } else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
        fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
        if (opt->commit_format != CMIT_FMT_ONELINE)
            fputs("commit ", stdout);

        if (!opt->graph) {
            if (commit->object.flags & BOUNDARY)
                putchar('-');
            else if (commit->object.flags & UNINTERESTING)
                putchar('^');
            else if (opt->left_right) {
                if (commit->object.flags & SYMMETRIC_LEFT)
                    putchar('<');
                else
                    putchar('>');
            }
        }
        fputs(find_unique_abbrev(commit->object.sha1, abbrev_commit),
              stdout);
        if (opt->print_parents)
            show_parents(commit, abbrev_commit);
        if (parent)
            printf(" (from %s)",
                   find_unique_abbrev(parent->object.sha1,
                                      abbrev_commit));
        show_decorations(opt, commit);
        printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
        if (opt->commit_format == CMIT_FMT_ONELINE) {
            putchar(' ');
        } else {
            putchar('\n');
            graph_show_oneline(opt->graph);
        }
        if (opt->reflog_info) {
            /*
             * setup_revisions() ensures that opt->reflog_info
             * and opt->graph cannot both be set,
             * so we don't need to worry about printing the
             * graph info here.
             */
            show_reflog_message(opt->reflog_info,
                                opt->commit_format == CMIT_FMT_ONELINE,
                                opt->date_mode);
            if (opt->commit_format == CMIT_FMT_ONELINE)
                return;
        }
    }

    if (!commit->buffer)
        return;

    /*
     * And then the pretty-printed message itself
     */
    if (need_8bit_cte >= 0)
        need_8bit_cte = has_non_ascii(opt->add_signoff);
    pretty_print_commit(opt->commit_format, commit, &msgbuf,
                        abbrev, subject, extra_headers, opt->date_mode,
                        need_8bit_cte);

    if (opt->add_signoff)
        append_signoff(&msgbuf, opt->add_signoff);
    if (opt->show_log_size) {
        printf("log size %i\n", (int)msgbuf.len);
        graph_show_oneline(opt->graph);
    }

    /*
     * Set opt->missing_newline if msgbuf doesn't
     * end in a newline (including if it is empty)
     */
    if (!msgbuf.len || msgbuf.buf[msgbuf.len - 1] != '\n')
        opt->missing_newline = 1;
    else
        opt->missing_newline = 0;

    if (opt->graph)
        graph_show_commit_msg(opt->graph, &msgbuf);
    else
        fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
    if (opt->use_terminator) {
        if (!opt->missing_newline)
            graph_show_padding(opt->graph);
        putchar('\n');
    }

    strbuf_release(&msgbuf);
}