Fixed GIT_DIFF_UPDATE_INDEX not being aware of executable bit changes In the prior implementation, enabling GIT_DIFF_UPDATE_INDEX would overwrite entries in the index with the ones generated from scanning the working if the OID was the same. Because this OID comparison ignores file modes, this means an file in the workdir with only an exec bit difference with the one in the index would end up being overwritten, resulting in the exec bit being loss. There might be other related bugs but the fix of comparing OIDs and file modes should address them all.
diff --git a/src/diff.c b/src/diff.c
index ba8a1b8..08e218c 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -807,7 +807,7 @@ static int maybe_modified(
*/
if (modified_uncertain && git_oid_iszero(&nitem->id)) {
const git_oid *update_check =
- DIFF_FLAG_IS_SET(diff, GIT_DIFF_UPDATE_INDEX) ?
+ DIFF_FLAG_IS_SET(diff, GIT_DIFF_UPDATE_INDEX) && omode == nmode ?
&oitem->id : NULL;
if ((error = git_diff__oid_for_entry(
&noid, diff, nitem, update_check)) < 0)