28
28
#include "line-range.h"
29
29
#include "line-log.h"
30
30
#include "dir.h"
31
+ #include "progress.h"
31
32
32
33
static char blame_usage [] = N_ ("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>" );
33
34
@@ -50,6 +51,7 @@ static int incremental;
50
51
static int xdl_opts ;
51
52
static int abbrev = -1 ;
52
53
static int no_whole_file_rename ;
54
+ static int show_progress ;
53
55
54
56
static struct date_mode blame_date_mode = { DATE_ISO8601 };
55
57
static size_t blame_date_width ;
@@ -127,6 +129,11 @@ struct origin {
127
129
char path [FLEX_ARRAY ];
128
130
};
129
131
132
+ struct progress_info {
133
+ struct progress * progress ;
134
+ int blamed_lines ;
135
+ };
136
+
130
137
static int diff_hunks (mmfile_t * file_a , mmfile_t * file_b , long ctxlen ,
131
138
xdl_emit_hunk_consume_func_t hunk_func , void * cb_data )
132
139
{
@@ -1746,7 +1753,8 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
1746
1753
* The blame_entry is found to be guilty for the range.
1747
1754
* Show it in incremental output.
1748
1755
*/
1749
- static void found_guilty_entry (struct blame_entry * ent )
1756
+ static void found_guilty_entry (struct blame_entry * ent ,
1757
+ struct progress_info * pi )
1750
1758
{
1751
1759
if (incremental ) {
1752
1760
struct origin * suspect = ent -> suspect ;
@@ -1758,6 +1766,8 @@ static void found_guilty_entry(struct blame_entry *ent)
1758
1766
write_filename_info (suspect -> path );
1759
1767
maybe_flush_or_die (stdout , "stdout" );
1760
1768
}
1769
+ pi -> blamed_lines += ent -> num_lines ;
1770
+ display_progress (pi -> progress , pi -> blamed_lines );
1761
1771
}
1762
1772
1763
1773
/*
@@ -1768,6 +1778,11 @@ static void assign_blame(struct scoreboard *sb, int opt)
1768
1778
{
1769
1779
struct rev_info * revs = sb -> revs ;
1770
1780
struct commit * commit = prio_queue_get (& sb -> commits );
1781
+ struct progress_info pi = { NULL , 0 };
1782
+
1783
+ if (show_progress )
1784
+ pi .progress = start_progress_delay (_ ("Blaming lines" ),
1785
+ sb -> num_lines , 50 , 1 );
1771
1786
1772
1787
while (commit ) {
1773
1788
struct blame_entry * ent ;
@@ -1809,7 +1824,7 @@ static void assign_blame(struct scoreboard *sb, int opt)
1809
1824
suspect -> guilty = 1 ;
1810
1825
for (;;) {
1811
1826
struct blame_entry * next = ent -> next ;
1812
- found_guilty_entry (ent );
1827
+ found_guilty_entry (ent , & pi );
1813
1828
if (next ) {
1814
1829
ent = next ;
1815
1830
continue ;
@@ -1825,6 +1840,8 @@ static void assign_blame(struct scoreboard *sb, int opt)
1825
1840
if (DEBUG ) /* sanity */
1826
1841
sanity_check_refcnt (sb );
1827
1842
}
1843
+
1844
+ stop_progress (& pi .progress );
1828
1845
}
1829
1846
1830
1847
static const char * format_time (unsigned long time , const char * tz_str ,
@@ -2520,6 +2537,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2520
2537
OPT_BOOL ('b' , NULL , & blank_boundary , N_ ("Show blank SHA-1 for boundary commits (Default: off)" )),
2521
2538
OPT_BOOL (0 , "root" , & show_root , N_ ("Do not treat root commits as boundaries (Default: off)" )),
2522
2539
OPT_BOOL (0 , "show-stats" , & show_stats , N_ ("Show work cost statistics" )),
2540
+ OPT_BOOL (0 , "progress" , & show_progress , N_ ("Force progress reporting" )),
2523
2541
OPT_BIT (0 , "score-debug" , & output_option , N_ ("Show output score for blame entries" ), OUTPUT_SHOW_SCORE ),
2524
2542
OPT_BIT ('f' , "show-name" , & output_option , N_ ("Show original filename (Default: auto)" ), OUTPUT_SHOW_NAME ),
2525
2543
OPT_BIT ('n' , "show-number" , & output_option , N_ ("Show original linenumber (Default: off)" ), OUTPUT_SHOW_NUMBER ),
@@ -2555,6 +2573,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2555
2573
2556
2574
save_commit_buffer = 0 ;
2557
2575
dashdash_pos = 0 ;
2576
+ show_progress = -1 ;
2558
2577
2559
2578
parse_options_start (& ctx , argc , argv , prefix , options ,
2560
2579
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 );
@@ -2579,6 +2598,13 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2579
2598
DIFF_OPT_CLR (& revs .diffopt , FOLLOW_RENAMES );
2580
2599
argc = parse_options_end (& ctx );
2581
2600
2601
+ if (incremental || (output_option & OUTPUT_PORCELAIN )) {
2602
+ if (show_progress > 0 )
2603
+ die ("--progress can't be used with --incremental or porcelain formats" );
2604
+ show_progress = 0 ;
2605
+ } else if (show_progress < 0 )
2606
+ show_progress = isatty (2 );
2607
+
2582
2608
if (0 < abbrev )
2583
2609
/* one more abbrev length is needed for the boundary commit */
2584
2610
abbrev ++ ;
@@ -2828,11 +2854,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2828
2854
2829
2855
read_mailmap (& mailmap , NULL );
2830
2856
2857
+ assign_blame (& sb , opt );
2858
+
2831
2859
if (!incremental )
2832
2860
setup_pager ();
2833
2861
2834
- assign_blame (& sb , opt );
2835
-
2836
2862
free (final_commit_name );
2837
2863
2838
2864
if (incremental )
0 commit comments