@@ -2544,6 +2544,105 @@ void init_scoreboard(struct blame_scoreboard *sb)
2544
2544
sb -> copy_score = BLAME_DEFAULT_COPY_SCORE ;
2545
2545
}
2546
2546
2547
+ void setup_scoreboard (struct blame_scoreboard * sb , const char * path , struct blame_origin * * orig )
2548
+ {
2549
+ const char * final_commit_name = NULL ;
2550
+ struct blame_origin * o ;
2551
+ struct commit * final_commit = NULL ;
2552
+ enum object_type type ;
2553
+
2554
+ if (sb -> reverse && sb -> contents_from )
2555
+ die (_ ("--contents and --reverse do not blend well." ));
2556
+
2557
+ if (!sb -> reverse ) {
2558
+ sb -> final = find_single_final (sb -> revs , & final_commit_name );
2559
+ sb -> commits .compare = compare_commits_by_commit_date ;
2560
+ } else {
2561
+ sb -> final = find_single_initial (sb -> revs , & final_commit_name );
2562
+ sb -> commits .compare = compare_commits_by_reverse_commit_date ;
2563
+ }
2564
+
2565
+ if (sb -> final && sb -> contents_from )
2566
+ die (_ ("cannot use --contents with final commit object name" ));
2567
+
2568
+ if (sb -> reverse && sb -> revs -> first_parent_only )
2569
+ sb -> revs -> children .name = NULL ;
2570
+
2571
+ if (!sb -> final ) {
2572
+ /*
2573
+ * "--not A B -- path" without anything positive;
2574
+ * do not default to HEAD, but use the working tree
2575
+ * or "--contents".
2576
+ */
2577
+ setup_work_tree ();
2578
+ sb -> final = fake_working_tree_commit (& sb -> revs -> diffopt ,
2579
+ path , sb -> contents_from );
2580
+ add_pending_object (sb -> revs , & (sb -> final -> object ), ":" );
2581
+ }
2582
+
2583
+ if (sb -> reverse && sb -> revs -> first_parent_only ) {
2584
+ final_commit = find_single_final (sb -> revs , NULL );
2585
+ if (!final_commit )
2586
+ die (_ ("--reverse and --first-parent together require specified latest commit" ));
2587
+ }
2588
+
2589
+ /*
2590
+ * If we have bottom, this will mark the ancestors of the
2591
+ * bottom commits we would reach while traversing as
2592
+ * uninteresting.
2593
+ */
2594
+ if (prepare_revision_walk (sb -> revs ))
2595
+ die (_ ("revision walk setup failed" ));
2596
+
2597
+ if (sb -> reverse && sb -> revs -> first_parent_only ) {
2598
+ struct commit * c = final_commit ;
2599
+
2600
+ sb -> revs -> children .name = "children" ;
2601
+ while (c -> parents &&
2602
+ oidcmp (& c -> object .oid , & sb -> final -> object .oid )) {
2603
+ struct commit_list * l = xcalloc (1 , sizeof (* l ));
2604
+
2605
+ l -> item = c ;
2606
+ if (add_decoration (& sb -> revs -> children ,
2607
+ & c -> parents -> item -> object , l ))
2608
+ die ("BUG: not unique item in first-parent chain" );
2609
+ c = c -> parents -> item ;
2610
+ }
2611
+
2612
+ if (oidcmp (& c -> object .oid , & sb -> final -> object .oid ))
2613
+ die (_ ("--reverse --first-parent together require range along first-parent chain" ));
2614
+ }
2615
+
2616
+ if (is_null_oid (& sb -> final -> object .oid )) {
2617
+ o = sb -> final -> util ;
2618
+ sb -> final_buf = xmemdupz (o -> file .ptr , o -> file .size );
2619
+ sb -> final_buf_size = o -> file .size ;
2620
+ }
2621
+ else {
2622
+ o = get_origin (sb -> final , path );
2623
+ if (fill_blob_sha1_and_mode (o ))
2624
+ die (_ ("no such path %s in %s" ), path , final_commit_name );
2625
+
2626
+ if (DIFF_OPT_TST (& sb -> revs -> diffopt , ALLOW_TEXTCONV ) &&
2627
+ textconv_object (path , o -> mode , & o -> blob_oid , 1 , (char * * ) & sb -> final_buf ,
2628
+ & sb -> final_buf_size ))
2629
+ ;
2630
+ else
2631
+ sb -> final_buf = read_sha1_file (o -> blob_oid .hash , & type ,
2632
+ & sb -> final_buf_size );
2633
+
2634
+ if (!sb -> final_buf )
2635
+ die (_ ("cannot read blob %s for path %s" ),
2636
+ oid_to_hex (& o -> blob_oid ),
2637
+ path );
2638
+ }
2639
+ sb -> num_read_blob ++ ;
2640
+ prepare_lines (sb );
2641
+
2642
+ if (orig )
2643
+ * orig = o ;
2644
+ }
2645
+
2547
2646
int cmd_blame (int argc , const char * * argv , const char * prefix )
2548
2647
{
2549
2648
struct rev_info revs ;
@@ -2552,9 +2651,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2552
2651
struct blame_origin * o ;
2553
2652
struct blame_entry * ent = NULL ;
2554
2653
long dashdash_pos , lno ;
2555
- const char * final_commit_name = NULL ;
2556
- enum object_type type ;
2557
- struct commit * final_commit = NULL ;
2558
2654
struct progress_info pi = { NULL , 0 };
2559
2655
2560
2656
struct string_list range_list = STRING_LIST_INIT_NODUP ;
@@ -2759,92 +2855,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2759
2855
sb .revs = & revs ;
2760
2856
sb .contents_from = contents_from ;
2761
2857
sb .reverse = reverse ;
2762
-
2763
- if (!reverse ) {
2764
- sb .final = find_single_final (& revs , & final_commit_name );
2765
- sb .commits .compare = compare_commits_by_commit_date ;
2766
- }
2767
- else if (contents_from )
2768
- die (_ ("--contents and --reverse do not blend well." ));
2769
- else {
2770
- sb .final = find_single_initial (& revs , & final_commit_name );
2771
- sb .commits .compare = compare_commits_by_reverse_commit_date ;
2772
- if (revs .first_parent_only )
2773
- revs .children .name = NULL ;
2774
- }
2775
-
2776
- if (!sb .final ) {
2777
- /*
2778
- * "--not A B -- path" without anything positive;
2779
- * do not default to HEAD, but use the working tree
2780
- * or "--contents".
2781
- */
2782
- setup_work_tree ();
2783
- sb .final = fake_working_tree_commit (& sb .revs -> diffopt ,
2784
- path , contents_from );
2785
- add_pending_object (& revs , & (sb .final -> object ), ":" );
2786
- }
2787
- else if (contents_from )
2788
- die (_ ("cannot use --contents with final commit object name" ));
2789
-
2790
- if (reverse && revs .first_parent_only ) {
2791
- final_commit = find_single_final (sb .revs , NULL );
2792
- if (!final_commit )
2793
- die (_ ("--reverse and --first-parent together require specified latest commit" ));
2794
- }
2795
-
2796
- /*
2797
- * If we have bottom, this will mark the ancestors of the
2798
- * bottom commits we would reach while traversing as
2799
- * uninteresting.
2800
- */
2801
- if (prepare_revision_walk (& revs ))
2802
- die (_ ("revision walk setup failed" ));
2803
-
2804
- if (reverse && revs .first_parent_only ) {
2805
- struct commit * c = final_commit ;
2806
-
2807
- sb .revs -> children .name = "children" ;
2808
- while (c -> parents &&
2809
- oidcmp (& c -> object .oid , & sb .final -> object .oid )) {
2810
- struct commit_list * l = xcalloc (1 , sizeof (* l ));
2811
-
2812
- l -> item = c ;
2813
- if (add_decoration (& sb .revs -> children ,
2814
- & c -> parents -> item -> object , l ))
2815
- die ("BUG: not unique item in first-parent chain" );
2816
- c = c -> parents -> item ;
2817
- }
2818
-
2819
- if (oidcmp (& c -> object .oid , & sb .final -> object .oid ))
2820
- die (_ ("--reverse --first-parent together require range along first-parent chain" ));
2821
- }
2822
-
2823
- if (is_null_oid (& sb .final -> object .oid )) {
2824
- o = sb .final -> util ;
2825
- sb .final_buf = xmemdupz (o -> file .ptr , o -> file .size );
2826
- sb .final_buf_size = o -> file .size ;
2827
- }
2828
- else {
2829
- o = get_origin (sb .final , path );
2830
- if (fill_blob_sha1_and_mode (o ))
2831
- die (_ ("no such path %s in %s" ), path , final_commit_name );
2832
-
2833
- if (DIFF_OPT_TST (& sb .revs -> diffopt , ALLOW_TEXTCONV ) &&
2834
- textconv_object (path , o -> mode , & o -> blob_oid , 1 , (char * * ) & sb .final_buf ,
2835
- & sb .final_buf_size ))
2836
- ;
2837
- else
2838
- sb .final_buf = read_sha1_file (o -> blob_oid .hash , & type ,
2839
- & sb .final_buf_size );
2840
-
2841
- if (!sb .final_buf )
2842
- die (_ ("cannot read blob %s for path %s" ),
2843
- oid_to_hex (& o -> blob_oid ),
2844
- path );
2845
- }
2846
- sb .num_read_blob ++ ;
2847
- lno = prepare_lines (& sb );
2858
+ setup_scoreboard (& sb , path , & o );
2859
+ lno = sb .num_lines ;
2848
2860
2849
2861
if (lno && !range_list .nr )
2850
2862
string_list_append (& range_list , "1" );
0 commit comments