2005-05-21 11:39:09 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2005 Junio C Hamano
|
|
|
|
*/
|
2007-04-29 08:38:52 +02:00
|
|
|
#ifndef DIFFCORE_H
|
|
|
|
#define DIFFCORE_H
|
2005-05-21 11:39:09 +02:00
|
|
|
|
|
|
|
/* This header file is internal between diff.c and its diff transformers
|
|
|
|
* (e.g. diffcore-rename, diffcore-pickaxe). Never include this header
|
|
|
|
* in anything else.
|
|
|
|
*/
|
[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 <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-03 10:40:28 +02:00
|
|
|
|
|
|
|
/* 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).
|
|
|
|
*/
|
2006-01-16 06:08:42 +01:00
|
|
|
#define MAX_SCORE 60000.0
|
[PATCH] Add -B flag to diff-* brothers.
A new diffcore transformation, diffcore-break.c, is introduced.
When the -B flag is given, a patch that represents a complete
rewrite is broken into a deletion followed by a creation. This
makes it easier to review such a complete rewrite patch.
The -B flag takes the same syntax as the -M and -C flags to
specify the minimum amount of non-source material the resulting
file needs to have to be considered a complete rewrite, and
defaults to 99% if not specified.
As the new test t4008-diff-break-rewrite.sh demonstrates, if a
file is a complete rewrite, it is broken into a delete/create
pair, which can further be subjected to the usual rename
detection if -M or -C is used. For example, if file0 gets
completely rewritten to make it as if it were rather based on
file1 which itself disappeared, the following happens:
The original change looks like this:
file0 --> file0' (quite different from file0)
file1 --> /dev/null
After diffcore-break runs, it would become this:
file0 --> /dev/null
/dev/null --> file0'
file1 --> /dev/null
Then diffcore-rename matches them up:
file1 --> file0'
The internal score values are finer grained now. Earlier
maximum of 10000 has been raised to 60000; there is no user
visible changes but there is no reason to waste available bits.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-30 09:08:37 +02:00
|
|
|
#define DEFAULT_RENAME_SCORE 30000 /* rename/copy similarity minimum (50%) */
|
2006-03-04 10:03:53 +01:00
|
|
|
#define DEFAULT_BREAK_SCORE 30000 /* minimum for break to happen (50%) */
|
2010-08-05 18:14:25 +02:00
|
|
|
#define DEFAULT_MERGE_SCORE 36000 /* maximum for break-merge to happen (60%) */
|
[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 <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-03 10:40:28 +02:00
|
|
|
|
|
|
|
#define MINIMUM_BREAK_SIZE 400 /* do not break a file smaller than this */
|
2005-05-21 11:39:09 +02:00
|
|
|
|
diff: introduce diff.<driver>.binary
The "diff" gitattribute is somewhat overloaded right now. It
can say one of three things:
1. this file is definitely binary, or definitely not
(i.e., diff or !diff)
2. this file should use an external diff engine (i.e.,
diff=foo, diff.foo.command = custom-script)
3. this file should use particular funcname patterns
(i.e., diff=foo, diff.foo.(x?)funcname = some-regex)
Most of the time, there is no conflict between these uses,
since using one implies that the other is irrelevant (e.g.,
an external diff engine will decide for itself whether the
file is binary).
However, there is at least one conflicting situation: there
is no way to say "use the regular rules to determine whether
this file is binary, but if we do diff it textually, use
this funcname pattern." That is, currently setting diff=foo
indicates that the file is definitely text.
This patch introduces a "binary" config option for a diff
driver, so that one can explicitly set diff.foo.binary. We
default this value to "don't know". That is, setting a diff
attribute to "foo" and using "diff.foo.funcname" will have
no effect on the binaryness of a file. To get the current
behavior, one can set diff.foo.binary to true.
This patch also has one additional advantage: it cleans up
the interface to the userdiff code a bit. Before, calling
code had to know more about whether attributes were false,
true, or unset to determine binaryness. Now that binaryness
is a property of a driver, we can represent these situations
just by passing back a driver struct.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2008-10-05 23:43:36 +02:00
|
|
|
struct userdiff_driver;
|
|
|
|
|
2005-05-21 11:39:09 +02:00
|
|
|
struct diff_filespec {
|
|
|
|
unsigned char sha1[20];
|
|
|
|
char *path;
|
|
|
|
void *data;
|
2006-03-12 12:22:10 +01:00
|
|
|
void *cnt_data;
|
2005-05-21 11:39:09 +02:00
|
|
|
unsigned long size;
|
2007-10-25 20:19:10 +02:00
|
|
|
int count; /* Reference count */
|
2007-10-25 20:20:56 +02:00
|
|
|
int rename_used; /* Count of rename users */
|
2005-05-21 11:39:09 +02:00
|
|
|
unsigned short mode; /* file mode */
|
|
|
|
unsigned sha1_valid : 1; /* if true, use sha1 and trust mode;
|
|
|
|
* if false, use the name and read from
|
|
|
|
* the filesystem.
|
|
|
|
*/
|
2005-06-13 02:23:15 +02:00
|
|
|
#define DIFF_FILE_VALID(spec) (((spec)->mode) != 0)
|
2005-05-21 11:39:09 +02:00
|
|
|
unsigned should_free : 1; /* data should be free()'ed */
|
|
|
|
unsigned should_munmap : 1; /* data should be munmap()'ed */
|
2010-03-04 22:20:33 +01:00
|
|
|
unsigned dirty_submodule : 2; /* For submodules: its work tree is dirty */
|
|
|
|
#define DIRTY_SUBMODULE_UNTRACKED 1
|
|
|
|
#define DIRTY_SUBMODULE_MODIFIED 2
|
2014-01-17 02:19:46 +01:00
|
|
|
unsigned is_stdin : 1;
|
2011-08-20 08:32:51 +02:00
|
|
|
unsigned has_more_entries : 1; /* only appear in combined diff */
|
diff: introduce diff.<driver>.binary
The "diff" gitattribute is somewhat overloaded right now. It
can say one of three things:
1. this file is definitely binary, or definitely not
(i.e., diff or !diff)
2. this file should use an external diff engine (i.e.,
diff=foo, diff.foo.command = custom-script)
3. this file should use particular funcname patterns
(i.e., diff=foo, diff.foo.(x?)funcname = some-regex)
Most of the time, there is no conflict between these uses,
since using one implies that the other is irrelevant (e.g.,
an external diff engine will decide for itself whether the
file is binary).
However, there is at least one conflicting situation: there
is no way to say "use the regular rules to determine whether
this file is binary, but if we do diff it textually, use
this funcname pattern." That is, currently setting diff=foo
indicates that the file is definitely text.
This patch introduces a "binary" config option for a diff
driver, so that one can explicitly set diff.foo.binary. We
default this value to "don't know". That is, setting a diff
attribute to "foo" and using "diff.foo.funcname" will have
no effect on the binaryness of a file. To get the current
behavior, one can set diff.foo.binary to true.
This patch also has one additional advantage: it cleans up
the interface to the userdiff code a bit. Before, calling
code had to know more about whether attributes were false,
true, or unset to determine binaryness. Now that binaryness
is a property of a driver, we can represent these situations
just by passing back a driver struct.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2008-10-05 23:43:36 +02:00
|
|
|
/* data should be considered "binary"; -1 means "don't know yet" */
|
2014-01-17 02:25:40 +01:00
|
|
|
int is_binary : 2;
|
diff_filespec: reorder is_binary field
The middle of the diff_filespec struct contains a mixture of
ints, shorts, and bit-fields, followed by a pointer. On an
x86-64 system with an LP64 or LLP64 data model (i.e., most
of them), the integers and flags end up being padded out by
41 bits to put the pointer at an 8-byte boundary.
After the pointer, we have the "int is_binary" field, which
is only 32 bits. We end up wasting another 32 bits to pad
the struct size up to a multiple of 64 bits.
We can move the is_binary field before the pointer, which
lets the compiler store it where we used to have padding.
This shrinks the top padding to only 9 bits (from the
bit-fields), and eliminates the bottom padding entirely,
dropping the struct size from 88 to 80 bytes.
On a 32-bit system, there is no benefit, but nor should
there be any harm (we only need 4-byte alignment there, so
we were already using only 9 bits of padding).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-17 02:22:56 +01:00
|
|
|
struct userdiff_driver *driver;
|
2005-05-21 11:39:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
extern struct diff_filespec *alloc_filespec(const char *);
|
2007-10-25 20:19:10 +02:00
|
|
|
extern void free_filespec(struct diff_filespec *);
|
2005-05-21 11:39:09 +02:00
|
|
|
extern void fill_filespec(struct diff_filespec *, const unsigned char *,
|
diff: do not use null sha1 as a sentinel value
The diff code represents paths using the diff_filespec
struct. This struct has a sha1 to represent the sha1 of the
content at that path, as well as a sha1_valid member which
indicates whether its sha1 field is actually useful. If
sha1_valid is not true, then the filespec represents a
working tree file (e.g., for the no-index case, or for when
the index is not up-to-date).
The diff_filespec is only used internally, though. At the
interfaces to the diff subsystem, callers feed the sha1
directly, and we create a diff_filespec from it. It's at
that point that we look at the sha1 and decide whether it is
valid or not; callers may pass the null sha1 as a sentinel
value to indicate that it is not.
We should not typically see the null sha1 coming from any
other source (e.g., in the index itself, or from a tree).
However, a corrupt tree might have a null sha1, which would
cause "diff --patch" to accidentally diff the working tree
version of a file instead of treating it as a blob.
This patch extends the edges of the diff interface to accept
a "sha1_valid" flag whenever we accept a sha1, and to use
that flag when creating a filespec. In some cases, this
means passing the flag through several layers, making the
code change larger than would be desirable.
One alternative would be to simply die() upon seeing
corrupted trees with null sha1s. However, this fix more
directly addresses the problem (while bogus sha1s in a tree
are probably a bad thing, it is really the sentinel
confusion sending us down the wrong code path that is what
makes it devastating). And it means that git is more capable
of examining and debugging these corrupted trees. For
example, you can still "diff --raw" such a tree to find out
when the bogus entry was introduced; you just cannot do a
"--patch" diff (just as you could not with any other
corrupted tree, as we do not have any content to diff).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-07-28 17:03:01 +02:00
|
|
|
int, unsigned short);
|
2005-05-21 11:39:09 +02:00
|
|
|
|
2005-05-28 00:56:38 +02:00
|
|
|
extern int diff_populate_filespec(struct diff_filespec *, int);
|
2005-09-14 23:06:50 +02:00
|
|
|
extern void diff_free_filespec_data(struct diff_filespec *);
|
2007-10-03 06:01:03 +02:00
|
|
|
extern void diff_free_filespec_blob(struct diff_filespec *);
|
2007-07-06 09:18:54 +02:00
|
|
|
extern int diff_filespec_is_binary(struct diff_filespec *);
|
2005-05-21 11:39:09 +02:00
|
|
|
|
2005-05-21 11:40:01 +02:00
|
|
|
struct diff_filepair {
|
2005-05-21 11:39:09 +02:00
|
|
|
struct diff_filespec *one;
|
|
|
|
struct diff_filespec *two;
|
2005-05-30 01:56:48 +02:00
|
|
|
unsigned short int score;
|
2008-11-02 14:37:28 +01:00
|
|
|
char status; /* M C R A D U etc. (see Documentation/diff-format.txt or DIFF_STATUS_* in diff.h) */
|
[PATCH] Add -B flag to diff-* brothers.
A new diffcore transformation, diffcore-break.c, is introduced.
When the -B flag is given, a patch that represents a complete
rewrite is broken into a deletion followed by a creation. This
makes it easier to review such a complete rewrite patch.
The -B flag takes the same syntax as the -M and -C flags to
specify the minimum amount of non-source material the resulting
file needs to have to be considered a complete rewrite, and
defaults to 99% if not specified.
As the new test t4008-diff-break-rewrite.sh demonstrates, if a
file is a complete rewrite, it is broken into a delete/create
pair, which can further be subjected to the usual rename
detection if -M or -C is used. For example, if file0 gets
completely rewritten to make it as if it were rather based on
file1 which itself disappeared, the following happens:
The original change looks like this:
file0 --> file0' (quite different from file0)
file1 --> /dev/null
After diffcore-break runs, it would become this:
file0 --> /dev/null
/dev/null --> file0'
file1 --> /dev/null
Then diffcore-rename matches them up:
file1 --> file0'
The internal score values are finer grained now. Earlier
maximum of 10000 has been raised to 60000; there is no user
visible changes but there is no reason to waste available bits.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-30 09:08:37 +02:00
|
|
|
unsigned broken_pair : 1;
|
2006-08-03 21:01:01 +02:00
|
|
|
unsigned renamed_pair : 1;
|
2007-01-05 10:25:18 +01:00
|
|
|
unsigned is_unmerged : 1;
|
2005-05-21 11:39:09 +02:00
|
|
|
};
|
2007-01-05 10:25:18 +01:00
|
|
|
#define DIFF_PAIR_UNMERGED(p) ((p)->is_unmerged)
|
2005-05-21 11:39:09 +02:00
|
|
|
|
2006-08-03 21:01:01 +02:00
|
|
|
#define DIFF_PAIR_RENAME(p) ((p)->renamed_pair)
|
2005-05-30 01:56:48 +02:00
|
|
|
|
[PATCH] Add -B flag to diff-* brothers.
A new diffcore transformation, diffcore-break.c, is introduced.
When the -B flag is given, a patch that represents a complete
rewrite is broken into a deletion followed by a creation. This
makes it easier to review such a complete rewrite patch.
The -B flag takes the same syntax as the -M and -C flags to
specify the minimum amount of non-source material the resulting
file needs to have to be considered a complete rewrite, and
defaults to 99% if not specified.
As the new test t4008-diff-break-rewrite.sh demonstrates, if a
file is a complete rewrite, it is broken into a delete/create
pair, which can further be subjected to the usual rename
detection if -M or -C is used. For example, if file0 gets
completely rewritten to make it as if it were rather based on
file1 which itself disappeared, the following happens:
The original change looks like this:
file0 --> file0' (quite different from file0)
file1 --> /dev/null
After diffcore-break runs, it would become this:
file0 --> /dev/null
/dev/null --> file0'
file1 --> /dev/null
Then diffcore-rename matches them up:
file1 --> file0'
The internal score values are finer grained now. Earlier
maximum of 10000 has been raised to 60000; there is no user
visible changes but there is no reason to waste available bits.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-30 09:08:37 +02:00
|
|
|
#define DIFF_PAIR_BROKEN(p) \
|
|
|
|
( (!DIFF_FILE_VALID((p)->one) != !DIFF_FILE_VALID((p)->two)) && \
|
|
|
|
((p)->broken_pair != 0) )
|
|
|
|
|
2005-05-26 00:07:08 +02:00
|
|
|
#define DIFF_PAIR_TYPE_CHANGED(p) \
|
|
|
|
((S_IFMT & (p)->one->mode) != (S_IFMT & (p)->two->mode))
|
|
|
|
|
2005-05-26 11:24:30 +02:00
|
|
|
#define DIFF_PAIR_MODE_CHANGED(p) ((p)->one->mode != (p)->two->mode)
|
|
|
|
|
2005-05-28 00:50:30 +02:00
|
|
|
extern void diff_free_filepair(struct diff_filepair *);
|
|
|
|
|
[PATCH] Rename/copy detection fix.
The rename/copy detection logic in earlier round was only good
enough to show patch output and discussion on the mailing list
about the diff-raw format updates revealed many problems with
it. This patch fixes all the ones known to me, without making
things I want to do later impossible, mostly related to patch
reordering.
(1) Earlier rename/copy detector determined which one is rename
and which one is copy too early, which made it impossible
to later introduce diffcore transformers to reorder
patches. This patch fixes it by moving that logic to the
very end of the processing.
(2) Earlier output routine diff_flush() was pruning all the
"no-change" entries indiscriminatingly. This was done due
to my false assumption that one of the requirements in the
diff-raw output was not to show such an entry (which
resulted in my incorrect comment about "diff-helper never
being able to be equivalent to built-in diff driver"). My
special thanks go to Linus for correcting me about this.
When we produce diff-raw output, for the downstream to be
able to tell renames from copies, sometimes it _is_
necessary to output "no-change" entries, and this patch
adds diffcore_prune() function for doing it.
(3) Earlier diff_filepair structure was trying to be not too
specific about rename/copy operations, but the purpose of
the structure was to record one or two paths, which _was_
indeed about rename/copy. This patch discards xfrm_msg
field which was trying to be generic for this wrong reason,
and introduces a couple of fields (rename_score and
rename_rank) that are explicitly specific to rename/copy
logic. One thing to note is that the information in a
single diff_filepair structure _still_ does not distinguish
renames from copies, and it is deliberately so. This is to
allow patches to be reordered in later stages.
(4) This patch also adds some tests about diff-raw format
output and makes sure that necessary "no-change" entries
appear on the output.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-23 06:26:09 +02:00
|
|
|
extern int diff_unmodified_pair(struct diff_filepair *);
|
|
|
|
|
2005-05-21 11:39:09 +02:00
|
|
|
struct diff_queue_struct {
|
2005-05-21 11:40:01 +02:00
|
|
|
struct diff_filepair **queue;
|
2005-05-21 11:39:09 +02:00
|
|
|
int alloc;
|
|
|
|
int nr;
|
|
|
|
};
|
2010-05-07 06:52:27 +02:00
|
|
|
#define DIFF_QUEUE_CLEAR(q) \
|
|
|
|
do { \
|
|
|
|
(q)->queue = NULL; \
|
|
|
|
(q)->nr = (q)->alloc = 0; \
|
2010-08-13 00:11:15 +02:00
|
|
|
} while (0)
|
2005-05-21 11:39:09 +02:00
|
|
|
|
2005-05-22 04:40:36 +02:00
|
|
|
extern struct diff_queue_struct diff_queued_diff;
|
2005-05-21 11:40:01 +02:00
|
|
|
extern struct diff_filepair *diff_queue(struct diff_queue_struct *,
|
|
|
|
struct diff_filespec *,
|
|
|
|
struct diff_filespec *);
|
2005-05-22 19:04:37 +02:00
|
|
|
extern void diff_q(struct diff_queue_struct *, struct diff_filepair *);
|
[PATCH] Rename/copy detection fix.
The rename/copy detection logic in earlier round was only good
enough to show patch output and discussion on the mailing list
about the diff-raw format updates revealed many problems with
it. This patch fixes all the ones known to me, without making
things I want to do later impossible, mostly related to patch
reordering.
(1) Earlier rename/copy detector determined which one is rename
and which one is copy too early, which made it impossible
to later introduce diffcore transformers to reorder
patches. This patch fixes it by moving that logic to the
very end of the processing.
(2) Earlier output routine diff_flush() was pruning all the
"no-change" entries indiscriminatingly. This was done due
to my false assumption that one of the requirements in the
diff-raw output was not to show such an entry (which
resulted in my incorrect comment about "diff-helper never
being able to be equivalent to built-in diff driver"). My
special thanks go to Linus for correcting me about this.
When we produce diff-raw output, for the downstream to be
able to tell renames from copies, sometimes it _is_
necessary to output "no-change" entries, and this patch
adds diffcore_prune() function for doing it.
(3) Earlier diff_filepair structure was trying to be not too
specific about rename/copy operations, but the purpose of
the structure was to record one or two paths, which _was_
indeed about rename/copy. This patch discards xfrm_msg
field which was trying to be generic for this wrong reason,
and introduces a couple of fields (rename_score and
rename_rank) that are explicitly specific to rename/copy
logic. One thing to note is that the information in a
single diff_filepair structure _still_ does not distinguish
renames from copies, and it is deliberately so. This is to
allow patches to be reordered in later stages.
(4) This patch also adds some tests about diff-raw format
output and makes sure that necessary "no-change" entries
appear on the output.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-23 06:26:09 +02:00
|
|
|
|
2005-06-03 10:36:43 +02:00
|
|
|
extern void diffcore_break(int);
|
2005-09-21 09:18:27 +02:00
|
|
|
extern void diffcore_rename(struct diff_options *);
|
[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 <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-03 10:40:28 +02:00
|
|
|
extern void diffcore_merge_broken(void);
|
2010-08-31 22:44:39 +02:00
|
|
|
extern void diffcore_pickaxe(struct diff_options *);
|
2005-06-03 10:36:43 +02:00
|
|
|
extern void diffcore_order(const char *orderfile);
|
|
|
|
|
2014-01-20 17:20:38 +01:00
|
|
|
/* low-level interface to diffcore_order */
|
|
|
|
struct obj_order {
|
|
|
|
void *obj; /* setup by caller */
|
|
|
|
|
|
|
|
/* setup/used by order_objects() */
|
|
|
|
int orig_order;
|
|
|
|
int order;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef const char *(*obj_path_fn_t)(void *obj);
|
|
|
|
|
|
|
|
void order_objects(const char *orderfile, obj_path_fn_t obj_path,
|
|
|
|
struct obj_order *objs, int nr);
|
|
|
|
|
2005-05-24 10:10:48 +02:00
|
|
|
#define DIFF_DEBUG 0
|
|
|
|
#if DIFF_DEBUG
|
|
|
|
void diff_debug_filespec(struct diff_filespec *, int, const char *);
|
|
|
|
void diff_debug_filepair(const struct diff_filepair *, int);
|
|
|
|
void diff_debug_queue(const char *, struct diff_queue_struct *);
|
|
|
|
#else
|
2010-08-13 00:11:15 +02:00
|
|
|
#define diff_debug_filespec(a,b,c) do { /* nothing */ } while (0)
|
|
|
|
#define diff_debug_filepair(a,b) do { /* nothing */ } while (0)
|
|
|
|
#define diff_debug_queue(a,b) do { /* nothing */ } while (0)
|
2005-05-24 10:10:48 +02:00
|
|
|
#endif
|
|
|
|
|
2007-06-29 07:54:37 +02:00
|
|
|
extern int diffcore_count_changes(struct diff_filespec *src,
|
|
|
|
struct diff_filespec *dst,
|
2006-03-12 12:22:10 +01:00
|
|
|
void **src_count_p,
|
|
|
|
void **dst_count_p,
|
2006-03-01 01:01:36 +01:00
|
|
|
unsigned long delta_limit,
|
|
|
|
unsigned long *src_copied,
|
|
|
|
unsigned long *literal_added);
|
|
|
|
|
2005-05-21 11:39:09 +02:00
|
|
|
#endif
|