]> git.proxmox.com Git - libgit2.git/commitdiff
diff: preserve original mode in the index
authorEdward Thomson <ethomson@edwardthomson.com>
Fri, 19 Jun 2015 15:32:26 +0000 (08:32 -0700)
committerEdward Thomson <ethomson@edwardthomson.com>
Sat, 20 Jun 2015 19:37:32 +0000 (15:37 -0400)
When updating the index during a diff, preserve the original mode,
which prevents us from dropping the mode to what we have interpreted
as on our system (eg, what the working directory claims it to be,
which may be a lie on some systems.)

src/checkout.c
src/diff.c
src/diff.h

index fd2b19a951b6de330b7be479ed964bce2ea1c793..2893c63de25479dd39557ccb7e02fa72b2b8ee01 100644 (file)
@@ -211,7 +211,7 @@ static bool checkout_is_workdir_modified(
        if (baseitem->size && wditem->file_size != baseitem->size)
                return true;
 
-       if (git_diff__oid_for_entry(&oid, data->diff, wditem, NULL) < 0)
+       if (git_diff__oid_for_entry(&oid, data->diff, wditem, wditem->mode, NULL) < 0)
                return false;
 
        /* Allow the checkout if the workdir is not modified *or* if the checkout
index c9d1d87301e9bf99c41d8ef6375d4b332979dae8..d7365ef772ea0f27c34ff1981ceec2c2de5f35a2 100644 (file)
@@ -570,7 +570,7 @@ int git_diff__oid_for_file(
        git_oid *out,
        git_diff *diff,
        const char *path,
-       uint16_t  mode,
+       uint16_t mode,
        git_off_t size)
 {
        git_index_entry entry;
@@ -580,13 +580,14 @@ int git_diff__oid_for_file(
        entry.file_size = size;
        entry.path = (char *)path;
 
-       return git_diff__oid_for_entry(out, diff, &entry, NULL);
+       return git_diff__oid_for_entry(out, diff, &entry, mode, NULL);
 }
 
 int git_diff__oid_for_entry(
        git_oid *out,
        git_diff *diff,
        const git_index_entry *src,
+       uint16_t mode,
        const git_oid *update_match)
 {
        int error = 0;
@@ -600,7 +601,7 @@ int git_diff__oid_for_entry(
                &full_path, git_repository_workdir(diff->repo), entry.path) < 0)
                return -1;
 
-       if (!entry.mode) {
+       if (!mode) {
                struct stat st;
 
                diff->perf.stat_calls++;
@@ -616,7 +617,7 @@ int git_diff__oid_for_entry(
        }
 
        /* calculate OID for file if possible */
-       if (S_ISGITLINK(entry.mode)) {
+       if (S_ISGITLINK(mode)) {
                git_submodule *sm;
 
                if (!git_submodule_lookup(&sm, diff->repo, entry.path)) {
@@ -630,7 +631,7 @@ int git_diff__oid_for_entry(
                         */
                        giterr_clear();
                }
-       } else if (S_ISLNK(entry.mode)) {
+       } else if (S_ISLNK(mode)) {
                error = git_odb__hashlink(out, full_path.ptr);
                diff->perf.oid_calculations++;
        } else if (!git__is_sizet(entry.file_size)) {
@@ -657,11 +658,14 @@ int git_diff__oid_for_entry(
        /* update index for entry if requested */
        if (!error && update_match && git_oid_equal(out, update_match)) {
                git_index *idx;
+               git_index_entry updated_entry;
 
-               if (!(error = git_repository_index__weakptr(&idx, diff->repo))) {
-                       git_oid_cpy(&entry.id, out);
-                       error = git_index_add(idx, &entry);
-               }
+               memcpy(&updated_entry, &entry, sizeof(git_index_entry));
+               updated_entry.mode = mode;
+               git_oid_cpy(&updated_entry.id, out);
+
+               if (!(error = git_repository_index__weakptr(&idx, diff->repo)))
+                       error = git_index_add(idx, &updated_entry);
        }
 
        git_buf_free(&full_path);
@@ -856,7 +860,7 @@ static int maybe_modified(
                        &oitem->id : NULL;
 
                if ((error = git_diff__oid_for_entry(
-                               &noid, diff, nitem, update_check)) < 0)
+                               &noid, diff, nitem, nmode, update_check)) < 0)
                        return error;
 
                /* if oid matches, then mark unmodified (except submodules, where
index 3305238d0dc11e1f72c90eb22dfef24675c1d51d..2a35fd9aca56dc4795f9b0dbc7b7d7c3c9022c84 100644 (file)
@@ -94,7 +94,7 @@ extern int git_diff_delta__format_file_header(
 extern int git_diff__oid_for_file(
        git_oid *out, git_diff *, const char *, uint16_t, git_off_t);
 extern int git_diff__oid_for_entry(
-       git_oid *out, git_diff *, const git_index_entry *, const git_oid *update);
+       git_oid *out, git_diff *, const git_index_entry *, uint16_t, const git_oid *update);
 
 extern int git_diff__from_iterators(
        git_diff **diff_ptr,