From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
This new API allows the commit history to be displayed as a text-based
graphical representation.
Signed-off-by: Adam Simpkins <redacted>
---
This is a replacement for the git-graph patch I submitted last weekend.
It adds the graph functionality as a new API. A subsequent commit
updates "git log" and "git rev-list" to use the new API.
I saw that Jan Engelhardt also submitted a patch for his git-forest
script this past week. It looks like a fine tool, too.
I think there are benefits to having the graphing functionality built in
to git. This way all of the existing log functionality (argument
parsing, pretty formats, etc) can be easily re-used. Other builtin
parts of git can also take advantage of the graphing API. It is also
one less tool for system administrators to install and maintain
(although this depends on how the distros decide to package things, I
suppose).
I also prefer the output of my graphing API better than that of
git-forest (although, as the author, I'm a bit biased). It is more
similar to gitk's graph, which many people are already familiar with.
It also doesn't require a terminal with Unicode support.
I do like the fact that git-forest prints the names of the refs that
point to each commit. For the graphing API, we could perhaps add a "%r"
specifier to --pretty=format to print the refs pointing to the commit.
Documentation/technical/api-history-graph.txt | 108 ++++
Makefile | 2 +
graph.c | 711 +++++++++++++++++++++++++
graph.h | 57 ++
4 files changed, 878 insertions(+), 0 deletions(-)
create mode 100644 Documentation/technical/api-history-graph.txt
create mode 100644 graph.c
create mode 100644 graph.h
@@ -0,0 +1,108 @@+history graph API+=================++The graph API is used to draw a text-based representation of the commit+history. The API generates the graph in a line-by-line fashion.++Calling sequence+----------------++* Create a `struct git_graph` by calling `graph_init()`++* Use the revision walking API to walk through a group of contiguous commits.++* For each commit you walk through, call `graph_update()`. Then call+ `graph_next_line()` repeatedly, until `graph_is_commit_finished()` returns+ non-zero. Each call go `graph_next_line()` will output a single line of the+ graph. The resulting lines will not contain any newlines.+ `graph_next_line()` returns 1 if the resulting line contains the current+ commit, or 0 if this is merely a line needed to adjust the graph before or+ after the current commit. This return value can be used to determine where+ to print the commit summary information alongside the graph output.++Data structure+--------------+`struct git_graph` is an opaque data type used to store the current graph+state.++Limitations+-----------++* `graph_update()` must be called with commits in topological order. The+ commits must also be a contiguous group--intervening parents should not+ be ommitted. Otherwise, the graph API cannot determine the proper+ parent-child relationships between the commits. If intervening parents+ are ommitted, the next ancestor that is used will appear to be on a+ separate branch in the graph.++* The graph API does not currently support reverse commit ordering. In+ order to implement reverse ordering, the graphing API needs an+ (efficient) mechanism to find the children of a commit.++Sample usage+------------++------------+struct commit *commit;+struct git_graph *graph = graph_init();++while ((commit = get_revision(opts)) != NULL) {+ graph_update(graph, commit);+ while (!graph_is_commit_finished(graph))+ {+ struct strbuf sb;+ int is_commit_line;++ strbuf_init(&sb, 0);+ is_commit_line = graph_next_line(graph, &sb);+ fputs(sb.buf, stdout);++ if (is_commit_line)+ log_tree_commit(opts, commit);+ else+ putchar(opts->diffopt.line_termination);+ }+}++graph_release(graph);+------------++Sample output+-------------++The following is an example of the output from the graph API. This output does+not include any commit summary information--callers of responsible for+outputting that information, if desired.++------------+*+*+M+|\+* |+| | *+| \ \+| \ \+M-. \ \+|\ \ \ \+| | * | |+| | | | | *+| | | | | *+| | | | | M+| | | | | |\+| | | | | | *+| * | | | | |+| | | | | M \+| | | | | |\ |+| | | | * | | |+| | | | * | | |+* | | | | | | |+| |/ / / / / /+|/| / / / / /+* | | | | | |+|/ / / / / /+* | | | | |+| | | | | *+| | | | |/+| | | | *+------------
@@ -0,0 +1,57 @@+#ifndef GRAPH_H+#define GRAPH_H++/* A graph is a pointer to this opaque structure */+structgit_graph;++/* Defined in commit.h */+structcommit;+/* Defined in strbuf.h */+structstrbuf;++/*+*Createanewstructgit_graph.+*Thegraphshouldbefreedwithgraph_release()whennolongerneeded.+*/+structgit_graph*graph_init();++/*+*Destroyastructgit_graphandfreeassociatedmemory.+*/+voidgraph_release(structgit_graph*graph);++/*+*Updateagit_graphwithanewcommit.+*Thiswillcausethegraphtobeginoutputtinglinesforthenewcommit+*thenexttimegraph_next_line()iscalled.+*+*Ifgraph_update()iscalledbeforegraph_is_commit_finished()returns1,+*thenextcalltograph_next_line()willoutputanellipsis("...")+*toindicatethataportionofthegraphismissing.+*/+voidgraph_update(structgit_graph*graph,structcommit*commit);++/*+*Outputthenextlineforagraph.+*Thisformatsthenextgraphlineintothespecifiedstrbuf.Itisnot+*terminatedwithanewline.+*+*Returns1ifthelineincludesthecurrentcommit,and0otherwise.+*graph_next_line()willreturn1exactlyonceforeachtime+*graph_update()iscalled.+*/+intgraph_next_line(structgit_graph*graph,structstrbuf*sb);++/*+*Determineifagraphhasfinishedoutputtinglinesforthecurrent+*commit.+*+*Returns1ifgraph_next_line()needstobecalledagainbefore+*graph_update()shouldbecalled.Returns0ifnomorelinesareneeded+*forthiscommit.If0isreturned,graph_next_line()maystillbe+*calledwithoutcallinggraph_update(),anditwillmerelyoutput+*appropriate"vertical padding"inthegraph.+*/+intgraph_is_commit_finished(structgit_graphconst*graph);++#endif /* GRAPH_H */
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
The --graph option causes a text-based representation of the history
graph to be printed on the left-hand side of the output.
Signed-off-by: Adam Simpkins <redacted>
---
The --graph option can be used with any --pretty format. If this change
is too intrusive for people's liking, a smaller change could probably be
done that only adds --pretty=graph and --pretty=graph:<user_fmt>
options.
At the moment, --graph and --reverse are mutually exclusive. With
Junio's new --children patch for git log, it probably shouldn't be too
hard to get them working together.
Documentation/technical/api-history-graph.txt | 61 +++++++++++++++++------
builtin-rev-list.c | 50 +++++++++++++++++--
log-tree.c | 65 +++++++++++++++++++++++--
revision.c | 28 ++++++++++-
revision.h | 3 +
5 files changed, 180 insertions(+), 27 deletions(-)
@@ -4,26 +4,34 @@ history graph API The graph API is used to draw a text-based representation of the commit history. The API generates the graph in a line-by-line fashion.-Calling sequence-----------------+Functions+----------* Create a `struct git_graph` by calling `graph_init()`+Core functions:-* Use the revision walking API to walk through a group of contiguous commits.+* `graph_init()` creates a new `struct git_graph`++* `graph_release()` destroys a `struct git_graph`, and frees the memory+ associated with it.-* For each commit you walk through, call `graph_update()`. Then call- `graph_next_line()` repeatedly, until `graph_is_commit_finished()` returns- non-zero. Each call go `graph_next_line()` will output a single line of the- graph. The resulting lines will not contain any newlines.- `graph_next_line()` returns 1 if the resulting line contains the current- commit, or 0 if this is merely a line needed to adjust the graph before or- after the current commit. This return value can be used to determine where- to print the commit summary information alongside the graph output.+* `graph_update()` moves the graph to a new commit.-Utility functions------------------+* `graph_next_line()` outputs the next line of the graph into a strbuf. It does+ not add a terminating newline.-The following functions are wrappers around `graph_next_line()` and+* `graph_padding_line()` outputs a line of vertical padding in the graph. It+ is similar to `graph_next_line()`, but is guaranteed to never print the line+ containing the current commit. Where `graph_next_line()` would print the+ commit line next, `graph_padding_line()` prints a line that simply extends+ all branch lines downwards one row, leaving their positions unchanged.++* `graph_is_commit_finished()` determines if the graph has output all lines+ necessary for the current commit. If `graph_update()` is called before all+ lines for the current commit have been printed, the next call to+ `graph_next_line()` will output an ellipsis, to indicate that a portion of the+ graph was omitted.++The following utility functions are wrappers around `graph_next_line()` and `graph_is_commit_finished()`. They always print the output to stdout. They can all be called with a NULL graph argument, in which case no graph output will be printed.
@@ -37,6 +45,9 @@ will be printed. * `graph_show_oneline()` calls `graph_next_line()` and prints the result to stdout. The line printed does not contain a terminating newline.+* `graph_show_padding()` calls `graph_padding_line()` and prints the result to+ stdout. The line printed does not contain a terminating newline.+ * `graph_show_remainder()` calls `graph_next_line()` until `graph_is_commit_finished()` returns non-zero. Output is printed to stdout. The last line printed does not contain a terminating newline. Returns 1 if
@@ -53,6 +64,26 @@ Data structure `struct git_graph` is an opaque data type used to store the current graph state.+Calling sequence+----------------++* Create a `struct git_graph` by calling `graph_init()`. When using the+ revision walking API, this is done automatically by `setup_revisions()` if+ the '--graph' option is supplied.++* Use the revision walking API to walk through a group of contiguous commits.+ The `get_revision()` function automatically calls `graph_update()` each time+ it is invoked.++* For each commit, call `graph_next_line()` repeatedly, until+ `graph_is_commit_finished()` returns non-zero. Each call go+ `graph_next_line()` will output a single line of the graph. The resulting+ lines will not contain any newlines. `graph_next_line()` returns 1 if the+ resulting line contains the current commit, or 0 if this is merely a line+ needed to adjust the graph before or after the current commit. This return+ value can be used to determine where to print the commit summary information+ alongside the graph output.+ Limitations -----------
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
Added several graph_show_* functions that print directly to stdout instead
of to a strbuf. Also added functions for explicitly adding vertical padding
in the graph.
Signed-off-by: Adam Simpkins <redacted>
---
Documentation/technical/api-history-graph.txt | 28 +++++
graph.c | 140 +++++++++++++++++++++++++
graph.h | 51 +++++++++
3 files changed, 219 insertions(+), 0 deletions(-)
@@ -20,6 +20,34 @@ Calling sequence after the current commit. This return value can be used to determine where to print the commit summary information alongside the graph output.+Utility functions+-----------------++The following functions are wrappers around `graph_next_line()` and+`graph_is_commit_finished()`. They always print the output to stdout.+They can all be called with a NULL graph argument, in which case no graph output+will be printed.++* `graph_show_commit()` calls `graph_next_line()` until it returns non-zero.+ This prints all graph lines up to, and including, the line containing this+ commit. Output is printed to stdout. The last line printed does not contain+ a terminating newline. This should not be called if the commit line has+ already been printed, or it will loop forever.++* `graph_show_oneline()` calls `graph_next_line()` and prints the result to+ stdout. The line printed does not contain a terminating newline.++* `graph_show_remainder()` calls `graph_next_line()` until+ `graph_is_commit_finished()` returns non-zero. Output is printed to stdout.+ The last line printed does not contain a terminating newline. Returns 1 if+ output was printed, and 0 if no output was necessary.++* `graph_show_strbuf()` prints the specified strbuf to stdout, prefixing all+ lines but the first with a graph line. The caller is responsible for ensuring+ graph output for the first line has already been printed to stdout. (This can+ be done with `graph_show_commit()` or `graph_show_oneline()`.) If a NULL+ graph is supplied, the strbuf is printed as-is.+ Data structure -------------- `struct git_graph` is an opaque data type used to store the current graph
From: Teemu Likonen <hidden> Date: 2016-06-15 22:44:27
Adam Simpkins kirjoitti:
I think there are benefits to having the graphing functionality built
in to git. This way all of the existing log functionality (argument
parsing, pretty formats, etc) can be easily re-used. Other builtin
parts of git can also take advantage of the graphing API.
I don't know anything about the inside stuff but from user's point of
view this is the kind of text-based graph I'd agree to be integrated to
Git (well, I integrated it already to my Git). I like this a lot,
thanks.
Maybe git-doc.txt should be updated with new option(s)?
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:44:27
Hi,
On Sun, 6 Apr 2008, Adam Simpkins wrote:
I do like the fact that git-forest prints the names of the refs that
point to each commit. For the graphing API, we could perhaps add a "%r"
specifier to --pretty=format to print the refs pointing to the commit.
@@ -0,0 +1,57 @@+#ifndef GRAPH_H+#define GRAPH_H++/* A graph is a pointer to this opaque structure */+structgit_graph;++/* Defined in commit.h */+structcommit;+/* Defined in strbuf.h */+structstrbuf;
You do not need those.
Apart from that, it looks very, very clean to me. (Except maybe the
prefix ++ that could have been a postfix ++ in the line before, but that
is just me.)
Ciao,
Dscho
From: Teemu Likonen <hidden> Date: 2016-06-15 22:44:27
Adam Simpkins kirjoitti:
The --graph option causes a text-based representation of the history
graph to be printed on the left-hand side of the output.
The '--graph' seems to work nicely with every '--pretty=' option
except 'email'.
$ git log --graph --pretty=email
|
M From 77ad7a49d3cc946487ca759e5361effbcfb03be5 [...]
From: Junio C Hamano <redacted>
|\ Date: Fri, 4 Apr 2008 22:38:32 -0700
| | Subject: [PATCH] Merge git://repo.or.cz/git-gui
| |
| | * git://repo.or.cz/git-gui:
| | git-gui: use +/- instead of ]/[ to show [...]
| | git-gui: Update french translation
| | git-gui: Switch keybindings for [ and ] to [...]
The 'From:' field is always at the column 1.
@@ -75,6 +75,16 @@ you would get an output line this: -xxxxxxx... 1st on a -----------------------------------------------------------------------+--graph::++ Draw a text-based graphical representation of the commit history+ on the left hand side of the output. This may cause extra lines+ to be printed in between commits, in order for the graph history+ to be drawn properly.+++This implies the '--topo-order' option by default, but the+'--date-order' option may also be specified.+ Diff Formatting ~~~~~~~~~~~~~~~
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
On Sun, Apr 06, 2008 at 10:06:24PM +0100, Johannes Schindelin wrote:
On Sun, 6 Apr 2008, Adam Simpkins wrote:
quoted
+/* Defined in commit.h */
+struct commit;
+/* Defined in strbuf.h */
+struct strbuf;
You do not need those.
I added them so that graph.h can be included without including any
other header files first. They can be taken out if we assume that all
users of graph.h will include commit.h and strbuf.h first.
Apart from that, it looks very, very clean to me. (Except maybe the
prefix ++ that could have been a postfix ++ in the line before, but that
is just me.)
Sorry, force of habit. I tried to remember to use postfix in most
places, but I guess I forgot in that place.
I do most of my programming in C++, which allows crazy things like
defining prefix and postfix ++ and -- operators on classes. When
using these on classes, the prefix operator is normally more efficient
than the postfix version, so I'm just in the habit of using prefix
increment everywhere. This can easily be changed if postfix is
preferred for the git coding style.
--
Adam Simpkins
adam@adamsimpkins.net
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:44:27
Hi,
On Sun, 6 Apr 2008, Adam Simpkins wrote:
On Sun, Apr 06, 2008 at 10:06:24PM +0100, Johannes Schindelin wrote:
quoted
On Sun, 6 Apr 2008, Adam Simpkins wrote:
quoted
+/* Defined in commit.h */
+struct commit;
+/* Defined in strbuf.h */
+struct strbuf;
You do not need those.
I added them so that graph.h can be included without including any other
header files first. They can be taken out if we assume that all users
of graph.h will include commit.h and strbuf.h first.
AFAICT you do not even need them then. Using "struct strbuf *" without
ever declaring struct strbuf before that is perfectly valid.
Ciao,
Dscho
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
On Sun, Apr 06, 2008 at 09:42:20PM +0100, Johannes Schindelin wrote:
Hi,
On Sun, 6 Apr 2008, Adam Simpkins wrote:
quoted
I do like the fact that git-forest prints the names of the refs that
point to each commit. For the graphing API, we could perhaps add a "%r"
specifier to --pretty=format to print the refs pointing to the commit.
Would "--decorate" help?
Yes, it does. Unfortunately, it doesn't have any effect with
--pretty=format.
Actually, going back and testing this, it looks like I have a bug when
handling --graph together with --pretty=format. There's a missing
newline after the user's format message and the next graph line. I'll
try to fix this and submit a patch later this evening.
--
Adam Simpkins
adam@adamsimpkins.net
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
On Mon, Apr 07, 2008 at 12:15:32AM +0300, Teemu Likonen wrote:
Adam Simpkins kirjoitti:
quoted
The --graph option causes a text-based representation of the history
graph to be printed on the left-hand side of the output.
The '--graph' seems to work nicely with every '--pretty=' option
except 'email'.
$ git log --graph --pretty=email
Yep, I forgot to test that one. Thanks for pointing it out.
It looks like it shouldn't be too hard to fix. I'll try to fix it and
submit a patch later this evening.
--
Adam Simpkins
adam@adamsimpkins.net
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
On Sun, Apr 06, 2008 at 11:15:58PM +0100, Johannes Schindelin wrote:
On Sun, 6 Apr 2008, Adam Simpkins wrote:
quoted
On Sun, Apr 06, 2008 at 10:06:24PM +0100, Johannes Schindelin wrote:
quoted
On Sun, 6 Apr 2008, Adam Simpkins wrote:
quoted
+/* Defined in commit.h */
+struct commit;
+/* Defined in strbuf.h */
+struct strbuf;
You do not need those.
I added them so that graph.h can be included without including any other
header files first. They can be taken out if we assume that all users
of graph.h will include commit.h and strbuf.h first.
AFAICT you do not even need them then. Using "struct strbuf *" without
ever declaring struct strbuf before that is perfectly valid.
Trying to compile the following test code with gcc 4.1.2 results in a
warning.
test.c:
#include <stdio.h>
void test(struct strbuf *sb);
int main(int argc, char **argv)
{
test(NULL);
return 0;
}
$ gcc -c test.c
test.c:3: warning: ‘struct strbuf’ declared inside parameter list
test.c:3: warning: its scope is only this definition or declaration, which is probably not what you want
--
Adam Simpkins
adam@adamsimpkins.net
From: Teemu Likonen <hidden> Date: 2016-06-15 22:44:27
Adam Simpkins kirjoitti:
Actually, going back and testing this, it looks like I have a bug
when handling --graph together with --pretty=format. There's a
missing newline after the user's format message and the next graph
line. I'll try to fix this and submit a patch later this evening.
Also, the output is not indented for options that display some
additional information to commit message. Those include:
--raw
--stat
--numstat
--shortstat
--summary
--name-only
--name-status
I'm not sure if the diff output of -p, -u etc. should be
indented--probably not--but for different stat and summary options it
would be nice to not have their output displayed over the graph area.
Especially --name-status is funny since it displays "M" to column 1 to
indicate modified file while "M" also means merge commit in the graph.
From: Teemu Likonen <hidden> Date: 2016-06-15 22:44:27
Adam Simpkins kirjoitti (6.4.2008 klo 11.42):
[...] graphing API [...] is more similar to gitk's graph, which many
people are already familiar with. It also doesn't require a terminal
with Unicode support.
As I've spent some time in testing the --graph functionality I'm
spamming my discoveries here.
When limiting the log output to a subdirectory or to a file the graph
becomes quite hard to understand. Probably the easiest way to
demonstrate my point is to compare side by side (for example)
git log --graph --pretty=oneline -- Documentation/
and
gitk -- Documentation/
in the Git repository. gitk draws lines between commits even when they
are not in direct parent-child relationship (i.e. there is longer series
of commits between them). With log --graph it's hard to tell which
development line some commits come from.
The whole-repository log graphs seem to work nicely though.
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
This change automatically enables parent rewriting when --graph is
specified. This makes the graph output look much nicer when commit
pruning is enabled.
The existing rev_info "parents" flag has been split into
two flags: "rewrite_parents" causes the parents to be rewritten, while
"print_parents" causes the log and rev-list commands to print the
parents. The --parents option now enables both rewrite_parents and
print_parents, while --graph enables only rewrite_parents.
Signed-off-by: Adam Simpkins <redacted>
---
builtin-rev-list.c | 2 +-
log-tree.c | 4 ++--
revision.c | 8 +++++---
revision.h | 3 ++-
4 files changed, 10 insertions(+), 7 deletions(-)
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
As pointed out by Teemu Likonen, the initial line of
pretty_print_commit() output wasn't correctly prefixed by the graph
information.
Signed-off-by: Adam Simpkins <redacted>
---
log-tree.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
- Removed pre-declarations of structs from graph.h; all users are
expected to include the necessary header files first.
- Replaced prefix increment and decrement operators with postfix
operators
Signed-off-by: Adam Simpkins <redacted>
---
graph.c | 42 +++++++++++++++++++++---------------------
graph.h | 5 -----
2 files changed, 21 insertions(+), 26 deletions(-)
@@ -4,11 +4,6 @@/* A graph is a pointer to this opaque structure */structgit_graph;-/* Defined in commit.h */-structcommit;-/* Defined in strbuf.h */-structstrbuf;-/**Createanewstructgit_graph.*Thegraphshouldbefreedwithgraph_release()whennolongerneeded.
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
Previously, the --graph option had problems when used together with
--pretty=format. The output was missing a newline at the end of each
entry, before the next graph line.
This change updates the code to treat CMIT_FMT_USERFORMAT just like
CMIT_FMT_ONELINE, even when --graph is not in use. Like
CMIT_FMT_ONELINE, the pretty_print_commit() output for
CMIT_FMT_USERFORMAT lacks a terminating newline. Similarly, there
should be no blank line between entries for CMIT_FMT_USERFORMAT.
The old code took care of these cases for CMIT_FMT_ONELINE, but not for
CMIT_FMT_USERFORMAT. For CMIT_FMT_USERFORMAT, show_log() left each
entry without a terminating newline. The next call to show_log() would
then try to print an extra blank line between entries. However, since
the previous entry lacked a newline, the "blank line" simply added a
newline at the end of the previous entry. For the most part, this made
the output look correct. The very last entry in the output was always
missing a terminating newline, but piping the output through less would
hide this fact. (Running with --no-pager would clearly show the missing
newline at the end of the output.)
I believe the old behavior was accidental, rather than intentional. The
new code always prints a newline at the end of the last entry.
Signed-off-by: Adam Simpkins <redacted>
---
builtin-rev-list.c | 52 ++++++++++++++---------------
graph.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++
graph.h | 20 ++++++++++-
log-tree.c | 61 ++++++++++++++-------------------
4 files changed, 163 insertions(+), 63 deletions(-)
@@ -630,7 +629,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)}if(revs.commit_format!=CMIT_FMT_UNSPECIFIED){/* The command line has a --pretty */-hdr_termination='\n';if(revs.commit_format==CMIT_FMT_ONELINE)header_prefix="";else
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
On Mon, Apr 07, 2008 at 10:26:29AM +0300, Teemu Likonen wrote:
As I've spent some time in testing the --graph functionality I'm
spamming my discoveries here.
When limiting the log output to a subdirectory or to a file the graph
becomes quite hard to understand. Probably the easiest way to
demonstrate my point is to compare side by side (for example)
git log --graph --pretty=oneline -- Documentation/
and
gitk -- Documentation/
in the Git repository. gitk draws lines between commits even when they
are not in direct parent-child relationship (i.e. there is longer series
of commits between them). With log --graph it's hard to tell which
development line some commits come from.
Interesting, I wasn't aware of this gitk behavior. I took a look at
the gitk code, and they're able to do this by passing the "--parents"
option to "git log". This causes git to rewrite the parent
information so that it lists the most recent ancestor that is in the
resulting commit set, instead of the actual parent.
It was pretty easy to change "git log --graph" to do the same; I just
sent out a new patch for it.
Thanks for all the testing!
--
Adam Simpkins
adam@adamsimpkins.net
From: Adam Simpkins <hidden> Date: 2016-06-15 22:44:27
On Mon, Apr 07, 2008 at 08:24:10AM +0300, Teemu Likonen wrote:
Adam Simpkins kirjoitti:
quoted
Actually, going back and testing this, it looks like I have a bug
when handling --graph together with --pretty=format. There's a
missing newline after the user's format message and the next graph
line. I'll try to fix this and submit a patch later this evening.
Also, the output is not indented for options that display some
additional information to commit message. Those include:
--raw
--stat
--numstat
--shortstat
--summary
--name-only
--name-status
I'm not sure if the diff output of -p, -u etc. should be
indented--probably not--but for different stat and summary options it
would be nice to not have their output displayed over the graph area.
Especially --name-status is funny since it displays "M" to column 1 to
indicate modified file while "M" also means merge commit in the graph.
Hmm. This is a harder problem to fix. All of the options you list
above are handled by the internal diff API. The diff API doesn't have
any knowledge about log and rev-list options, such as --graph.
The nicest way to fix this would probably be to write new diff API
functions that output to a strbuf instead of printing directly to
stdout. Then the log code could prefix each line of the buffer with
the graph info before printing it.
However, this would be a lot of work, and I'm not sure that it's
really worth the effort at the moment. For now, I'm leaning towards
changing the code to just exit with an error if --graph is used with
any of these options.
Any opinions? Alternative suggestions?
--
Adam Simpkins
adam@adamsimpkins.net
From: Teemu Likonen <hidden> Date: 2016-06-15 22:44:27
Adam Simpkins kirjoitti (7.4.2008 klo 1.34):
The nicest way to fix this would probably be to write new diff API
functions that output to a strbuf instead of printing directly to
stdout. Then the log code could prefix each line of the buffer with
the graph info before printing it.
However, this would be a lot of work, and I'm not sure that it's
really worth the effort at the moment. For now, I'm leaning towards
changing the code to just exit with an error if --graph is used with
any of these options.
Any opinions? Alternative suggestions?
Ok, then I'd suggest that it's left as is. The --graph may be useful
with some stat options even when the graph area is parially broken by
some other output.
From: Teemu Likonen <hidden> Date: 2016-06-15 22:44:27
Signed-off-by: Teemu Likonen <redacted>
---
Hmm, why not add some more useful long options? There are plenty of them of
course but I feel these are one of the most common.
contrib/completion/git-completion.bash | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
AFAICT you do not even need them then. Using "struct strbuf *" without
ever declaring struct strbuf before that is perfectly valid.
In traditional C, and inside structure declarations etc, yes.
In modern C, in other contexts, no.
Modern C considers a function declaration to be its own scope (it's the
scope of the function definition, which in a declaration is obviously
just the declaration). So if you use a "struct xyzzy *" in a function
declaration, it will be a *different* "struct xyzzy *" from one declared
later.
Try to compile something like this:
int fn(struct xyzzy *);
int fn(struct xyzzy *);
with a modern C compiler, and it will actually say something along the
lines of "conflicting types for ‘fn’", because while the two declarations
look identical, they actually have two different (private) declarations of
"struct xyzzy" going on.
But to make it even more interesting, you don't actually need a full
declaration of "struct xyzzy" to make the compiler happy, you only need an
implicit one ahead of time. You can do that with the incomplete
declaration, of course (like the --graph patch did), ie just a simple
struct xyzzy;
before those declarations is sufficient, but so is the implicit
declaration of just using the pointer to it in some non-private scope, ie
it's equally valid to do
struct foobar {
struct xyzzy *ptr;
};
and this will already be enough to declare "struct xyzzy" in scope for the
function declarations afterwards.
Is this illogical? Somewhat. Why is it a private scope in a function
declaration but not in a struct declaration? Why isn't the function scope
limited to the stuff *inside* the function? Somebody probably knows, but
for the rest of us the answer is just "that's how it is, deal with it".
Linus