Autogenerated HTML docs for v1.7.6-472-g4bfe7
[git/jnareb-git.git] / technical / api-history-graph.html
blobc3e7aade9262c0ba1a1d7212aaa0cbc7fee38215
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.4.5" />
7 <title>history graph API</title>
8 <style type="text/css">
9 /* Debug borders */
10 p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
12 border: 1px solid red;
16 body {
17 margin: 1em 5% 1em 5%;
20 a {
21 color: blue;
22 text-decoration: underline;
24 a:visited {
25 color: fuchsia;
28 em {
29 font-style: italic;
30 color: navy;
33 strong {
34 font-weight: bold;
35 color: #083194;
38 tt {
39 color: navy;
42 h1, h2, h3, h4, h5, h6 {
43 color: #527bbd;
44 font-family: sans-serif;
45 margin-top: 1.2em;
46 margin-bottom: 0.5em;
47 line-height: 1.3;
50 h1, h2, h3 {
51 border-bottom: 2px solid silver;
53 h2 {
54 padding-top: 0.5em;
56 h3 {
57 float: left;
59 h3 + * {
60 clear: left;
63 div.sectionbody {
64 font-family: serif;
65 margin-left: 0;
68 hr {
69 border: 1px solid silver;
72 p {
73 margin-top: 0.5em;
74 margin-bottom: 0.5em;
77 ul, ol, li > p {
78 margin-top: 0;
81 pre {
82 padding: 0;
83 margin: 0;
86 span#author {
87 color: #527bbd;
88 font-family: sans-serif;
89 font-weight: bold;
90 font-size: 1.1em;
92 span#email {
94 span#revnumber, span#revdate, span#revremark {
95 font-family: sans-serif;
98 div#footer {
99 font-family: sans-serif;
100 font-size: small;
101 border-top: 2px solid silver;
102 padding-top: 0.5em;
103 margin-top: 4.0em;
105 div#footer-text {
106 float: left;
107 padding-bottom: 0.5em;
109 div#footer-badges {
110 float: right;
111 padding-bottom: 0.5em;
114 div#preamble {
115 margin-top: 1.5em;
116 margin-bottom: 1.5em;
118 div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
119 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
120 div.admonitionblock {
121 margin-top: 1.5em;
122 margin-bottom: 1.5em;
124 div.admonitionblock {
125 margin-top: 2.5em;
126 margin-bottom: 2.5em;
129 div.content { /* Block element content. */
130 padding: 0;
133 /* Block element titles. */
134 div.title, caption.title {
135 color: #527bbd;
136 font-family: sans-serif;
137 font-weight: bold;
138 text-align: left;
139 margin-top: 1.0em;
140 margin-bottom: 0.5em;
142 div.title + * {
143 margin-top: 0;
146 td div.title:first-child {
147 margin-top: 0.0em;
149 div.content div.title:first-child {
150 margin-top: 0.0em;
152 div.content + div.title {
153 margin-top: 0.0em;
156 div.sidebarblock > div.content {
157 background: #ffffee;
158 border: 1px solid silver;
159 padding: 0.5em;
162 div.listingblock > div.content {
163 border: 1px solid silver;
164 background: #f4f4f4;
165 padding: 0.5em;
168 div.quoteblock {
169 padding-left: 2.0em;
170 margin-right: 10%;
172 div.quoteblock > div.attribution {
173 padding-top: 0.5em;
174 text-align: right;
177 div.verseblock {
178 padding-left: 2.0em;
179 margin-right: 10%;
181 div.verseblock > div.content {
182 white-space: pre;
184 div.verseblock > div.attribution {
185 padding-top: 0.75em;
186 text-align: left;
188 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
189 div.verseblock + div.attribution {
190 text-align: left;
193 div.admonitionblock .icon {
194 vertical-align: top;
195 font-size: 1.1em;
196 font-weight: bold;
197 text-decoration: underline;
198 color: #527bbd;
199 padding-right: 0.5em;
201 div.admonitionblock td.content {
202 padding-left: 0.5em;
203 border-left: 2px solid silver;
206 div.exampleblock > div.content {
207 border-left: 2px solid silver;
208 padding: 0.5em;
211 div.imageblock div.content { padding-left: 0; }
212 span.image img { border-style: none; }
213 a.image:visited { color: white; }
215 dl {
216 margin-top: 0.8em;
217 margin-bottom: 0.8em;
219 dt {
220 margin-top: 0.5em;
221 margin-bottom: 0;
222 font-style: normal;
223 color: navy;
225 dd > *:first-child {
226 margin-top: 0.1em;
229 ul, ol {
230 list-style-position: outside;
232 ol.arabic {
233 list-style-type: decimal;
235 ol.loweralpha {
236 list-style-type: lower-alpha;
238 ol.upperalpha {
239 list-style-type: upper-alpha;
241 ol.lowerroman {
242 list-style-type: lower-roman;
244 ol.upperroman {
245 list-style-type: upper-roman;
248 div.compact ul, div.compact ol,
249 div.compact p, div.compact p,
250 div.compact div, div.compact div {
251 margin-top: 0.1em;
252 margin-bottom: 0.1em;
255 div.tableblock > table {
256 border: 3px solid #527bbd;
258 thead {
259 font-family: sans-serif;
260 font-weight: bold;
262 tfoot {
263 font-weight: bold;
265 td > div.verse {
266 white-space: pre;
268 p.table {
269 margin-top: 0;
271 /* Because the table frame attribute is overriden by CSS in most browsers. */
272 div.tableblock > table[frame="void"] {
273 border-style: none;
275 div.tableblock > table[frame="hsides"] {
276 border-left-style: none;
277 border-right-style: none;
279 div.tableblock > table[frame="vsides"] {
280 border-top-style: none;
281 border-bottom-style: none;
285 div.hdlist {
286 margin-top: 0.8em;
287 margin-bottom: 0.8em;
289 div.hdlist tr {
290 padding-bottom: 15px;
292 dt.hdlist1.strong, td.hdlist1.strong {
293 font-weight: bold;
295 td.hdlist1 {
296 vertical-align: top;
297 font-style: normal;
298 padding-right: 0.8em;
299 color: navy;
301 td.hdlist2 {
302 vertical-align: top;
304 div.hdlist.compact tr {
305 margin: 0;
306 padding-bottom: 0;
309 .comment {
310 background: yellow;
313 @media print {
314 div#footer-badges { display: none; }
317 div#toctitle {
318 color: #527bbd;
319 font-family: sans-serif;
320 font-size: 1.1em;
321 font-weight: bold;
322 margin-top: 1.0em;
323 margin-bottom: 0.1em;
326 div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
327 margin-top: 0;
328 margin-bottom: 0;
330 div.toclevel2 {
331 margin-left: 2em;
332 font-size: 0.9em;
334 div.toclevel3 {
335 margin-left: 4em;
336 font-size: 0.9em;
338 div.toclevel4 {
339 margin-left: 6em;
340 font-size: 0.9em;
342 /* Workarounds for IE6's broken and incomplete CSS2. */
344 div.sidebar-content {
345 background: #ffffee;
346 border: 1px solid silver;
347 padding: 0.5em;
349 div.sidebar-title, div.image-title {
350 color: #527bbd;
351 font-family: sans-serif;
352 font-weight: bold;
353 margin-top: 0.0em;
354 margin-bottom: 0.5em;
357 div.listingblock div.content {
358 border: 1px solid silver;
359 background: #f4f4f4;
360 padding: 0.5em;
363 div.quoteblock-attribution {
364 padding-top: 0.5em;
365 text-align: right;
368 div.verseblock-content {
369 white-space: pre;
371 div.verseblock-attribution {
372 padding-top: 0.75em;
373 text-align: left;
376 div.exampleblock-content {
377 border-left: 2px solid silver;
378 padding-left: 0.5em;
381 /* IE6 sets dynamically generated links as visited. */
382 div#toc a:visited { color: blue; }
383 </style>
384 </head>
385 <body>
386 <div id="header">
387 <h1>history graph API</h1>
388 </div>
389 <div id="preamble">
390 <div class="sectionbody">
391 <div class="paragraph"><p>The graph API is used to draw a text-based representation of the commit
392 history. The API generates the graph in a line-by-line fashion.</p></div>
393 </div>
394 </div>
395 <h2 id="_functions">Functions</h2>
396 <div class="sectionbody">
397 <div class="paragraph"><p>Core functions:</p></div>
398 <div class="ulist"><ul>
399 <li>
401 <tt>graph_init()</tt> creates a new <tt>struct git_graph</tt>
402 </p>
403 </li>
404 <li>
406 <tt>graph_update()</tt> moves the graph to a new commit.
407 </p>
408 </li>
409 <li>
411 <tt>graph_next_line()</tt> outputs the next line of the graph into a strbuf. It
412 does not add a terminating newline.
413 </p>
414 </li>
415 <li>
417 <tt>graph_padding_line()</tt> outputs a line of vertical padding in the graph. It
418 is similar to <tt>graph_next_line()</tt>, but is guaranteed to never print the line
419 containing the current commit. Where <tt>graph_next_line()</tt> would print the
420 commit line next, <tt>graph_padding_line()</tt> prints a line that simply extends
421 all branch lines downwards one row, leaving their positions unchanged.
422 </p>
423 </li>
424 <li>
426 <tt>graph_is_commit_finished()</tt> determines if the graph has output all lines
427 necessary for the current commit. If <tt>graph_update()</tt> is called before all
428 lines for the current commit have been printed, the next call to
429 <tt>graph_next_line()</tt> will output an ellipsis, to indicate that a portion of
430 the graph was omitted.
431 </p>
432 </li>
433 </ul></div>
434 <div class="paragraph"><p>The following utility functions are wrappers around <tt>graph_next_line()</tt> and
435 <tt>graph_is_commit_finished()</tt>. They always print the output to stdout.
436 They can all be called with a NULL graph argument, in which case no graph
437 output will be printed.</p></div>
438 <div class="ulist"><ul>
439 <li>
441 <tt>graph_show_commit()</tt> calls <tt>graph_next_line()</tt> until it returns non-zero.
442 This prints all graph lines up to, and including, the line containing this
443 commit. Output is printed to stdout. The last line printed does not contain
444 a terminating newline. This should not be called if the commit line has
445 already been printed, or it will loop forever.
446 </p>
447 </li>
448 <li>
450 <tt>graph_show_oneline()</tt> calls <tt>graph_next_line()</tt> and prints the result to
451 stdout. The line printed does not contain a terminating newline.
452 </p>
453 </li>
454 <li>
456 <tt>graph_show_padding()</tt> calls <tt>graph_padding_line()</tt> and prints the result to
457 stdout. The line printed does not contain a terminating newline.
458 </p>
459 </li>
460 <li>
462 <tt>graph_show_remainder()</tt> calls <tt>graph_next_line()</tt> until
463 <tt>graph_is_commit_finished()</tt> returns non-zero. Output is printed to stdout.
464 The last line printed does not contain a terminating newline. Returns 1 if
465 output was printed, and 0 if no output was necessary.
466 </p>
467 </li>
468 <li>
470 <tt>graph_show_strbuf()</tt> prints the specified strbuf to stdout, prefixing all
471 lines but the first with a graph line. The caller is responsible for
472 ensuring graph output for the first line has already been printed to stdout.
473 (This can be done with <tt>graph_show_commit()</tt> or <tt>graph_show_oneline()</tt>.) If
474 a NULL graph is supplied, the strbuf is printed as-is.
475 </p>
476 </li>
477 <li>
479 <tt>graph_show_commit_msg()</tt> is similar to <tt>graph_show_strbuf()</tt>, but it also
480 prints the remainder of the graph, if more lines are needed after the strbuf
481 ends. It is better than directly calling <tt>graph_show_strbuf()</tt> followed by
482 <tt>graph_show_remainder()</tt> since it properly handles buffers that do not end in
483 a terminating newline. The output printed by <tt>graph_show_commit_msg()</tt> will
484 end in a newline if and only if the strbuf ends in a newline.
485 </p>
486 </li>
487 </ul></div>
488 </div>
489 <h2 id="_data_structure">Data structure</h2>
490 <div class="sectionbody">
491 <div class="paragraph"><p><tt>struct git_graph</tt> is an opaque data type used to store the current graph
492 state.</p></div>
493 </div>
494 <h2 id="_calling_sequence">Calling sequence</h2>
495 <div class="sectionbody">
496 <div class="ulist"><ul>
497 <li>
499 Create a <tt>struct git_graph</tt> by calling <tt>graph_init()</tt>. When using the
500 revision walking API, this is done automatically by <tt>setup_revisions()</tt> if
501 the <em>--graph</em> option is supplied.
502 </p>
503 </li>
504 <li>
506 Use the revision walking API to walk through a group of contiguous commits.
507 The <tt>get_revision()</tt> function automatically calls <tt>graph_update()</tt> each time
508 it is invoked.
509 </p>
510 </li>
511 <li>
513 For each commit, call <tt>graph_next_line()</tt> repeatedly, until
514 <tt>graph_is_commit_finished()</tt> returns non-zero. Each call go
515 <tt>graph_next_line()</tt> will output a single line of the graph. The resulting
516 lines will not contain any newlines. <tt>graph_next_line()</tt> returns 1 if the
517 resulting line contains the current commit, or 0 if this is merely a line
518 needed to adjust the graph before or after the current commit. This return
519 value can be used to determine where to print the commit summary information
520 alongside the graph output.
521 </p>
522 </li>
523 </ul></div>
524 </div>
525 <h2 id="_limitations">Limitations</h2>
526 <div class="sectionbody">
527 <div class="ulist"><ul>
528 <li>
530 <tt>graph_update()</tt> must be called with commits in topological order. It should
531 not be called on a commit if it has already been invoked with an ancestor of
532 that commit, or the graph output will be incorrect.
533 </p>
534 </li>
535 <li>
537 <tt>graph_update()</tt> must be called on a contiguous group of commits. If
538 <tt>graph_update()</tt> is called on a particular commit, it should later be called
539 on all parents of that commit. Parents must not be skipped, or the graph
540 output will appear incorrect.
541 </p>
542 <div class="paragraph"><p><tt>graph_update()</tt> may be used on a pruned set of commits only if the parent list
543 has been rewritten so as to include only ancestors from the pruned set.</p></div>
544 </li>
545 <li>
547 The graph API does not currently support reverse commit ordering. In
548 order to implement reverse ordering, the graphing API needs an
549 (efficient) mechanism to find the children of a commit.
550 </p>
551 </li>
552 </ul></div>
553 </div>
554 <h2 id="_sample_usage">Sample usage</h2>
555 <div class="sectionbody">
556 <div class="listingblock">
557 <div class="content">
558 <pre><tt>struct commit *commit;
559 struct git_graph *graph = graph_init(opts);
561 while ((commit = get_revision(opts)) != NULL) {
562 graph_update(graph, commit);
563 while (!graph_is_commit_finished(graph))
565 struct strbuf sb;
566 int is_commit_line;
568 strbuf_init(&amp;sb, 0);
569 is_commit_line = graph_next_line(graph, &amp;sb);
570 fputs(sb.buf, stdout);
572 if (is_commit_line)
573 log_tree_commit(opts, commit);
574 else
575 putchar(opts-&gt;diffopt.line_termination);
577 }</tt></pre>
578 </div></div>
579 </div>
580 <h2 id="_sample_output">Sample output</h2>
581 <div class="sectionbody">
582 <div class="paragraph"><p>The following is an example of the output from the graph API. This output does
583 not include any commit summary information&#8212;callers are responsible for
584 outputting that information, if desired.</p></div>
585 <div class="listingblock">
586 <div class="content">
587 <pre><tt>*
592 | | *
593 | \ \
594 | \ \
595 *-. \ \
596 |\ \ \ \
597 | | * | |
598 | | | | | *
599 | | | | | *
600 | | | | | *
601 | | | | | |\
602 | | | | | | *
603 | * | | | | |
604 | | | | | * \
605 | | | | | |\ |
606 | | | | * | | |
607 | | | | * | | |
608 * | | | | | | |
609 | |/ / / / / /
610 |/| / / / / /
611 * | | | | | |
612 |/ / / / / /
613 * | | | | |
614 | | | | | *
615 | | | | |/
616 | | | | *</tt></pre>
617 </div></div>
618 </div>
619 <div id="footer">
620 <div id="footer-text">
621 Last updated 2009-11-23 06:10:40 UTC
622 </div>
623 </div>
624 </body>
625 </html>