@@ -1999,16 +1999,86 @@ static void run_external_diff(const char *pgm,
19991999 }
20002000}
20012001
2002+ static int similarity_index (struct diff_filepair * p )
2003+ {
2004+ return p -> score * 100 / MAX_SCORE ;
2005+ }
2006+
2007+ static void fill_metainfo (struct strbuf * msg ,
2008+ const char * name ,
2009+ const char * other ,
2010+ struct diff_filespec * one ,
2011+ struct diff_filespec * two ,
2012+ struct diff_options * o ,
2013+ struct diff_filepair * p )
2014+ {
2015+ strbuf_init (msg , PATH_MAX * 2 + 300 );
2016+ switch (p -> status ) {
2017+ case DIFF_STATUS_COPIED :
2018+ strbuf_addf (msg , "similarity index %d%%" , similarity_index (p ));
2019+ strbuf_addstr (msg , "\ncopy from " );
2020+ quote_c_style (name , msg , NULL , 0 );
2021+ strbuf_addstr (msg , "\ncopy to " );
2022+ quote_c_style (other , msg , NULL , 0 );
2023+ strbuf_addch (msg , '\n' );
2024+ break ;
2025+ case DIFF_STATUS_RENAMED :
2026+ strbuf_addf (msg , "similarity index %d%%" , similarity_index (p ));
2027+ strbuf_addstr (msg , "\nrename from " );
2028+ quote_c_style (name , msg , NULL , 0 );
2029+ strbuf_addstr (msg , "\nrename to " );
2030+ quote_c_style (other , msg , NULL , 0 );
2031+ strbuf_addch (msg , '\n' );
2032+ break ;
2033+ case DIFF_STATUS_MODIFIED :
2034+ if (p -> score ) {
2035+ strbuf_addf (msg , "dissimilarity index %d%%\n" ,
2036+ similarity_index (p ));
2037+ break ;
2038+ }
2039+ /* fallthru */
2040+ default :
2041+ /* nothing */
2042+ ;
2043+ }
2044+ if (one && two && hashcmp (one -> sha1 , two -> sha1 )) {
2045+ int abbrev = DIFF_OPT_TST (o , FULL_INDEX ) ? 40 : DEFAULT_ABBREV ;
2046+
2047+ if (DIFF_OPT_TST (o , BINARY )) {
2048+ mmfile_t mf ;
2049+ if ((!fill_mmfile (& mf , one ) && diff_filespec_is_binary (one )) ||
2050+ (!fill_mmfile (& mf , two ) && diff_filespec_is_binary (two )))
2051+ abbrev = 40 ;
2052+ }
2053+ strbuf_addf (msg , "index %.*s..%.*s" ,
2054+ abbrev , sha1_to_hex (one -> sha1 ),
2055+ abbrev , sha1_to_hex (two -> sha1 ));
2056+ if (one -> mode == two -> mode )
2057+ strbuf_addf (msg , " %06o" , one -> mode );
2058+ strbuf_addch (msg , '\n' );
2059+ }
2060+ if (msg -> len )
2061+ strbuf_setlen (msg , msg -> len - 1 );
2062+ }
2063+
20022064static void run_diff_cmd (const char * pgm ,
20032065 const char * name ,
20042066 const char * other ,
20052067 const char * attr_path ,
20062068 struct diff_filespec * one ,
20072069 struct diff_filespec * two ,
2008- const char * xfrm_msg ,
2070+ struct strbuf * msg ,
20092071 struct diff_options * o ,
2010- int complete_rewrite )
2072+ struct diff_filepair * p )
20112073{
2074+ const char * xfrm_msg = NULL ;
2075+ int complete_rewrite = (p -> status == DIFF_STATUS_MODIFIED ) && p -> score ;
2076+
2077+ if (msg ) {
2078+ fill_metainfo (msg , name , other , one , two , o , p );
2079+ xfrm_msg = msg -> len ? msg -> buf : NULL ;
2080+ }
2081+
20122082 if (!DIFF_OPT_TST (o , ALLOW_EXTERNAL ))
20132083 pgm = NULL ;
20142084 else {
@@ -2048,11 +2118,6 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
20482118 hashclr (one -> sha1 );
20492119}
20502120
2051- static int similarity_index (struct diff_filepair * p )
2052- {
2053- return p -> score * 100 / MAX_SCORE ;
2054- }
2055-
20562121static void strip_prefix (int prefix_length , const char * * namep , const char * * otherp )
20572122{
20582123 /* Strip the prefix but do not molest /dev/null and absolute paths */
@@ -2066,13 +2131,11 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
20662131{
20672132 const char * pgm = external_diff ();
20682133 struct strbuf msg ;
2069- char * xfrm_msg ;
20702134 struct diff_filespec * one = p -> one ;
20712135 struct diff_filespec * two = p -> two ;
20722136 const char * name ;
20732137 const char * other ;
20742138 const char * attr_path ;
2075- int complete_rewrite = 0 ;
20762139
20772140 name = p -> one -> path ;
20782141 other = (strcmp (name , p -> two -> path ) ? p -> two -> path : NULL );
@@ -2082,83 +2145,34 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
20822145
20832146 if (DIFF_PAIR_UNMERGED (p )) {
20842147 run_diff_cmd (pgm , name , NULL , attr_path ,
2085- NULL , NULL , NULL , o , 0 );
2148+ NULL , NULL , NULL , o , p );
20862149 return ;
20872150 }
20882151
20892152 diff_fill_sha1_info (one );
20902153 diff_fill_sha1_info (two );
20912154
2092- strbuf_init (& msg , PATH_MAX * 2 + 300 );
2093- switch (p -> status ) {
2094- case DIFF_STATUS_COPIED :
2095- strbuf_addf (& msg , "similarity index %d%%" , similarity_index (p ));
2096- strbuf_addstr (& msg , "\ncopy from " );
2097- quote_c_style (name , & msg , NULL , 0 );
2098- strbuf_addstr (& msg , "\ncopy to " );
2099- quote_c_style (other , & msg , NULL , 0 );
2100- strbuf_addch (& msg , '\n' );
2101- break ;
2102- case DIFF_STATUS_RENAMED :
2103- strbuf_addf (& msg , "similarity index %d%%" , similarity_index (p ));
2104- strbuf_addstr (& msg , "\nrename from " );
2105- quote_c_style (name , & msg , NULL , 0 );
2106- strbuf_addstr (& msg , "\nrename to " );
2107- quote_c_style (other , & msg , NULL , 0 );
2108- strbuf_addch (& msg , '\n' );
2109- break ;
2110- case DIFF_STATUS_MODIFIED :
2111- if (p -> score ) {
2112- strbuf_addf (& msg , "dissimilarity index %d%%\n" ,
2113- similarity_index (p ));
2114- complete_rewrite = 1 ;
2115- break ;
2116- }
2117- /* fallthru */
2118- default :
2119- /* nothing */
2120- ;
2121- }
2122-
2123- if (hashcmp (one -> sha1 , two -> sha1 )) {
2124- int abbrev = DIFF_OPT_TST (o , FULL_INDEX ) ? 40 : DEFAULT_ABBREV ;
2125-
2126- if (DIFF_OPT_TST (o , BINARY )) {
2127- mmfile_t mf ;
2128- if ((!fill_mmfile (& mf , one ) && diff_filespec_is_binary (one )) ||
2129- (!fill_mmfile (& mf , two ) && diff_filespec_is_binary (two )))
2130- abbrev = 40 ;
2131- }
2132- strbuf_addf (& msg , "index %.*s..%.*s" ,
2133- abbrev , sha1_to_hex (one -> sha1 ),
2134- abbrev , sha1_to_hex (two -> sha1 ));
2135- if (one -> mode == two -> mode )
2136- strbuf_addf (& msg , " %06o" , one -> mode );
2137- strbuf_addch (& msg , '\n' );
2138- }
2139-
2140- if (msg .len )
2141- strbuf_setlen (& msg , msg .len - 1 );
2142- xfrm_msg = msg .len ? msg .buf : NULL ;
2143-
21442155 if (!pgm &&
21452156 DIFF_FILE_VALID (one ) && DIFF_FILE_VALID (two ) &&
21462157 (S_IFMT & one -> mode ) != (S_IFMT & two -> mode )) {
2147- /* a filepair that changes between file and symlink
2158+ /*
2159+ * a filepair that changes between file and symlink
21482160 * needs to be split into deletion and creation.
21492161 */
21502162 struct diff_filespec * null = alloc_filespec (two -> path );
21512163 run_diff_cmd (NULL , name , other , attr_path ,
2152- one , null , xfrm_msg , o , 0 );
2164+ one , null , & msg , o , p );
21532165 free (null );
2166+ strbuf_release (& msg );
2167+
21542168 null = alloc_filespec (one -> path );
21552169 run_diff_cmd (NULL , name , other , attr_path ,
2156- null , two , xfrm_msg , o , 0 );
2170+ null , two , & msg , o , p );
21572171 free (null );
21582172 }
21592173 else
21602174 run_diff_cmd (pgm , name , other , attr_path ,
2161- one , two , xfrm_msg , o , complete_rewrite );
2175+ one , two , & msg , o , p );
21622176
21632177 strbuf_release (& msg );
21642178}
0 commit comments