@@ -2069,6 +2069,55 @@ static int git_blame_config(const char *var, const char *value, void *cb)
20692069 return git_default_config (var , value , cb );
20702070}
20712071
2072+ static void verify_working_tree_path (struct commit * work_tree , const char * path )
2073+ {
2074+ struct commit_list * parents ;
2075+
2076+ for (parents = work_tree -> parents ; parents ; parents = parents -> next ) {
2077+ const unsigned char * commit_sha1 = parents -> item -> object .sha1 ;
2078+ unsigned char blob_sha1 [20 ];
2079+ unsigned mode ;
2080+
2081+ if (!get_tree_entry (commit_sha1 , path , blob_sha1 , & mode ) &&
2082+ sha1_object_info (blob_sha1 , NULL ) == OBJ_BLOB )
2083+ return ;
2084+ }
2085+ die ("no such path '%s' in HEAD" , path );
2086+ }
2087+
2088+ static struct commit_list * * append_parent (struct commit_list * * tail , const unsigned char * sha1 )
2089+ {
2090+ struct commit * parent ;
2091+
2092+ parent = lookup_commit_reference (sha1 );
2093+ if (!parent )
2094+ die ("no such commit %s" , sha1_to_hex (sha1 ));
2095+ return & commit_list_insert (parent , tail )-> next ;
2096+ }
2097+
2098+ static void append_merge_parents (struct commit_list * * tail )
2099+ {
2100+ int merge_head ;
2101+ const char * merge_head_file = git_path ("MERGE_HEAD" );
2102+ struct strbuf line = STRBUF_INIT ;
2103+
2104+ merge_head = open (merge_head_file , O_RDONLY );
2105+ if (merge_head < 0 ) {
2106+ if (errno == ENOENT )
2107+ return ;
2108+ die ("cannot open '%s' for reading" , merge_head_file );
2109+ }
2110+
2111+ while (!strbuf_getwholeline_fd (& line , merge_head , '\n' )) {
2112+ unsigned char sha1 [20 ];
2113+ if (line .len < 40 || get_sha1_hex (line .buf , sha1 ))
2114+ die ("unknown line in '%s': %s" , merge_head_file , line .buf );
2115+ tail = append_parent (tail , sha1 );
2116+ }
2117+ close (merge_head );
2118+ strbuf_release (& line );
2119+ }
2120+
20722121/*
20732122 * Prepare a dummy commit that represents the work tree (or staged) item.
20742123 * Note that annotating work tree item never works in the reverse.
@@ -2079,27 +2128,46 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
20792128{
20802129 struct commit * commit ;
20812130 struct origin * origin ;
2131+ struct commit_list * * parent_tail , * parent ;
20822132 unsigned char head_sha1 [20 ];
20832133 struct strbuf buf = STRBUF_INIT ;
20842134 const char * ident ;
20852135 time_t now ;
20862136 int size , len ;
20872137 struct cache_entry * ce ;
20882138 unsigned mode ;
2089-
2090- if (get_sha1 ("HEAD" , head_sha1 ))
2091- die ("No such ref: HEAD" );
2139+ struct strbuf msg = STRBUF_INIT ;
20922140
20932141 time (& now );
20942142 commit = xcalloc (1 , sizeof (* commit ));
2095- commit -> parents = xcalloc (1 , sizeof (* commit -> parents ));
2096- commit -> parents -> item = lookup_commit_reference (head_sha1 );
20972143 commit -> object .parsed = 1 ;
20982144 commit -> date = now ;
20992145 commit -> object .type = OBJ_COMMIT ;
2146+ parent_tail = & commit -> parents ;
2147+
2148+ if (!resolve_ref_unsafe ("HEAD" , head_sha1 , 1 , NULL ))
2149+ die ("no such ref: HEAD" );
2150+
2151+ parent_tail = append_parent (parent_tail , head_sha1 );
2152+ append_merge_parents (parent_tail );
2153+ verify_working_tree_path (commit , path );
21002154
21012155 origin = make_origin (commit , path );
21022156
2157+ ident = fmt_ident ("Not Committed Yet" , "not.committed.yet" , NULL , 0 );
2158+ strbuf_addstr (& msg , "tree 0000000000000000000000000000000000000000\n" );
2159+ for (parent = commit -> parents ; parent ; parent = parent -> next )
2160+ strbuf_addf (& msg , "parent %s\n" ,
2161+ sha1_to_hex (parent -> item -> object .sha1 ));
2162+ strbuf_addf (& msg ,
2163+ "author %s\n"
2164+ "committer %s\n\n"
2165+ "Version of %s from %s\n" ,
2166+ ident , ident , path ,
2167+ (!contents_from ? path :
2168+ (!strcmp (contents_from , "-" ) ? "standard input" : contents_from )));
2169+ commit -> buffer = strbuf_detach (& msg , NULL );
2170+
21032171 if (!contents_from || strcmp ("-" , contents_from )) {
21042172 struct stat st ;
21052173 const char * read_from ;
@@ -2136,7 +2204,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
21362204 }
21372205 else {
21382206 /* Reading from stdin */
2139- contents_from = "standard input" ;
21402207 mode = 0 ;
21412208 if (strbuf_read (& buf , 0 , 0 ) < 0 )
21422209 die_errno ("failed to read from stdin" );
@@ -2181,16 +2248,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
21812248 */
21822249 cache_tree_invalidate_path (active_cache_tree , path );
21832250
2184- commit -> buffer = xmalloc (400 );
2185- ident = fmt_ident ("Not Committed Yet" , "not.committed.yet" , NULL , 0 );
2186- snprintf (commit -> buffer , 400 ,
2187- "tree 0000000000000000000000000000000000000000\n"
2188- "parent %s\n"
2189- "author %s\n"
2190- "committer %s\n\n"
2191- "Version of %s from %s\n" ,
2192- sha1_to_hex (head_sha1 ),
2193- ident , ident , path , contents_from ? contents_from : path );
21942251 return commit ;
21952252}
21962253
0 commit comments