@@ -2087,16 +2087,86 @@ static void run_external_diff(const char *pgm,
20872087 }
20882088}
20892089
2090+ static int similarity_index (struct diff_filepair * p )
2091+ {
2092+ return p -> score * 100 / MAX_SCORE ;
2093+ }
2094+
2095+ static void fill_metainfo (struct strbuf * msg ,
2096+ const char * name ,
2097+ const char * other ,
2098+ struct diff_filespec * one ,
2099+ struct diff_filespec * two ,
2100+ struct diff_options * o ,
2101+ struct diff_filepair * p )
2102+ {
2103+ strbuf_init (msg , PATH_MAX * 2 + 300 );
2104+ switch (p -> status ) {
2105+ case DIFF_STATUS_COPIED :
2106+ strbuf_addf (msg , "similarity index %d%%" , similarity_index (p ));
2107+ strbuf_addstr (msg , "\ncopy from " );
2108+ quote_c_style (name , msg , NULL , 0 );
2109+ strbuf_addstr (msg , "\ncopy to " );
2110+ quote_c_style (other , msg , NULL , 0 );
2111+ strbuf_addch (msg , '\n' );
2112+ break ;
2113+ case DIFF_STATUS_RENAMED :
2114+ strbuf_addf (msg , "similarity index %d%%" , similarity_index (p ));
2115+ strbuf_addstr (msg , "\nrename from " );
2116+ quote_c_style (name , msg , NULL , 0 );
2117+ strbuf_addstr (msg , "\nrename to " );
2118+ quote_c_style (other , msg , NULL , 0 );
2119+ strbuf_addch (msg , '\n' );
2120+ break ;
2121+ case DIFF_STATUS_MODIFIED :
2122+ if (p -> score ) {
2123+ strbuf_addf (msg , "dissimilarity index %d%%\n" ,
2124+ similarity_index (p ));
2125+ break ;
2126+ }
2127+ /* fallthru */
2128+ default :
2129+ /* nothing */
2130+ ;
2131+ }
2132+ if (one && two && hashcmp (one -> sha1 , two -> sha1 )) {
2133+ int abbrev = DIFF_OPT_TST (o , FULL_INDEX ) ? 40 : DEFAULT_ABBREV ;
2134+
2135+ if (DIFF_OPT_TST (o , BINARY )) {
2136+ mmfile_t mf ;
2137+ if ((!fill_mmfile (& mf , one ) && diff_filespec_is_binary (one )) ||
2138+ (!fill_mmfile (& mf , two ) && diff_filespec_is_binary (two )))
2139+ abbrev = 40 ;
2140+ }
2141+ strbuf_addf (msg , "index %.*s..%.*s" ,
2142+ abbrev , sha1_to_hex (one -> sha1 ),
2143+ abbrev , sha1_to_hex (two -> sha1 ));
2144+ if (one -> mode == two -> mode )
2145+ strbuf_addf (msg , " %06o" , one -> mode );
2146+ strbuf_addch (msg , '\n' );
2147+ }
2148+ if (msg -> len )
2149+ strbuf_setlen (msg , msg -> len - 1 );
2150+ }
2151+
20902152static void run_diff_cmd (const char * pgm ,
20912153 const char * name ,
20922154 const char * other ,
20932155 const char * attr_path ,
20942156 struct diff_filespec * one ,
20952157 struct diff_filespec * two ,
2096- const char * xfrm_msg ,
2158+ struct strbuf * msg ,
20972159 struct diff_options * o ,
2098- int complete_rewrite )
2160+ struct diff_filepair * p )
20992161{
2162+ const char * xfrm_msg = NULL ;
2163+ int complete_rewrite = (p -> status == DIFF_STATUS_MODIFIED ) && p -> score ;
2164+
2165+ if (msg ) {
2166+ fill_metainfo (msg , name , other , one , two , o , p );
2167+ xfrm_msg = msg -> len ? msg -> buf : NULL ;
2168+ }
2169+
21002170 if (!DIFF_OPT_TST (o , ALLOW_EXTERNAL ))
21012171 pgm = NULL ;
21022172 else {
@@ -2136,11 +2206,6 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
21362206 hashclr (one -> sha1 );
21372207}
21382208
2139- static int similarity_index (struct diff_filepair * p )
2140- {
2141- return p -> score * 100 / MAX_SCORE ;
2142- }
2143-
21442209static void strip_prefix (int prefix_length , const char * * namep , const char * * otherp )
21452210{
21462211 /* Strip the prefix but do not molest /dev/null and absolute paths */
@@ -2154,13 +2219,11 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
21542219{
21552220 const char * pgm = external_diff ();
21562221 struct strbuf msg ;
2157- char * xfrm_msg ;
21582222 struct diff_filespec * one = p -> one ;
21592223 struct diff_filespec * two = p -> two ;
21602224 const char * name ;
21612225 const char * other ;
21622226 const char * attr_path ;
2163- int complete_rewrite = 0 ;
21642227
21652228 name = p -> one -> path ;
21662229 other = (strcmp (name , p -> two -> path ) ? p -> two -> path : NULL );
@@ -2170,83 +2233,34 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
21702233
21712234 if (DIFF_PAIR_UNMERGED (p )) {
21722235 run_diff_cmd (pgm , name , NULL , attr_path ,
2173- NULL , NULL , NULL , o , 0 );
2236+ NULL , NULL , NULL , o , p );
21742237 return ;
21752238 }
21762239
21772240 diff_fill_sha1_info (one );
21782241 diff_fill_sha1_info (two );
21792242
2180- strbuf_init (& msg , PATH_MAX * 2 + 300 );
2181- switch (p -> status ) {
2182- case DIFF_STATUS_COPIED :
2183- strbuf_addf (& msg , "similarity index %d%%" , similarity_index (p ));
2184- strbuf_addstr (& msg , "\ncopy from " );
2185- quote_c_style (name , & msg , NULL , 0 );
2186- strbuf_addstr (& msg , "\ncopy to " );
2187- quote_c_style (other , & msg , NULL , 0 );
2188- strbuf_addch (& msg , '\n' );
2189- break ;
2190- case DIFF_STATUS_RENAMED :
2191- strbuf_addf (& msg , "similarity index %d%%" , similarity_index (p ));
2192- strbuf_addstr (& msg , "\nrename from " );
2193- quote_c_style (name , & msg , NULL , 0 );
2194- strbuf_addstr (& msg , "\nrename to " );
2195- quote_c_style (other , & msg , NULL , 0 );
2196- strbuf_addch (& msg , '\n' );
2197- break ;
2198- case DIFF_STATUS_MODIFIED :
2199- if (p -> score ) {
2200- strbuf_addf (& msg , "dissimilarity index %d%%\n" ,
2201- similarity_index (p ));
2202- complete_rewrite = 1 ;
2203- break ;
2204- }
2205- /* fallthru */
2206- default :
2207- /* nothing */
2208- ;
2209- }
2210-
2211- if (hashcmp (one -> sha1 , two -> sha1 )) {
2212- int abbrev = DIFF_OPT_TST (o , FULL_INDEX ) ? 40 : DEFAULT_ABBREV ;
2213-
2214- if (DIFF_OPT_TST (o , BINARY )) {
2215- mmfile_t mf ;
2216- if ((!fill_mmfile (& mf , one ) && diff_filespec_is_binary (one )) ||
2217- (!fill_mmfile (& mf , two ) && diff_filespec_is_binary (two )))
2218- abbrev = 40 ;
2219- }
2220- strbuf_addf (& msg , "index %.*s..%.*s" ,
2221- abbrev , sha1_to_hex (one -> sha1 ),
2222- abbrev , sha1_to_hex (two -> sha1 ));
2223- if (one -> mode == two -> mode )
2224- strbuf_addf (& msg , " %06o" , one -> mode );
2225- strbuf_addch (& msg , '\n' );
2226- }
2227-
2228- if (msg .len )
2229- strbuf_setlen (& msg , msg .len - 1 );
2230- xfrm_msg = msg .len ? msg .buf : NULL ;
2231-
22322243 if (!pgm &&
22332244 DIFF_FILE_VALID (one ) && DIFF_FILE_VALID (two ) &&
22342245 (S_IFMT & one -> mode ) != (S_IFMT & two -> mode )) {
2235- /* a filepair that changes between file and symlink
2246+ /*
2247+ * a filepair that changes between file and symlink
22362248 * needs to be split into deletion and creation.
22372249 */
22382250 struct diff_filespec * null = alloc_filespec (two -> path );
22392251 run_diff_cmd (NULL , name , other , attr_path ,
2240- one , null , xfrm_msg , o , 0 );
2252+ one , null , & msg , o , p );
22412253 free (null );
2254+ strbuf_release (& msg );
2255+
22422256 null = alloc_filespec (one -> path );
22432257 run_diff_cmd (NULL , name , other , attr_path ,
2244- null , two , xfrm_msg , o , 0 );
2258+ null , two , & msg , o , p );
22452259 free (null );
22462260 }
22472261 else
22482262 run_diff_cmd (pgm , name , other , attr_path ,
2249- one , two , xfrm_msg , o , complete_rewrite );
2263+ one , two , & msg , o , p );
22502264
22512265 strbuf_release (& msg );
22522266}
0 commit comments