summaryrefslogtreecommitdiff
path: root/src/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/diff.c')
-rw-r--r--src/diff.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/src/diff.c b/src/diff.c
index 499b95b44..7c8e2a9bb 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -5,8 +5,6 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "common.h"
-#include "git2/diff.h"
-#include "git2/oid.h"
#include "diff.h"
#include "fileops.h"
#include "config.h"
@@ -268,9 +266,17 @@ static int diff_delta__from_two(
delta->old_file.mode = old_mode;
delta->old_file.flags |= GIT_DIFF_FILE_VALID_OID;
- git_oid_cpy(&delta->new_file.oid, new_oid ? new_oid : &new_entry->oid);
+ git_oid_cpy(&delta->new_file.oid, &new_entry->oid);
delta->new_file.size = new_entry->file_size;
delta->new_file.mode = new_mode;
+
+ if (new_oid) {
+ if ((diff->opts.flags & GIT_DIFF_REVERSE) != 0)
+ git_oid_cpy(&delta->old_file.oid, new_oid);
+ else
+ git_oid_cpy(&delta->new_file.oid, new_oid);
+ }
+
if (new_oid || !git_oid_iszero(&new_entry->oid))
delta->new_file.flags |= GIT_DIFF_FILE_VALID_OID;
@@ -425,6 +431,11 @@ void git_diff_list_free(git_diff_list *diff)
GIT_REFCOUNT_DEC(diff, diff_list_free);
}
+void git_diff_list_addref(git_diff_list *diff)
+{
+ GIT_REFCOUNT_INC(diff);
+}
+
static int oid_for_workdir_item(
git_repository *repo,
const git_index_entry *item,
@@ -519,17 +530,17 @@ static int maybe_modified(
omode == nmode)
status = GIT_DELTA_UNMODIFIED;
- /* if modes match and we have an unknown OID and a workdir iterator,
- * then check deeper for matching
+ /* if we have an unknown OID and a workdir iterator, then check some
+ * circumstances that can accelerate things or need special handling
*/
- else if (omode == nmode &&
- git_oid_iszero(&nitem->oid) &&
- new_iter->type == GIT_ITERATOR_WORKDIR)
+ else if (git_oid_iszero(&nitem->oid) &&
+ new_iter->type == GIT_ITERATOR_WORKDIR)
{
/* TODO: add check against index file st_mtime to avoid racy-git */
- /* if they files look exactly alike, then we'll assume the same */
- if (oitem->file_size == nitem->file_size &&
+ /* if the stat data looks exactly alike, then assume the same */
+ if (omode == nmode &&
+ oitem->file_size == nitem->file_size &&
(!(diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) ||
(oitem->ctime.seconds == nitem->ctime.seconds)) &&
oitem->mtime.seconds == nitem->mtime.seconds &&
@@ -554,16 +565,15 @@ static int maybe_modified(
status = GIT_DELTA_UNMODIFIED;
}
}
+ }
- /* TODO: check git attributes so we will not have to read the file
- * in if it is marked binary.
- */
-
- else if (oid_for_workdir_item(diff->repo, nitem, &noid) < 0)
+ /* if we got here and decided that the files are modified, but we
+ * haven't calculated the OID of the new item, then calculate it now
+ */
+ if (status == GIT_DELTA_MODIFIED && git_oid_iszero(&nitem->oid)) {
+ if (oid_for_workdir_item(diff->repo, nitem, &noid) < 0)
return -1;
-
- else if (git_oid_cmp(&oitem->oid, &noid) == 0 &&
- omode == nmode)
+ else if (omode == nmode && git_oid_equal(&oitem->oid, &noid))
status = GIT_DELTA_UNMODIFIED;
/* store calculated oid so we don't have to recalc later */