Michael J Gruber <git@xxxxxxxxxxxxxxxxxxxx> writes: > Again, I'm sorry I'm not seeing through the call chain here. diff_flush() notices it needs to produce textual patch and count added or deleted lines here: if (output_format & (DIFF_FORMAT_DIFFSTAT|DIFF_FORMAT... struct diffstat_t diffstat; memset(&diffstat, 0, sizeof(struct diffstat_t)); for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; if (check_pair_status(p)) diff_flush_stat(p, options, &diffstat); } if (output_format & DIFF_FORMAT_NUMSTAT) show_numstat(&diffstat, options); if (output_format & DIFF_FORMAT_DIFFSTAT) show_stats(&diffstat, options); if (output_format & DIFF_FORMAT_SHORTSTAT) show_shortstats(&diffstat, options); free_diffstat_info(&diffstat); separator++; } In the loop, it calls diff_flush_stat() for each and every filepair in the queue. The result is collected in &diffstat, and that is what your patch works on in show_stats() function. Before you look at it in show_stats(), the same &diffstat may be examined by show_numstat(), and after you look at it, the same &diffstat may be examined by show_shortstats(). diff_flush_stat() calls run_diffstat() to get textual patch for one filepair. It ends up calling builtin_diffstat(). builtin_diffstat() looks at the preimage and postimage, and feeds the low level xdiff machinery with it, and uses diffstat_consume() callbac to count the +/- lines in the patch between the two. Even though three show_*stat* function look at the same &diffstat, two have duplicated logic to ignore (and uncount) a path whose executable bit was changed without any other change, with: if (!it->is_renamed && (added + deleted) == 0) ignore it! -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html