From: Allan Caffee <allan.caffee@gmail.com>
To: git@vger.kernel.org
Cc: Jeff King <peff@peff.net>, Nanako Shiraishi <nanako3@lavabit.com>,
Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: [RFC/PATCH] graph API: Added logic for colored edges.
Date: Mon, 30 Mar 2009 10:13:23 -0400 [thread overview]
Message-ID: <20090330141322.GA6221@linux.vnet> (raw)
In-Reply-To: <20090321175726.GA6677@linux.vnet>
Modified the graph drawing logic to colorize edges based on parent-child
relationships similiarly to gitk.
Signed-off-by: Allan Caffee <allan.caffee@gmail.com>
---
I havn't gotten the chance to do any of the color clean up that's been
discussed on this thread. I'll try to throw something together in a seperate
patch series.
Also this patch isn't respecting the --no-color option which I imagine means
that diff_use_color_default isn't the right variable to be checking. Johannes
mentioned using diff_use_color but the only instance I see is a parameter to
diff_get_color. What am I missing?
~Allan
color.h | 1 +
graph.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 144 insertions(+), 24 deletions(-)
diff --git a/color.h b/color.h
index 6846be1..18abeb7 100644
--- a/color.h
+++ b/color.h
@@ -11,6 +11,7 @@
#define GIT_COLOR_GREEN "\033[32m"
#define GIT_COLOR_YELLOW "\033[33m"
#define GIT_COLOR_BLUE "\033[34m"
+#define GIT_COLOR_MAGENTA "\033[35m"
#define GIT_COLOR_CYAN "\033[36m"
#define GIT_COLOR_BG_RED "\033[41m"
diff --git a/graph.c b/graph.c
index 162a516..2929c8b 100644
--- a/graph.c
+++ b/graph.c
@@ -1,9 +1,11 @@
#include "cache.h"
#include "commit.h"
+#include "color.h"
#include "graph.h"
#include "diff.h"
#include "revision.h"
+extern int diff_use_color_default;
/* Internal API */
/*
@@ -72,11 +74,22 @@ struct column {
*/
struct commit *commit;
/*
- * XXX: Once we add support for colors, struct column could also
- * contain the color of its branch line.
+ * The color to (optionally) print this column in.
*/
+ char *color;
};
+static void strbuf_write_column(struct strbuf *sb, const struct column *c,
+ const char *s);
+
+static char* get_current_column_color (const struct git_graph* graph);
+
+/*
+ * Update the default column color and return the new value.
+ */
+static char* get_next_column_color(struct git_graph* graph);
+
+
enum graph_state {
GRAPH_PADDING,
GRAPH_SKIP,
@@ -86,6 +99,24 @@ enum graph_state {
GRAPH_COLLAPSING
};
+/*
+ * The list of available column colors.
+ */
+static char column_colors[][COLOR_MAXLEN] = {
+ GIT_COLOR_RED,
+ GIT_COLOR_GREEN,
+ GIT_COLOR_YELLOW,
+ GIT_COLOR_BLUE,
+ GIT_COLOR_MAGENTA,
+ GIT_COLOR_CYAN,
+ GIT_COLOR_BOLD GIT_COLOR_RED,
+ GIT_COLOR_BOLD GIT_COLOR_GREEN,
+ GIT_COLOR_BOLD GIT_COLOR_YELLOW,
+ GIT_COLOR_BOLD GIT_COLOR_BLUE,
+ GIT_COLOR_BOLD GIT_COLOR_MAGENTA,
+ GIT_COLOR_BOLD GIT_COLOR_CYAN,
+};
+
struct git_graph {
/*
* The commit currently being processed
@@ -185,6 +216,11 @@ struct git_graph {
* temporary array each time we have to output a collapsing line.
*/
int *new_mapping;
+ /*
+ * The current default column color being used. This is
+ * stored as an index into the array column_colors.
+ */
+ short default_column_color;
};
struct git_graph *graph_init(struct rev_info *opt)
@@ -201,6 +237,7 @@ struct git_graph *graph_init(struct rev_info *opt)
graph->num_columns = 0;
graph->num_new_columns = 0;
graph->mapping_size = 0;
+ graph->default_column_color = 0;
/*
* Allocate a reasonably large default number of columns
@@ -317,6 +354,14 @@ static void graph_insert_into_new_columns(struct git_graph *graph,
int *mapping_index)
{
int i;
+ char *color = get_current_column_color(graph);
+
+ for (i = 0; i < graph->num_columns; i++) {
+ if (graph->columns[i].commit == commit) {
+ color = graph->columns[i].color;
+ break;
+ }
+ }
/*
* If the commit is already in the new_columns list, we don't need to
@@ -334,6 +379,8 @@ static void graph_insert_into_new_columns(struct git_graph *graph,
* This commit isn't already in new_columns. Add it.
*/
graph->new_columns[graph->num_new_columns].commit = commit;
+/* fprintf(stderr,"adding the %scommit%s\n", color, GIT_COLOR_RESET); */
+ graph->new_columns[graph->num_new_columns].color = color;
graph->mapping[*mapping_index] = graph->num_new_columns;
*mapping_index += 2;
graph->num_new_columns++;
@@ -445,6 +492,12 @@ static void graph_update_columns(struct git_graph *graph)
for (parent = first_interesting_parent(graph);
parent;
parent = next_interesting_parent(graph, parent)) {
+ /*
+ * If this is a merge increment the current
+ * color.
+ */
+ if (graph->num_parents > 1)
+ get_next_column_color(graph);
graph_insert_into_new_columns(graph,
parent->item,
&mapping_idx);
@@ -596,7 +649,7 @@ static void graph_output_padding_line(struct git_graph *graph,
* Output a padding row, that leaves all branch lines unchanged
*/
for (i = 0; i < graph->num_new_columns; i++) {
- strbuf_addstr(sb, "| ");
+ strbuf_write_column(sb, &graph->new_columns[i], "| ");
}
graph_pad_horizontally(graph, sb);
@@ -649,7 +702,10 @@ static void graph_output_pre_commit_line(struct git_graph *graph,
struct column *col = &graph->columns[i];
if (col->commit == graph->commit) {
seen_this = 1;
- strbuf_addf(sb, "| %*s", graph->expansion_row, "");
+ struct strbuf tmp = STRBUF_INIT;
+ strbuf_addf(&tmp, "| %*s", graph->expansion_row, "");
+ strbuf_write_column(sb, col, tmp.buf);
+ strbuf_release(&tmp);
} else if (seen_this && (graph->expansion_row == 0)) {
/*
* This is the first line of the pre-commit output.
@@ -662,13 +718,13 @@ static void graph_output_pre_commit_line(struct git_graph *graph,
*/
if (graph->prev_state == GRAPH_POST_MERGE &&
graph->prev_commit_index < i)
- strbuf_addstr(sb, "\\ ");
+ strbuf_write_column(sb, col, "\\ ");
else
- strbuf_addstr(sb, "| ");
+ strbuf_write_column(sb, col, "| ");
} else if (seen_this && (graph->expansion_row > 0)) {
- strbuf_addstr(sb, "\\ ");
+ strbuf_write_column(sb, col, "\\ ");
} else {
- strbuf_addstr(sb, "| ");
+ strbuf_write_column(sb, col, "| ");
}
}
@@ -728,6 +784,7 @@ static void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
*/
seen_this = 0;
for (i = 0; i <= graph->num_columns; i++) {
+ struct column *col = &graph->columns[i];
struct commit *col_commit;
if (i == graph->num_columns) {
if (seen_this)
@@ -751,7 +808,7 @@ static void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
strbuf_addstr(sb, ". ");
}
} else if (seen_this && (graph->num_parents > 2)) {
- strbuf_addstr(sb, "\\ ");
+ strbuf_write_column(sb, col, "\\ ");
} else if (seen_this && (graph->num_parents == 2)) {
/*
* This is a 2-way merge commit.
@@ -768,11 +825,11 @@ static void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
*/
if (graph->prev_state == GRAPH_POST_MERGE &&
graph->prev_commit_index < i)
- strbuf_addstr(sb, "\\ ");
+ strbuf_write_column(sb, col, "\\ ");
else
- strbuf_addstr(sb, "| ");
+ strbuf_write_column(sb, col, "| ");
} else {
- strbuf_addstr(sb, "| ");
+ strbuf_write_column(sb, col, "| ");
}
}
@@ -789,6 +846,17 @@ static void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
graph_update_state(graph, GRAPH_COLLAPSING);
}
+inline struct column* find_new_column_by_commit(struct git_graph *graph,
+ struct commit *commit)
+{
+ int i;
+ for (i = 0; i < graph->num_new_columns; i++) {
+ if (graph->new_columns[i].commit == commit)
+ return &graph->new_columns[i];
+ }
+ return 0;
+}
+
static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb)
{
int seen_this = 0;
@@ -798,24 +866,43 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf
* Output the post-merge row
*/
for (i = 0; i <= graph->num_columns; i++) {
+ struct column *col = &graph->columns[i];
struct commit *col_commit;
if (i == graph->num_columns) {
if (seen_this)
break;
col_commit = graph->commit;
} else {
- col_commit = graph->columns[i].commit;
+ col_commit = col->commit;
}
if (col_commit == graph->commit) {
+ /*
+ * Since the current commit is a merge find
+ * the columns for the parent commits in
+ * new_columns and use those to format the
+ * edges.
+ */
+ struct commit_list *parents = NULL;
+ struct column *par_column;
seen_this = 1;
- strbuf_addch(sb, '|');
- for (j = 0; j < graph->num_parents - 1; j++)
- strbuf_addstr(sb, "\\ ");
+ parents = first_interesting_parent(graph);
+ assert(parents);
+ par_column = find_new_column_by_commit(graph,parents->item);
+ assert(par_column);
+
+ strbuf_write_column(sb, par_column, "|");
+ for (j = 0; j < graph->num_parents - 1; j++) {
+ parents = next_interesting_parent(graph, parents);
+ assert(parents);
+ par_column = find_new_column_by_commit(graph,parents->item);
+ assert(par_column);
+ strbuf_write_column(sb, par_column, "\\ ");
+ }
} else if (seen_this) {
- strbuf_addstr(sb, "\\ ");
+ strbuf_write_column(sb, col, "\\ ");
} else {
- strbuf_addstr(sb, "| ");
+ strbuf_write_column(sb, col, "| ");
}
}
@@ -834,6 +921,8 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf
{
int i;
int *tmp_mapping;
+ static int collapsing_columns[255];
+ int collapsing_seen_so_far = 0;
/*
* Clear out the new_mapping array
@@ -912,9 +1001,11 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf
if (target < 0)
strbuf_addch(sb, ' ');
else if (target * 2 == i)
- strbuf_addch(sb, '|');
- else
- strbuf_addch(sb, '/');
+ strbuf_write_column(sb, &graph->new_columns[target], "|");
+ else {
+ strbuf_write_column(sb, &graph->new_columns[target], "/");
+
+ }
}
graph_pad_horizontally(graph, sb);
@@ -979,9 +1070,10 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
* children that we have already processed.)
*/
for (i = 0; i < graph->num_columns; i++) {
- struct commit *col_commit = graph->columns[i].commit;
+ struct column *col = &graph->columns[i];
+ struct commit *col_commit = col->commit;
if (col_commit == graph->commit) {
- strbuf_addch(sb, '|');
+ strbuf_write_column(sb, col, "|");
if (graph->num_parents < 3)
strbuf_addch(sb, ' ');
@@ -991,7 +1083,7 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
strbuf_addch(sb, ' ');
}
} else {
- strbuf_addstr(sb, "| ");
+ strbuf_write_column(sb, col, "| ");
}
}
@@ -1154,3 +1246,30 @@ void graph_show_commit_msg(struct git_graph *graph,
putchar('\n');
}
}
+
+static void strbuf_write_column(struct strbuf *sb, const struct column *c,
+ const char *s)
+{
+ /*
+ * TODO: I get the creeping suspicion that this isn't the
+ * right flag to be checking since --no-color doesn't turn
+ * this off.
+ */
+ if (diff_use_color_default)
+ strbuf_addstr(sb, c->color);
+ strbuf_addstr(sb, s);
+ if (diff_use_color_default)
+ strbuf_addstr(sb, GIT_COLOR_RESET);
+}
+
+static char* get_current_column_color (const struct git_graph* graph)
+{
+ return column_colors[graph->default_column_color];
+}
+
+static char* get_next_column_color(struct git_graph* graph)
+{
+ graph->default_column_color = (graph->default_column_color + 1) %
+ ARRAY_SIZE(column_colors);
+ return (get_current_column_color(graph));
+}
--
1.5.4.3
next prev parent reply other threads:[~2009-03-30 14:15 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-18 10:05 [RFC] Colorization of log --graph Allan Caffee
2009-03-18 11:44 ` Johannes Schindelin
2009-03-19 16:59 ` Allan Caffee
2009-03-19 17:41 ` Johannes Schindelin
2009-03-19 21:48 ` Nanako Shiraishi
2009-03-20 19:13 ` Allan Caffee
2009-03-20 19:58 ` Jeff King
[not found] ` <20090321175726.GA6677@linux.vnet>
2009-03-30 14:13 ` Allan Caffee [this message]
[not found] ` <cover.1238428115u.git.johannes.schindelin@gmx.de>
2009-03-30 15:49 ` [PATCH 1/2] graph.c: avoid compile warnings Johannes Schindelin
2009-03-30 15:58 ` Junio C Hamano
2009-03-30 16:14 ` Junio C Hamano
2009-03-30 15:49 ` [PATCH 2/2] --graph: respect --no-color Johannes Schindelin
2009-03-30 16:04 ` [RFC/PATCH] graph API: Added logic for colored edges Johannes Schindelin
2009-03-31 10:13 ` Johannes Schindelin
2009-03-31 10:26 ` Johannes Sixt
2009-03-31 12:09 ` Johannes Schindelin
2009-03-31 10:21 ` Johannes Schindelin
2009-03-20 20:13 ` [RFC] Colorization of log --graph Junio C Hamano
2009-03-18 16:52 ` Eric Raible
2009-03-18 17:04 ` Santi Béjar
2009-03-18 17:29 ` Eric Raible
2009-03-19 19:32 ` Markus Heidelberg
2009-03-19 19:52 ` Eric Raible
2009-03-19 20:04 ` Markus Heidelberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090330141322.GA6221@linux.vnet \
--to=allan.caffee@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=nanako3@lavabit.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).