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

[RFC PATCH 1/2] dir/read-cache: Allow adding .git files and directories

From
LSLukas Straub <lukasstraub2@web.de>
Date
Aug 19, 2020, 16:43 UTC
Message-ID
<b673d675eef04b9cc9b7459c066856dcea7b6eea.1597853634.git.lukasstraub2@web.de>
In-Reply-To
<cover.1597853634.git.lukasstraub2@web.de>
Prevent adding .git/.gitmodules only in the root of the repository.

This allows adding .git files and directories as long as they are not in the root.

Signed-off-by: Lukas Straub <lukasstraub2@web.de>
---
 dir.c        |  3 ++-
 read-cache.c | 59 +++++++++++++++++++++++++++++++---------------------
 2 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/dir.c b/dir.c
index fe64be30ed..a959885f50 100644
--- a/dir.c
+++ b/dir.c
@@ -2145,7 +2145,8 @@ static enum path_treatment treat_path(struct dir_struct *dir,
 	if (!cdir->d_name)
 		return treat_path_fast(dir, untracked, cdir, istate, path,
 				       baselen, pathspec);
-	if (is_dot_or_dotdot(cdir->d_name) || !fspathcmp(cdir->d_name, ".git"))
+	if (is_dot_or_dotdot(cdir->d_name) ||
+	    (path->len == 0 && !fspathcmp(cdir->d_name, ".git")))
 		return path_none;
 	strbuf_setlen(path, baselen);
 	strbuf_addstr(path, cdir->d_name);
diff --git a/read-cache.c b/read-cache.c
index 8ed1c29b54..7fb25c23d5 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -906,12 +906,7 @@ int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)
 }
 
 /*
- * We fundamentally don't like some paths: we don't want
- * dot or dot-dot anywhere, and for obvious reasons don't
- * want to recurse into ".git" either.
- *
- * Also, we don't want double slashes or slashes at the
- * end that can make pathnames ambiguous.
+ * We don't want dot or dot-dot anywhere
  */
 static int verify_dotfile(const char *rest, unsigned mode)
 {
@@ -922,10 +917,24 @@ static int verify_dotfile(const char *rest, unsigned mode)
 	 */
 
 	/* "." is not allowed */
-	if (*rest == '\0' || is_dir_sep(*rest))
+	if (rest[0] == '\0' || is_dir_sep(rest[0]))
+		return 0;
+
+	/* ".." is not allowed */
+	if (rest[0] == '.' && (rest[1] == '\0' || is_dir_sep(rest[1])))
 		return 0;
 
-	switch (*rest) {
+	return 1;
+}
+
+static int verify_dotgit(const char *rest, unsigned mode)
+{
+	/*
+	 * The first character was '.', but that
+	 * has already been discarded, we now test
+	 * the rest.
+	 */
+
 	/*
 	 * ".git" followed by NUL or slash is bad. Note that we match
 	 * case-insensitively here, even if ignore_case is not set.
@@ -935,12 +944,11 @@ static int verify_dotfile(const char *rest, unsigned mode)
 	 * Once we've seen ".git", we can also find ".gitmodules", etc (also
 	 * case-insensitively).
 	 */
-	case 'g':
-	case 'G':
+	if (rest[0] == 'g' || rest[0] == 'G') {
 		if (rest[1] != 'i' && rest[1] != 'I')
-			break;
+			return 1;
 		if (rest[2] != 't' && rest[2] != 'T')
-			break;
+			return 1;
 		if (rest[3] == '\0' || is_dir_sep(rest[3]))
 			return 0;
 		if (S_ISLNK(mode)) {
@@ -949,17 +957,16 @@ static int verify_dotfile(const char *rest, unsigned mode)
 			    (*rest == '\0' || is_dir_sep(*rest)))
 				return 0;
 		}
-		break;
-	case '.':
-		if (rest[1] == '\0' || is_dir_sep(rest[1]))
-			return 0;
 	}
+
 	return 1;
 }
 
 int verify_path(const char *path, unsigned mode)
 {
+	const char *orig_path = path;
 	char c = 0;
+	#define is_root(len) ((len) == 0)
 
 	if (has_dos_drive_prefix(path))
 		return 0;
@@ -973,8 +980,7 @@ int verify_path(const char *path, unsigned mode)
 			return 1;
 		if (is_dir_sep(c)) {
 inside:
-			if (protect_hfs) {
-
+			if (protect_hfs && is_root(path - orig_path)) {
 				if (is_hfs_dotgit(path))
 					return 0;
 				if (S_ISLNK(mode)) {
@@ -982,11 +988,7 @@ int verify_path(const char *path, unsigned mode)
 						return 0;
 				}
 			}
-			if (protect_ntfs) {
-#ifdef GIT_WINDOWS_NATIVE
-				if (c == '\\')
-					return 0;
-#endif
+			if (protect_ntfs && is_root(path - orig_path)) {
 				if (is_ntfs_dotgit(path))
 					return 0;
 				if (S_ISLNK(mode)) {
@@ -995,11 +997,20 @@ int verify_path(const char *path, unsigned mode)
 				}
 			}
 
+#ifdef GIT_WINDOWS_NATIVE
+			if (protect_ntfs && c == '\\')
+				return 0;
+#endif
+
 			c = *path++;
 			if ((c == '.' && !verify_dotfile(path, mode)) ||
 			    is_dir_sep(c) || c == '\0')
 				return 0;
-		} else if (c == '\\' && protect_ntfs) {
+			if (c == '.' && is_root(path - orig_path -1) &&
+			    !verify_dotgit(path, mode))
+				return 0;
+		} else if (c == '\\' && protect_ntfs &&
+			   is_root(path - orig_path)) {
 			if (is_ntfs_dotgit(path))
 				return 0;
 			if (S_ISLNK(mode)) {
-- 
2.28.0.217.ge805fe7219
Previous: Lukas StraubNext: Junio C Hamano
Message 3 of 27 in “Allow adding .git files and directories”
  1. 0/2 Allow adding .git files and directoriesLukas Straub, Aug 19, 2020
  2. 2/2 dir: Recurse into nested git repos if they aren't submodulesLukas Straub, Aug 19, 2020
  3. 1/2 dir/read-cache: Allow adding .git files and directoriesLukas Straub, Aug 19, 2020
  4. Junio C HamanoAug 19, 2020
  5. Randall S. BeckerAug 19, 2020
  6. Junio C HamanoAug 19, 2020
  7. Randall S. BeckerAug 19, 2020
  8. Jeff KingAug 19, 2020
  9. Junio C HamanoAug 19, 2020
  10. Jeff KingAug 19, 2020
  11. Randall S. BeckerAug 19, 2020
  12. Johannes SchindelinAug 20, 2020
  13. Lukas StraubAug 20, 2020
  14. Jeff KingAug 20, 2020
  15. Lukas StraubAug 21, 2020
  16. Randall S. BeckerAug 21, 2020
  17. brian m. carlsonAug 21, 2020
  18. Lukas StraubAug 22, 2020
  19. brian m. carlsonAug 22, 2020
  20. Lukas StraubAug 22, 2020
  21. Johannes SchindelinAug 24, 2020
  22. Lukas StraubAug 20, 2020
  23. Jeff KingAug 20, 2020
  24. Lukas StraubAug 19, 2020
  25. Lukas StraubAug 19, 2020
  26. Randall S. BeckerAug 19, 2020
  27. Lukas StraubAug 20, 2020

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.