@@ -177,12 +177,12 @@ static void set_commit_buffer_from_strbuf(struct repository *r,
177
177
static struct commit * fake_working_tree_commit (struct repository * r ,
178
178
struct diff_options * opt ,
179
179
const char * path ,
180
- const char * contents_from )
180
+ const char * contents_from ,
181
+ struct object_id * oid )
181
182
{
182
183
struct commit * commit ;
183
184
struct blame_origin * origin ;
184
185
struct commit_list * * parent_tail , * parent ;
185
- struct object_id head_oid ;
186
186
struct strbuf buf = STRBUF_INIT ;
187
187
const char * ident ;
188
188
time_t now ;
@@ -198,10 +198,7 @@ static struct commit *fake_working_tree_commit(struct repository *r,
198
198
commit -> date = now ;
199
199
parent_tail = & commit -> parents ;
200
200
201
- if (!resolve_ref_unsafe ("HEAD" , RESOLVE_REF_READING , & head_oid , NULL ))
202
- die ("no such ref: HEAD" );
203
-
204
- parent_tail = append_parent (r , parent_tail , & head_oid );
201
+ parent_tail = append_parent (r , parent_tail , oid );
205
202
append_merge_parents (r , parent_tail );
206
203
verify_working_tree_path (r , commit , path );
207
204
@@ -2772,22 +2769,37 @@ void setup_scoreboard(struct blame_scoreboard *sb,
2772
2769
sb -> commits .compare = compare_commits_by_reverse_commit_date ;
2773
2770
}
2774
2771
2775
- if (sb -> final && sb -> contents_from )
2776
- die (_ ("cannot use --contents with final commit object name" ));
2777
-
2778
2772
if (sb -> reverse && sb -> revs -> first_parent_only )
2779
2773
sb -> revs -> children .name = NULL ;
2780
2774
2781
- if (!sb -> final ) {
2775
+ if (sb -> contents_from || !sb -> final ) {
2776
+ struct object_id head_oid , * parent_oid ;
2777
+
2782
2778
/*
2783
- * "--not A B -- path" without anything positive;
2784
- * do not default to HEAD, but use the working tree
2785
- * or "--contents".
2779
+ * Build a fake commit at the top of the history, when
2780
+ * (1) "git blame [^A] --path", i.e. with no positive end
2781
+ * of the history range, in which case we build such
2782
+ * a fake commit on top of the HEAD to blame in-tree
2783
+ * modifications.
2784
+ * (2) "git blame --contents=file [A] -- path", with or
2785
+ * without positive end of the history range but with
2786
+ * --contents, in which case we pretend that there is
2787
+ * a fake commit on top of the positive end (defaulting to
2788
+ * HEAD) that has the given contents in the path.
2786
2789
*/
2790
+ if (sb -> final ) {
2791
+ parent_oid = & sb -> final -> object .oid ;
2792
+ } else {
2793
+ if (!resolve_ref_unsafe ("HEAD" , RESOLVE_REF_READING , & head_oid , NULL ))
2794
+ die ("no such ref: HEAD" );
2795
+ parent_oid = & head_oid ;
2796
+ }
2797
+
2787
2798
setup_work_tree ();
2788
2799
sb -> final = fake_working_tree_commit (sb -> repo ,
2789
2800
& sb -> revs -> diffopt ,
2790
- sb -> path , sb -> contents_from );
2801
+ sb -> path , sb -> contents_from ,
2802
+ parent_oid );
2791
2803
add_pending_object (sb -> revs , & (sb -> final -> object ), ":" );
2792
2804
}
2793
2805
0 commit comments