[PATCH] Do not change the file type if the filesystem does not support symlinks.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]