@@ -2044,17 +2044,53 @@ static int git_blame_config(const char *var, const char *value, void *cb)
20442044 return git_default_config (var , value , cb );
20452045}
20462046
2047- static void verify_working_tree_path (unsigned char * head_sha1 , const char * path )
2047+ static void verify_working_tree_path (struct commit * work_tree , const char * path )
20482048{
2049- unsigned char blob_sha1 [20 ];
2050- unsigned mode ;
2049+ struct commit_list * parents ;
20512050
2052- if (!resolve_ref_unsafe ("HEAD" , head_sha1 , 1 , NULL ))
2053- die ("no such ref: HEAD" );
2054- if (get_tree_entry (head_sha1 , path , blob_sha1 , & mode ))
2055- die ("no such path '%s' in HEAD" , path );
2056- if (sha1_object_info (blob_sha1 , NULL ) != OBJ_BLOB )
2057- die ("path '%s' in HEAD is not a blob" , path );
2051+ for (parents = work_tree -> parents ; parents ; parents = parents -> next ) {
2052+ const unsigned char * commit_sha1 = parents -> item -> object .sha1 ;
2053+ unsigned char blob_sha1 [20 ];
2054+ unsigned mode ;
2055+
2056+ if (!get_tree_entry (commit_sha1 , path , blob_sha1 , & mode ) &&
2057+ sha1_object_info (blob_sha1 , NULL ) == OBJ_BLOB )
2058+ return ;
2059+ }
2060+ die ("no such path '%s' in HEAD" , path );
2061+ }
2062+
2063+ static struct commit_list * * append_parent (struct commit_list * * tail , const unsigned char * sha1 )
2064+ {
2065+ struct commit * parent ;
2066+
2067+ parent = lookup_commit_reference (sha1 );
2068+ if (!parent )
2069+ die ("no such commit %s" , sha1_to_hex (sha1 ));
2070+ return & commit_list_insert (parent , tail )-> next ;
2071+ }
2072+
2073+ static void append_merge_parents (struct commit_list * * tail )
2074+ {
2075+ int merge_head ;
2076+ const char * merge_head_file = git_path ("MERGE_HEAD" );
2077+ struct strbuf line = STRBUF_INIT ;
2078+
2079+ merge_head = open (merge_head_file , O_RDONLY );
2080+ if (merge_head < 0 ) {
2081+ if (errno == ENOENT )
2082+ return ;
2083+ die ("cannot open '%s' for reading" , merge_head_file );
2084+ }
2085+
2086+ while (!strbuf_getwholeline_fd (& line , merge_head , '\n' )) {
2087+ unsigned char sha1 [20 ];
2088+ if (line .len < 40 || get_sha1_hex (line .buf , sha1 ))
2089+ die ("unknown line in '%s': %s" , merge_head_file , line .buf );
2090+ tail = append_parent (tail , sha1 );
2091+ }
2092+ close (merge_head );
2093+ strbuf_release (& line );
20582094}
20592095
20602096/*
@@ -2067,26 +2103,46 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
20672103{
20682104 struct commit * commit ;
20692105 struct origin * origin ;
2106+ struct commit_list * * parent_tail , * parent ;
20702107 unsigned char head_sha1 [20 ];
20712108 struct strbuf buf = STRBUF_INIT ;
20722109 const char * ident ;
20732110 time_t now ;
20742111 int size , len ;
20752112 struct cache_entry * ce ;
20762113 unsigned mode ;
2077-
2078- verify_working_tree_path (head_sha1 , path );
2114+ struct strbuf msg = STRBUF_INIT ;
20792115
20802116 time (& now );
20812117 commit = xcalloc (1 , sizeof (* commit ));
2082- commit -> parents = xcalloc (1 , sizeof (* commit -> parents ));
2083- commit -> parents -> item = lookup_commit_reference (head_sha1 );
20842118 commit -> object .parsed = 1 ;
20852119 commit -> date = now ;
20862120 commit -> object .type = OBJ_COMMIT ;
2121+ parent_tail = & commit -> parents ;
2122+
2123+ if (!resolve_ref_unsafe ("HEAD" , head_sha1 , 1 , NULL ))
2124+ die ("no such ref: HEAD" );
2125+
2126+ parent_tail = append_parent (parent_tail , head_sha1 );
2127+ append_merge_parents (parent_tail );
2128+ verify_working_tree_path (commit , path );
20872129
20882130 origin = make_origin (commit , path );
20892131
2132+ ident = fmt_ident ("Not Committed Yet" , "not.committed.yet" , NULL , 0 );
2133+ strbuf_addstr (& msg , "tree 0000000000000000000000000000000000000000\n" );
2134+ for (parent = commit -> parents ; parent ; parent = parent -> next )
2135+ strbuf_addf (& msg , "parent %s\n" ,
2136+ sha1_to_hex (parent -> item -> object .sha1 ));
2137+ strbuf_addf (& msg ,
2138+ "author %s\n"
2139+ "committer %s\n\n"
2140+ "Version of %s from %s\n" ,
2141+ ident , ident , path ,
2142+ (!contents_from ? path :
2143+ (!strcmp (contents_from , "-" ) ? "standard input" : contents_from )));
2144+ commit -> buffer = strbuf_detach (& msg , NULL );
2145+
20902146 if (!contents_from || strcmp ("-" , contents_from )) {
20912147 struct stat st ;
20922148 const char * read_from ;
@@ -2123,7 +2179,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
21232179 }
21242180 else {
21252181 /* Reading from stdin */
2126- contents_from = "standard input" ;
21272182 mode = 0 ;
21282183 if (strbuf_read (& buf , 0 , 0 ) < 0 )
21292184 die_errno ("failed to read from stdin" );
@@ -2167,16 +2222,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
21672222 */
21682223 cache_tree_invalidate_path (active_cache_tree , path );
21692224
2170- commit -> buffer = xmalloc (400 );
2171- ident = fmt_ident ("Not Committed Yet" , "not.committed.yet" , NULL , 0 );
2172- snprintf (commit -> buffer , 400 ,
2173- "tree 0000000000000000000000000000000000000000\n"
2174- "parent %s\n"
2175- "author %s\n"
2176- "committer %s\n\n"
2177- "Version of %s from %s\n" ,
2178- sha1_to_hex (head_sha1 ),
2179- ident , ident , path , contents_from ? contents_from : path );
21802225 return commit ;
21812226}
21822227
0 commit comments