@@ -45,8 +45,8 @@ static int should_break(struct diff_filespec *src,
45
45
* The value we return is 1 if we want the pair to be broken,
46
46
* or 0 if we do not.
47
47
*/
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 ;
50
50
51
51
* merge_score_p = 0 ; /* assume no deletion --- "do not break"
52
52
* is the default.
@@ -72,33 +72,40 @@ static int should_break(struct diff_filespec *src,
72
72
& src_copied , & literal_added ))
73
73
return 0 ;
74
74
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
+
75
86
/* Compute merge-score, which is "how much is removed
76
87
* from the source material". The clean-up stage will
77
88
* merge the surviving pair together if the score is
78
89
* less than the minimum, after rename/copy runs.
79
90
*/
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
+
87
93
/* Extent of damage, which counts both inserts and
88
94
* deletes.
89
95
*/
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.
97
102
*/
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 ;
100
107
101
- return to_break ;
108
+ return 1 ;
102
109
}
103
110
104
111
void diffcore_break (int break_score )
0 commit comments