path: root/diffcore.h
diff options
authorJunio C Hamano <>2005-06-03 08:40:28 (GMT)
committerLinus Torvalds <>2005-06-03 18:23:03 (GMT)
commiteeaa4603147974b988d7b958571628d6ecd697f3 (patch)
tree5a60f9dbaeae8bddd3dda7130b5f5af471c0991a /diffcore.h
parent0e3994fa97e9876b571531444b97ae6e63fd744d (diff)
[PATCH] diff: Update -B heuristics.
As Linus pointed out on the mailing list discussion, -B should break a files that has many inserts even if it still keeps enough of the original contents, so that the broken pieces can later be matched with other files by -M or -C. However, if such a broken pair does not get picked up by -M or -C, we would want to apply different criteria; namely, regardless of the amount of new material in the result, the determination of "rewrite" should be done by looking at the amount of original material still left in the result. If you still have the original 97 lines from a 100-line document, it does not matter if you add your own 13 lines to make a 110-line document, or if you add 903 lines to make a 1000-line document. It is not a rewrite but an in-place edit. On the other hand, if you did lose 97 lines from the original, it does not matter if you added 27 lines to make a 30-line document or if you added 997 lines to make a 1000-line document. You did a complete rewrite in either case. This patch introduces a post-processing phase that runs after diffcore-rename matches up broken pairs diffcore-break creates. The purpose of this post-processing is to pick up these broken pieces and merge them back into in-place modifications. For this, the score parameter -B option takes is changed into a pair of numbers, and it takes "-B99/80" format when fully spelled out. The first number is the minimum amount of "edit" (same definition as what diffcore-rename uses, which is "sum of deletion and insertion") that a modification needs to have to be broken, and the second number is the minimum amount of "delete" a surviving broken pair must have to avoid being merged back together. It can be abbreviated to "-B" to use default for both, "-B9" or "-B9/" to use 90% for "edit" but default (80%) for merge avoidance, or "-B/75" to use default (99%) "edit" and 75% for merge avoidance. Signed-off-by: Junio C Hamano <> Signed-off-by: Linus Torvalds <>
Diffstat (limited to 'diffcore.h')
1 files changed, 11 insertions, 0 deletions
diff --git a/diffcore.h b/diffcore.h
index 2e613eb..194d40c 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -8,9 +8,19 @@
* (e.g. diffcore-rename, diffcore-pickaxe). Never include this header
* in anything else.
+/* We internally use unsigned short as the score value,
+ * and rely on an int capable to hold 32-bits. -B can take
+ * -Bmerge_score/break_score format and the two scores are
+ * passed around in one int (high 16-bit for merge and low 16-bit
+ * for break).
+ */
#define MAX_SCORE 60000
#define DEFAULT_RENAME_SCORE 30000 /* rename/copy similarity minimum (50%) */
#define DEFAULT_BREAK_SCORE 59400 /* minimum for break to happen (99%)*/
+#define DEFAULT_MERGE_SCORE 48000 /* maximum for break-merge to happen (80%)*/
+#define MINIMUM_BREAK_SIZE 400 /* do not break a file smaller than this */
struct diff_filespec {
unsigned char sha1[20];
@@ -76,6 +86,7 @@ extern void diff_q(struct diff_queue_struct *, struct diff_filepair *);
extern void diffcore_pathspec(const char **pathspec);
extern void diffcore_break(int);
extern void diffcore_rename(int rename_copy, int);
+extern void diffcore_merge_broken(void);
extern void diffcore_pickaxe(const char *needle, int opts);
extern void diffcore_order(const char *orderfile);