summaryrefslogtreecommitdiff
path: root/src/diff_output.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2012-06-04 16:17:41 -0700
committerRussell Belfer <rb@github.com>2012-06-08 12:09:10 -0700
commit0abd724454078f2089701b54be94df7306dcfb8e (patch)
tree603540e3cabb66601f063d3538fbce7f7d022af0 /src/diff_output.c
parent80c03754ae57ad387a6c02a5e58a59a327d44638 (diff)
downloadlibgit2-0abd724454078f2089701b54be94df7306dcfb8e.tar.gz
Fix filemode comparison in diffs
File modes were both not being ignored properly on platforms where they should be ignored, nor be diffed consistently on platforms where they are supported. This change adds a number of diff and status filemode change tests. This also makes sure that filemode-only changes are included in the diff output when they occur and that filemode changes are ignored successfully when core.filemode is false. There is no code that automatically toggles core.filemode based on the capabilities of the current platform, so the user still needs to be careful in their .git/config file.
Diffstat (limited to 'src/diff_output.c')
-rw-r--r--src/diff_output.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/diff_output.c b/src/diff_output.c
index 1c65e1bb8..d1aa910b3 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -359,7 +359,7 @@ int git_diff_foreach(
/* map files */
if (delta->binary != 1 &&
- (hunk_cb || line_cb) &&
+ (hunk_cb || line_cb || git_oid_iszero(&delta->old_file.oid)) &&
(delta->status == GIT_DELTA_DELETED ||
delta->status == GIT_DELTA_MODIFIED))
{
@@ -397,7 +397,9 @@ int git_diff_foreach(
/* since we did not have the definitive oid, we may have
* incorrect status and need to skip this item.
*/
- if (git_oid_cmp(&delta->old_file.oid, &delta->new_file.oid) == 0) {
+ if (delta->old_file.mode == delta->new_file.mode &&
+ !git_oid_cmp(&delta->old_file.oid, &delta->new_file.oid))
+ {
delta->status = GIT_DELTA_UNMODIFIED;
if ((diff->opts.flags & GIT_DIFF_INCLUDE_UNMODIFIED) == 0)
goto cleanup;
@@ -420,7 +422,8 @@ int git_diff_foreach(
*/
if (file_cb != NULL) {
- error = file_cb(data, delta, (float)info.index / diff->deltas.length);
+ error = file_cb(
+ data, delta, (float)info.index / diff->deltas.length);
if (error < 0)
goto cleanup;
}
@@ -433,6 +436,10 @@ int git_diff_foreach(
if (!old_data.len && !new_data.len)
goto cleanup;
+ /* nothing to do if only diff was a mode change */
+ if (!git_oid_cmp(&delta->old_file.oid, &delta->new_file.oid))
+ goto cleanup;
+
assert(hunk_cb || line_cb);
info.delta = delta;