git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Add ".git/config" file parser

From
Junio C Hamano <junkio@cox.net>
Date
Oct 12, 2005, 00:25 UTC
Message-ID
<7vvf03r36y.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<Pine.LNX.4.64.0510101415080.14597@g5.osdl.org>

This is a WIP to implement update-index that does not care the filesystem mode change. When you have the following in .git/config:

        [core]
                filemode = false
the following things happen:
 * "git-update-index --refresh" does not consider the executable
   bit change significant.
 * "git-update-index" on an existing path takes executable bit
   from the existing index entry, if the blob types are the
   same.
 * "git-diff-files" pretends the path on the filesystem has the
   same executable bit as the existing index entry, if the blob
   types are the same.
Yet to be done items are:
 * Other programs from diff-* family that compares with the
   filesystem needs to be covered.
 * "git-update-index --chmod=+x" and "--chmod=-x".
 * Refector code that takes the executable bit change from an
   existing index entry.
WIP-not-worth-signing-off-yet-by: Junio C Hamano <junkio.cox.net>
---
cd /opt/packrat/playpen/public/in-place/git/git.junio/
git diff HEAD
diff --git a/diff-files.c b/diff-files.c
index 96d2c7f..014f74e 100644
--- a/diff-files.c
+++ b/diff-files.c
@@ -81,7 +81,7 @@ int main(int argc, const char **argv)
 
 	for (i = 0; i < entries; i++) {
 		struct stat st;
-		unsigned int oldmode;
+		unsigned int oldmode, newmode;
 		struct cache_entry *ce = active_cache[i];
 		int changed;
 
@@ -111,7 +111,12 @@ int main(int argc, const char **argv)
 		if (!changed && !diff_options.find_copies_harder)
 			continue;
 		oldmode = ntohl(ce->ce_mode);
-		show_modified(oldmode, DIFF_FILE_CANON_MODE(st.st_mode),
+
+		newmode = DIFF_FILE_CANON_MODE(st.st_mode);
+		if (!trust_executable_bit &&
+		    S_ISREG(newmode) && ((newmode ^ oldmode) == 0111))
+			newmode = oldmode;
+		show_modified(oldmode, newmode,
 			      ce->sha1, (changed ? null_sha1 : ce->sha1),
 			      ce->name);
 	}
diff --git a/read-cache.c b/read-cache.c
index c7f3b26..4ed369a 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -36,8 +36,11 @@ int ce_match_stat(struct cache_entry *ce
 	switch (ntohl(ce->ce_mode) & S_IFMT) {
 	case S_IFREG:
 		changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0;
-		/* We consider only the owner x bit to be relevant for "mode changes" */
-		if (0100 & (ntohl(ce->ce_mode) ^ st->st_mode))
+		/* We consider only the owner x bit to be relevant for
+		 * "mode changes"
+		 */
+		if (trust_executable_bit &&
+		    (0100 & (ntohl(ce->ce_mode) ^ st->st_mode)))
 			changed |= MODE_CHANGED;
 		break;
 	case S_IFLNK:
@@ -393,7 +396,7 @@ int add_cache_entry(struct cache_entry *
 	int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
 	pos = cache_name_pos(ce->name, ntohs(ce->ce_flags));
 
-	/* existing match? Just replace it */
+	/* existing match? Just replace it. */
 	if (pos >= 0) {
 		active_cache_changed = 1;
 		active_cache[pos] = ce;
@@ -416,7 +419,8 @@ int add_cache_entry(struct cache_entry *
 	if (!ok_to_add)
 		return -1;
 
-	if (!skip_df_check && check_file_directory_conflict(ce, pos, ok_to_replace)) {
+	if (!skip_df_check &&
+	    check_file_directory_conflict(ce, pos, ok_to_replace)) {
 		if (!ok_to_replace)
 			return -1;
 		pos = cache_name_pos(ce->name, ntohs(ce->ce_flags));
diff --git a/update-index.c b/update-index.c
index 01b4088..fd3a882 100644
--- a/update-index.c
+++ b/update-index.c
@@ -67,13 +67,23 @@ static int add_file_to_cache(const char 
 			return error("lstat(\"%s\"): %s", path,
 				     strerror(errno));
 	}
+
 	namelen = strlen(path);
 	size = cache_entry_size(namelen);
 	ce = xmalloc(size);
 	memset(ce, 0, size);
 	memcpy(ce->name, path, namelen);
 	fill_stat_cache_info(ce, &st);
+
 	ce->ce_mode = create_ce_mode(st.st_mode);
+	if (!trust_executable_bit) {
+		/* If there is an existing entry, pick the mode bits
+		 * from it.
+		 */
+		int pos = cache_name_pos(path, namelen);
+		if (0 <= pos)
+			ce->ce_mode = active_cache[pos]->ce_mode;
+	}
 	ce->ce_flags = htons(namelen);
 
 	if (index_path(ce->sha1, path, &st, !info_only))
@@ -328,6 +338,8 @@ int main(int argc, const char **argv)
 	const char *prefix = setup_git_directory();
 	int prefix_length = prefix ? strlen(prefix) : 0;
 
+	git_config(git_default_config);
+
 	newfd = hold_index_file_for_update(&cache_file, get_index_file());
 	if (newfd < 0)
 		die("unable to create new cachefile");
Previous: Linus TorvaldsNext: Junio C Hamano
Message 15 of 18 in “Seeing various mode changes on cygwin”
  1. Jonas FonsecaOct 8, 2005
  2. Junio C HamanoOct 8, 2005
  3. Alex RiesenOct 8, 2005
  4. Junio C HamanoOct 8, 2005
  5. Linus TorvaldsOct 9, 2005
  6. Junio C HamanoOct 9, 2005
  7. Daniel BarkalowOct 10, 2005
  8. Junio C HamanoOct 10, 2005
  9. Daniel BarkalowOct 10, 2005
  10. Linus TorvaldsOct 10, 2005
  11. Add ".git/config" file parserLinus Torvalds, Oct 10, 2005
  12. Linus TorvaldsOct 10, 2005
  13. H. Peter AnvinOct 10, 2005
  14. Linus TorvaldsOct 10, 2005
  15. Junio C HamanoOct 12, 2005
  16. Use core.filemode.Junio C Hamano, Oct 12, 2005
  17. H. Peter AnvinOct 9, 2005
  18. Alex RiesenOct 9, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.