Upon git add and git update-index, if core.symlinks = false, do not change an entry from symbolic link to regular file even if the filesystem entry is a regular file. Signed-off-by: Johannes Sixt <johannes.sixt@xxxxxxxxxx> --- builtin-update-index.c | 6 +++--- cache.h | 6 +++++- read-cache.c | 12 +++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/builtin-update-index.c b/builtin-update-index.c index 772aaba..cf8c069 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -109,11 +109,11 @@ static int add_file_to_cache(const char *path) ce->ce_flags = htons(namelen); fill_stat_cache_info(ce, &st); - if (trust_executable_bit) + if (trust_executable_bit && trust_symlink_fmt) ce->ce_mode = create_ce_mode(st.st_mode); else { - /* If there is an existing entry, pick the mode bits - * from it, otherwise assume unexecutable. + /* If there is an existing entry, pick the mode bits and format + * from it, otherwise assume unexecutable regular file. */ struct cache_entry *ent; int pos = cache_name_pos(path, namelen); diff --git a/cache.h b/cache.h index 6cbb9d8..298cdd2 100644 --- a/cache.h +++ b/cache.h @@ -108,7 +108,11 @@ static inline unsigned int create_ce_mode(unsigned int mode) } static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode) { - extern int trust_executable_bit; + extern int trust_executable_bit, trust_symlink_fmt; + /* note: !trust_symlink_fmt trumps !trust_executable_bit */ + if (!trust_symlink_fmt && S_ISREG(mode) && + ce && S_ISLNK(ntohl(ce->ce_mode))) + return ce->ce_mode; if (!trust_executable_bit && S_ISREG(mode)) { if (ce && S_ISREG(ntohl(ce->ce_mode))) return ce->ce_mode; diff --git a/read-cache.c b/read-cache.c index 605b352..f09ee2e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -116,7 +116,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) switch (ntohl(ce->ce_mode) & S_IFMT) { case S_IFREG: - changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0; + if (trust_symlink_fmt && !S_ISREG(st->st_mode)) + changed |= TYPE_CHANGED; /* We consider only the owner x bit to be relevant for * "mode changes" */ @@ -125,7 +126,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) changed |= MODE_CHANGED; break; case S_IFLNK: - changed |= !S_ISLNK(st->st_mode) ? TYPE_CHANGED : 0; + if (trust_symlink_fmt && !S_ISLNK(st->st_mode)) + changed |= TYPE_CHANGED; break; default: die("internal error: ce_mode is %o", ntohl(ce->ce_mode)); @@ -344,11 +346,11 @@ int add_file_to_index(const char *path, int verbose) ce->ce_flags = htons(namelen); fill_stat_cache_info(ce, &st); - if (trust_executable_bit) + if (trust_executable_bit && trust_symlink_fmt) ce->ce_mode = create_ce_mode(st.st_mode); else { - /* If there is an existing entry, pick the mode bits - * from it, otherwise assume unexecutable. + /* If there is an existing entry, pick the mode bits and format + * from it, otherwise assume unexecutable regular file. */ struct cache_entry *ent; int pos = cache_name_pos(path, namelen); -- 1.5.0.19.gddff - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html