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
{
@@ -1745,7 +1752,8 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
1745
1752
* The blame_entry is found to be guilty for the range.
1746
1753
* Show it in incremental output.
1747
1754
*/
1748
- static void found_guilty_entry (struct blame_entry * ent )
1755
+ static void found_guilty_entry (struct blame_entry * ent ,
1756
+ struct progress_info * pi )
1749
1757
{
1750
1758
if (incremental ) {
1751
1759
struct origin * suspect = ent -> suspect ;
@@ -1757,6 +1765,8 @@ static void found_guilty_entry(struct blame_entry *ent)
1757
1765
write_filename_info (suspect -> path );
1758
1766
maybe_flush_or_die (stdout , "stdout" );
1759
1767
}
1768
+ pi -> blamed_lines += ent -> num_lines ;
1769
+ display_progress (pi -> progress , pi -> blamed_lines );
1760
1770
}
1761
1771
1762
1772
/*
@@ -1767,6 +1777,11 @@ static void assign_blame(struct scoreboard *sb, int opt)
1767
1777
{
1768
1778
struct rev_info * revs = sb -> revs ;
1769
1779
struct commit * commit = prio_queue_get (& sb -> commits );
1780
+ struct progress_info pi = { NULL , 0 };
1781
+
1782
+ if (show_progress )
1783
+ pi .progress = start_progress_delay (_ ("Blaming lines" ),
1784
+ sb -> num_lines , 50 , 1 );
1770
1785
1771
1786
while (commit ) {
1772
1787
struct blame_entry * ent ;
@@ -1808,7 +1823,7 @@ static void assign_blame(struct scoreboard *sb, int opt)
1808
1823
suspect -> guilty = 1 ;
1809
1824
for (;;) {
1810
1825
struct blame_entry * next = ent -> next ;
1811
- found_guilty_entry (ent );
1826
+ found_guilty_entry (ent , & pi );
1812
1827
if (next ) {
1813
1828
ent = next ;
1814
1829
continue ;
@@ -1824,6 +1839,8 @@ static void assign_blame(struct scoreboard *sb, int opt)
1824
1839
if (DEBUG ) /* sanity */
1825
1840
sanity_check_refcnt (sb );
1826
1841
}
1842
+
1843
+ stop_progress (& pi .progress );
1827
1844
}
1828
1845
1829
1846
static const char * format_time (unsigned long time , const char * tz_str ,
@@ -2513,6 +2530,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2513
2530
OPT_BOOL ('b' , NULL , & blank_boundary , N_ ("Show blank SHA-1 for boundary commits (Default: off)" )),
2514
2531
OPT_BOOL (0 , "root" , & show_root , N_ ("Do not treat root commits as boundaries (Default: off)" )),
2515
2532
OPT_BOOL (0 , "show-stats" , & show_stats , N_ ("Show work cost statistics" )),
2533
+ OPT_BOOL (0 , "progress" , & show_progress , N_ ("Force progress reporting" )),
2516
2534
OPT_BIT (0 , "score-debug" , & output_option , N_ ("Show output score for blame entries" ), OUTPUT_SHOW_SCORE ),
2517
2535
OPT_BIT ('f' , "show-name" , & output_option , N_ ("Show original filename (Default: auto)" ), OUTPUT_SHOW_NAME ),
2518
2536
OPT_BIT ('n' , "show-number" , & output_option , N_ ("Show original linenumber (Default: off)" ), OUTPUT_SHOW_NUMBER ),
@@ -2548,6 +2566,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2548
2566
2549
2567
save_commit_buffer = 0 ;
2550
2568
dashdash_pos = 0 ;
2569
+ show_progress = -1 ;
2551
2570
2552
2571
parse_options_start (& ctx , argc , argv , prefix , options ,
2553
2572
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 );
@@ -2572,6 +2591,13 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2572
2591
DIFF_OPT_CLR (& revs .diffopt , FOLLOW_RENAMES );
2573
2592
argc = parse_options_end (& ctx );
2574
2593
2594
+ if (incremental || (output_option & OUTPUT_PORCELAIN )) {
2595
+ if (show_progress > 0 )
2596
+ die ("--progress can't be used with --incremental or porcelain formats" );
2597
+ show_progress = 0 ;
2598
+ } else if (show_progress < 0 )
2599
+ show_progress = isatty (2 );
2600
+
2575
2601
if (0 < abbrev )
2576
2602
/* one more abbrev length is needed for the boundary commit */
2577
2603
abbrev ++ ;
@@ -2797,11 +2823,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2797
2823
2798
2824
read_mailmap (& mailmap , NULL );
2799
2825
2826
+ assign_blame (& sb , opt );
2827
+
2800
2828
if (!incremental )
2801
2829
setup_pager ();
2802
2830
2803
- assign_blame (& sb , opt );
2804
-
2805
2831
free (final_commit_name );
2806
2832
2807
2833
if (incremental )
0 commit comments