@@ -45,8 +45,8 @@ static int should_break(struct diff_filespec *src,
4545 * The value we return is 1 if we want the pair to be broken,
4646 * or 0 if we do not.
4747 */
48- unsigned long delta_size , base_size , src_copied , literal_added ;
49- int to_break = 0 ;
48+ unsigned long delta_size , base_size , src_copied , literal_added ,
49+ src_removed ;
5050
5151 * merge_score_p = 0 ; /* assume no deletion --- "do not break"
5252 * is the default.
@@ -72,33 +72,40 @@ static int should_break(struct diff_filespec *src,
7272 & src_copied , & literal_added ))
7373 return 0 ;
7474
75+ /* sanity */
76+ if (src -> size < src_copied )
77+ src_copied = src -> size ;
78+ if (dst -> size < literal_added + src_copied ) {
79+ if (src_copied < dst -> size )
80+ literal_added = dst -> size - src_copied ;
81+ else
82+ literal_added = 0 ;
83+ }
84+ src_removed = src -> size - src_copied ;
85+
7586 /* Compute merge-score, which is "how much is removed
7687 * from the source material". The clean-up stage will
7788 * merge the surviving pair together if the score is
7889 * less than the minimum, after rename/copy runs.
7990 */
80- if (src -> size <= src_copied )
81- ; /* all copied, nothing removed */
82- else {
83- delta_size = src -> size - src_copied ;
84- * merge_score_p = delta_size * MAX_SCORE / src -> size ;
85- }
86-
91+ * merge_score_p = src_removed * MAX_SCORE / src -> size ;
92+
8793 /* Extent of damage, which counts both inserts and
8894 * deletes.
8995 */
90- if (src -> size + literal_added <= src_copied )
91- delta_size = 0 ; /* avoid wrapping around */
92- else
93- delta_size = (src -> size - src_copied ) + literal_added ;
94-
95- /* We break if the edit exceeds the minimum.
96- * i.e. (break_score / MAX_SCORE < delta_size / base_size)
96+ delta_size = src_removed + literal_added ;
97+ if (delta_size * MAX_SCORE / base_size < break_score )
98+ return 0 ;
99+
100+ /* If you removed a lot without adding new material, that is
101+ * not really a rewrite.
97102 */
98- if (break_score * base_size < delta_size * MAX_SCORE )
99- to_break = 1 ;
103+ if ((src -> size * break_score < src_removed * MAX_SCORE ) &&
104+ (literal_added * 20 < src_removed ) &&
105+ (literal_added * 20 < src_copied ))
106+ return 0 ;
100107
101- return to_break ;
108+ return 1 ;
102109}
103110
104111void diffcore_break (int break_score )
0 commit comments