diff options
| author | Vicent Martà <vicent@github.com> | 2013-05-24 01:13:48 -0700 |
|---|---|---|
| committer | Vicent Martà <vicent@github.com> | 2013-05-24 01:13:48 -0700 |
| commit | 30caf0cf2942412981b7662e50a2e9242afa2cce (patch) | |
| tree | cbfb8e0a543dbce5f11230dad85e8309bf90037c /include/git2 | |
| parent | 87a56fe015d263e592242157fa6c88badf46fa18 (diff) | |
| parent | 49f70f2c370e649c3a0970b6aadd6f5cdf4f2701 (diff) | |
| download | libgit2-30caf0cf2942412981b7662e50a2e9242afa2cce.tar.gz | |
Merge pull request #1595 from arrbee/even-more-rename-fixes
Even more rename detection fixes
Diffstat (limited to 'include/git2')
| -rw-r--r-- | include/git2/diff.h | 70 | ||||
| -rw-r--r-- | include/git2/oid.h | 21 |
2 files changed, 73 insertions, 18 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h index 1feddd7a2..0d4875b43 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -243,6 +243,19 @@ typedef struct { * `NOT_BINARY` flag set to avoid examining file contents if you do not pass * in hunk and/or line callbacks to the diff foreach iteration function. It * will just use the git attributes for those files. + * + * The similarity score is zero unless you call `git_diff_find_similar()` + * which does a similarity analysis of files in the diff. Use that + * function to do rename and copy detection, and to split heavily modified + * files in add/delete pairs. After that call, deltas with a status of + * GIT_DELTA_RENAMED or GIT_DELTA_COPIED will have a similarity score + * between 0 and 100 indicating how similar the old and new sides are. + * + * If you ask `git_diff_find_similar` to find heavily modified files to + * break, but to not *actually* break the records, then GIT_DELTA_MODIFIED + * records may have a non-zero similarity score if the self-similarity is + * below the split threshold. To display this value like core Git, invert + * the score (a la `printf("M%03d", 100 - delta->similarity)`). */ typedef struct { git_diff_file old_file; @@ -408,18 +421,28 @@ typedef enum { /** consider unmodified as copy sources? (`--find-copies-harder`) */ GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1 << 3), - /** split large rewrites into delete/add pairs (`--break-rewrites=/M`) */ - GIT_DIFF_FIND_AND_BREAK_REWRITES = (1 << 4), + /** mark large rewrites for split (`--break-rewrites=/M`) */ + GIT_DIFF_FIND_REWRITES = (1 << 4), + /** actually split large rewrites into delete/add pairs */ + GIT_DIFF_BREAK_REWRITES = (1 << 5), + /** mark rewrites for split and break into delete/add pairs */ + GIT_DIFF_FIND_AND_BREAK_REWRITES = + (GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES), + + /** find renames/copies for untracked items in working directory */ + GIT_DIFF_FIND_FOR_UNTRACKED = (1 << 6), /** turn on all finding features */ - GIT_DIFF_FIND_ALL = (0x1f), + GIT_DIFF_FIND_ALL = (0x0ff), /** measure similarity ignoring leading whitespace (default) */ GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0, /** measure similarity ignoring all whitespace */ - GIT_DIFF_FIND_IGNORE_WHITESPACE = (1 << 6), + GIT_DIFF_FIND_IGNORE_WHITESPACE = (1 << 12), /** measure similarity including all data */ - GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 7), + GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 13), + /** measure similarity only by comparing SHAs (fast and cheap) */ + GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1 << 14), } git_diff_find_t; /** @@ -446,7 +469,10 @@ typedef struct { * - `copy_threshold` is the same as the -C option with a value * - `rename_from_rewrite_threshold` matches the top of the -B option * - `break_rewrite_threshold` matches the bottom of the -B option - * - `target_limit` matches the -l option + * - `rename_limit` is the maximum number of matches to consider for + * a particular file. This is a little different from the `-l` option + * to regular Git because we will still process up to this many matches + * before abandoning the search. * * The `metric` option allows you to plug in a custom similarity metric. * Set it to NULL for the default internal metric which is based on sampling @@ -458,21 +484,21 @@ typedef struct { unsigned int version; /** Combination of git_diff_find_t values (default FIND_RENAMES) */ - unsigned int flags; + uint32_t flags; /** Similarity to consider a file renamed (default 50) */ - unsigned int rename_threshold; + uint16_t rename_threshold; /** Similarity of modified to be eligible rename source (default 50) */ - unsigned int rename_from_rewrite_threshold; + uint16_t rename_from_rewrite_threshold; /** Similarity to consider a file a copy (default 50) */ - unsigned int copy_threshold; + uint16_t copy_threshold; /** Similarity to split modify into delete/add pair (default 60) */ - unsigned int break_rewrite_threshold; + uint16_t break_rewrite_threshold; - /** Maximum similarity sources to examine (a la diff's `-l` option or - * the `diff.renameLimit` config) (default 200) + /** Maximum similarity sources to examine for a file (somewhat like + * git-diff's `-l` option or `diff.renameLimit` config) (default 200) */ - unsigned int target_limit; + size_t rename_limit; /** Pluggable similarity metric; pass NULL to use internal metric */ git_diff_similarity_metric *metric; @@ -689,6 +715,22 @@ GIT_EXTERN(int) git_diff_print_compact( void *payload); /** + * Iterate over a diff generating text output like "git diff --raw". + * + * Returning a non-zero value from the callbacks will terminate the + * iteration and cause this return `GIT_EUSER`. + * + * @param diff A git_diff_list generated by one of the above functions. + * @param print_cb Callback to make per line of diff text. + * @param payload Reference pointer that will be passed to your callback. + * @return 0 on success, GIT_EUSER on non-zero callback, or error code + */ +GIT_EXTERN(int) git_diff_print_raw( + git_diff_list *diff, + git_diff_data_cb print_cb, + void *payload); + +/** * Look up the single character abbreviation for a delta status code. * * When you call `git_diff_print_compact` it prints single letter codes into diff --git a/include/git2/oid.h b/include/git2/oid.h index b20bb221a..018cead4a 100644 --- a/include/git2/oid.h +++ b/include/git2/oid.h @@ -90,6 +90,17 @@ GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw); GIT_EXTERN(void) git_oid_fmt(char *out, const git_oid *id); /** + * Format a git_oid into a partial hex string. + * + * @param out output hex string; you say how many bytes to write. + * If the number of bytes is > GIT_OID_HEXSZ, extra bytes + * will be zeroed; if not, a '\0' terminator is NOT added. + * @param n number of characters to write into out string + * @param oid oid structure to format. + */ +GIT_EXTERN(void) git_oid_nfmt(char *out, size_t n, const git_oid *id); + +/** * Format a git_oid into a loose-object path string. * * The resulting string is "aa/...", where "aa" is the first two @@ -117,10 +128,12 @@ GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id); * Format a git_oid into a buffer as a hex format c-string. * * If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting - * oid c-string will be truncated to n-1 characters. If there are - * any input parameter errors (out == NULL, n == 0, oid == NULL), - * then a pointer to an empty string is returned, so that the return - * value can always be printed. + * oid c-string will be truncated to n-1 characters (but will still be + * NUL-byte terminated). + * + * If there are any input parameter errors (out == NULL, n == 0, oid == + * NULL), then a pointer to an empty string is returned, so that the + * return value can always be printed. * * @param out the buffer into which the oid string is output. * @param n the size of the out buffer. |
