Commit Graph

80 Commits

Author SHA1 Message Date
Russell Belfer
37f66e8263 Fix Windows warnings
This fixes problems with missing function prototypes and 64-bit
data issues on Windows.
2013-06-12 15:21:21 -07:00
Vicent Martí
88c401bec8 Merge pull request #1643 from ethomson/rename_source
Keep data about source of similarity
2013-06-12 14:54:32 -07:00
Edward Thomson
690bf41ce5 keep source similarity in rename detection 2013-06-10 15:18:38 -05:00
Russell Belfer
114f5a6c41 Reorganize diff and add basic diff driver
This is a significant reorganization of the diff code to break it
into a set of more clearly distinct files and to document the new
organization.  Hopefully this will make the diff code easier to
understand and to extend.

This adds a new `git_diff_driver` object that looks of diff driver
information from the attributes and the config so that things like
function content in diff headers can be provided.  The full driver
spec is not implemented in the commit - this is focused on the
reorganization of the code and putting the driver hooks in place.

This also removes a few #includes from src/repository.h that were
overbroad, but as a result required extra #includes in a variety
of places since including src/repository.h no longer results in
pulling in the whole world.
2013-06-10 10:10:39 -07:00
Russell Belfer
49f70f2c37 Fill out diff rename test coverage
This extends the rename tests to make sure that every rename
scenario in the inner loop of git_diff_find_similar is actually
exercised.  Also, fixes an incorrect assert that was in one of
the clauses that was not previously being exercised.
2013-05-23 15:48:06 -07:00
Russell Belfer
67db583dab More diff rename tests; better split swap handling
This adds a couple more tests of different rename scenarios.

Also, this fixes a problem with the case where you have two
"split" deltas and the left half of one matches the right half of
the other.  That case was already being handled, but in the wrong
order in a way that could result in bad output.  Also, if the swap
also happened to put the other two halves into the correct place
(i.e. two files exchanged places with each other), then the second
delta was left with the SPLIT flag set when it really should be
cleared.
2013-05-23 15:06:07 -07:00
Russell Belfer
c68b09dc7a Fix dereference of freed delta
I was accidentally using a value that I had just freed.  This
moves the clearing of the delta internal flags into a better place.
2013-05-23 11:52:34 -07:00
Russell Belfer
a21cbb12db Significant rename detection rewrite
This flips rename detection around so instead of creating a
forward mapping from deltas to possible rename targets, instead
it creates a reverse mapping, looking at possible targets and
trying to find a source that they could have been renamed or
copied from.  This is important because each output can only
have a single source, but a given source could map to multiple
outputs (in the form of COPIED records).

Additionally, this makes a couple of tweaks to the public rename
detection APIs, mostly renaming a couple of options that control
the behavior to make more sense and to be more like core Git.

I walked through the tests looking at the exact results and
updated the expectations based on what I saw.  The new code is
different from the old because it cannot give some nonsense
results (like A was renamed to both B and C) which were part of
the outputs previously.
2013-05-22 10:37:12 -07:00
Russell Belfer
9be5be47fb More git_diff_find_similar improvements
- Add new GIT_DIFF_FIND_EXACT_MATCH_ONLY flag to do similarity
  matching without using the similarity metric (i.e. only compare
  the SHA).
- Clean up the similarity measurement code to more rigorously
  distinguish between files that are not similar and files that
  are not comparable (previously, a 0 could either mean that the
  files could not be compared or that they were totally different)
- When splitting a MODIFIED file into a DELETE/ADD pair, actually
  make a DELETED/UNTRACKED pair if the right side of the diff is
  from the working directory.  This prevents an odd mix of ADDED
  and UNTRACKED files on workdir diffs.
2013-05-20 13:37:21 -07:00
Russell Belfer
d958e37a48 Fix issues with git_diff_find_similar
There are a number of bugs in the rename code that only were
obvious when I started testing it against large old repos with
more complex patterns.  (The code to do that testing is not ready
to merge with libgit2, but I do plan to add more thorough tests.)

This contains a significant number of changes and also tweaks the
public API slightly to make emulating core git easier.

Most notably, this separates the GIT_DIFF_FIND_AND_BREAK_REWRITES
flag into FIND_REWRITES (which adds a self-similarity score to
every modified file) and BREAK_REWRITES (which splits the modified
deltas into add/remove pairs in the diff list).  When you do a raw
output of core git, rewrites show up as M090 or such, not at A and
D output, so I wanted to be able to emulate that.

Publicly, this also changes the flags to be uint16_t since we
don't need values out of that range.

Internally, this contains significant changes from a number of
small bug fixes (like using the wrong side of the diff to decide
if the object could be found in the ODB vs the workdir) to larger
issues about which files can and should be compared and how the
various edge cases of similarity scores should be treated.

Honestly, I don't think this is the last update that will have to
be made to this code, but I think this moves us closer to correct
behavior and I tried to document the code so it would be easier
to follow..
2013-05-17 17:21:45 -07:00
Vicent Martí
7159620044 Merge pull request #1588 from arrbee/fixes-for-checkout-and-diff
Bug fixes for checkout and diff
2013-05-15 15:47:46 -07:00
Russell Belfer
09fae31d45 Improve robustness of diff rename detection
Under some strange circumstances, diffs can end up listing files
that we can't actually open successfully.  Instead of aborting
the git_diff_find_similar, this makes it so that those files just
won't be considered as valid rename/copy targets instead.
2013-05-15 14:58:26 -07:00
nulltoken
1fed6b07f0 Fix trailing whitespaces 2013-05-15 22:41:30 +02:00
Edward Thomson
0462fba538 renames! 2013-04-30 16:01:11 -05:00
Russell Belfer
b7f167da29 Make git_oid_cmp public and add git_oid__cmp 2013-04-29 13:52:12 -07:00
Russell Belfer
8cfd54f0d8 Fix Windows/Win32 warning 2013-03-26 12:27:15 -07:00
Edward Thomson
aa408cbfc4 handle small files in similarity metrics 2013-03-11 12:47:01 -05:00
Russell Belfer
0a0089131f Minor improvements to find_similar code
This moves a couple of checks outside of the inner loop of the
find_similar rename/copy detection phase that are only dependent
on the "from" side of a detection.

Also, this replaces the inefficient initialization of the
options structure when a value is not provided explicitly by the
user.
2013-02-22 10:21:02 -08:00
Russell Belfer
f827589067 Replace static data with configured metric
Instead of creating three git_diff_similarity_metric statically
for the various config options, just create the metric structure
on demand and populate it, using the payload to specific the
extra flags that should be passed to the hashsig.  This removes
a level of obfuscation from the code, I think.
2013-02-22 10:19:50 -08:00
Russell Belfer
d4b747c1cb Add diff rename tests with partial similarity
This adds some new tests that actually exercise the similarity
metric between files to detect renames, copies, and split modified
files that are too heavily modified.

There is still more testing to do - these tests are just partially
covering the cases.

There is also one bug fix in this where a change set with only
MODIFY being broken into ADD/DELETE (due to low self-similarity)
without any additional RENAMED entries would end up not processing
the split requests (because the num_rewrites counter got reset).
2013-02-21 16:44:44 -08:00
Russell Belfer
960a04dd56 Initial integration of similarity metric to diff
This is the initial integration of the similarity metric into
the `git_diff_find_similar()` code path.  The existing tests all
pass, but the new functionality isn't currently well tested.  The
integration does go through the pluggable metric interface, so it
should be possible to drop in an alternative to the internal
metric that libgit2 implements.

This comes along with a behavior change for an existing interface;
namely, passing two NULLs to git_diff_blobs (or passing NULLs to
git_diff_blob_to_buffer) will now call the file_cb parameter zero
times instead of one time.  I know it's strange that that change
is paired with this other change, but it emerged from some
initialization changes that I ended up making.
2013-02-21 12:40:33 -08:00
Russell Belfer
71a3d27ea6 Replace diff delta binary with flags
Previously the git_diff_delta recorded if the delta was binary.
This replaces that (with no net change in structure size) with
a full set of flags.  The flag values that were already in use
for individual git_diff_file objects are reused for the delta
flags, too (along with renaming those flags to make it clear that
they are used more generally).

This (a) makes things somewhat more consistent (because I was
using a -1 value in the "boolean" binary field to indicate unset,
whereas now I can just use the flags that are easier to understand),
and (b) will make it easier for me to add some additional flags to
the delta object in the future, such as marking the results of a
copy/rename detection or other deltas that might want a special
indicator.

While making this change, I officially moved some of the flags that
were internal only into the private diff header.

This also allowed me to remove a gross hack in rename/copy detect
code where I was overwriting the status field with an internal
value.
2013-02-20 15:10:21 -08:00
Russell Belfer
9bc8be3d7e Refine pluggable similarity API
This plugs in the three basic similarity strategies for handling
whitespace via internal use of the pluggable API.  In so doing, I
realized that the use of git_buf in the hashsig API was not needed
and actually just made it harder to use, so I tweaked that API as
well.

Note that the similarity metric is still not hooked up in the
find_similarity code - this is just setting out the function that
will be used.
2013-02-20 15:09:41 -08:00
Russell Belfer
5e5848eb15 Change similarity metric to sampled hashes
This moves the similarity metric code out of buf_text and into a
new file.  Also, this implements a different approach to similarity
measurement based on a Rabin-Karp rolling hash where we only keep
the top 100 and bottom 100 hashes.  In theory, that should be
sufficient samples to given a fairly accurate measurement while
limiting the amount of data we keep for file signatures no matter
how large the file is.
2013-02-20 15:09:40 -08:00
Russell Belfer
99ba8f2322 wip: adding metric to diff 2013-02-20 15:09:40 -08:00
Philip Kelley
11d9f6b304 Vector improvements and their fallout 2013-01-27 14:17:07 -05:00
Edward Thomson
359fc2d241 update copyrights 2013-01-08 17:31:27 -06:00
Ben Straub
c7231c45fe Deploy GITERR_CHECK_VERSION 2012-11-30 16:31:42 -08:00
Ben Straub
ca901e7b0f Deploy GIT_DIFF_FIND_OPTIONS_INIT 2012-11-30 13:12:15 -08:00
Russell Belfer
db106d01f0 Move rename detection into new file
This improves the naming for the rename related functionality
moving it to be called `git_diff_find_similar()` and renaming
all the associated constants, etc. to make more sense.

I also moved the new code (plus the existing `git_diff_merge`)
into a new file `diff_tform.c` where I can put new functions
related to manipulating git diff lists.

This also updates the implementation significantly from the
last revision fixing some ordering issues (where break-rewrite
needs to be handled prior to copy and rename detection) and
improving config option handling.
2012-10-30 09:40:50 -07:00