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

[PATCH 05/11] has_dir_name(): make code more obvious

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
May 15, 2025, 13:11 UTC
Message-ID
<80422a5770ded04993c73c657b363ddad45e2f4a.1747314709.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1891.git.1747314709.gitgitgadget@gmail.com>
From: Johannes Schindelin <johannes.schindelin@gmx.de>

One thing that might be non-obvious to readers (or to analyzers like CodeQL) is that the function essentially does nothing when the Git index is empty, and in particular that it does not look at the value of `len_eq_last` (which would be uninitialized at that point).

Let's make this much easier to understand, by returning early if the Git index is empty, and by avoiding empty `else` blocks.

This commit changes indentation and is hence best viewed using `--ignore-space-change`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 read-cache.c | 55 +++++++++++++---------------------------------------
 1 file changed, 13 insertions(+), 42 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index 73f83a7e7a11..c0bb760ad473 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1117,48 +1117,19 @@ static int has_dir_name(struct index_state *istate,
 	 *
 	 * Compare the entry's full path with the last path in the index.
 	 */
-	if (istate->cache_nr > 0) {
-		cmp_last = strcmp_offset(name,
-			istate->cache[istate->cache_nr - 1]->name,
-			&len_eq_last);
-		if (cmp_last > 0) {
-			if (name[len_eq_last] != '/') {
-				/*
-				 * The entry sorts AFTER the last one in the
-				 * index.
-				 *
-				 * If there were a conflict with "file", then our
-				 * name would start with "file/" and the last index
-				 * entry would start with "file" but not "file/".
-				 *
-				 * The next character after common prefix is
-				 * not '/', so there can be no conflict.
-				 */
-				return retval;
-			} else {
-				/*
-				 * The entry sorts AFTER the last one in the
-				 * index, and the next character after common
-				 * prefix is '/'.
-				 *
-				 * Either the last index entry is a file in
-				 * conflict with this entry, or it has a name
-				 * which sorts between this entry and the
-				 * potential conflicting file.
-				 *
-				 * In both cases, we fall through to the loop
-				 * below and let the regular search code handle it.
-				 */
-			}
-		} else if (cmp_last == 0) {
-			/*
-			 * The entry exactly matches the last one in the
-			 * index, but because of multiple stage and CE_REMOVE
-			 * items, we fall through and let the regular search
-			 * code handle it.
-			 */
-		}
-	}
+	if (!istate->cache_nr)
+		return 0;
+
+	cmp_last = strcmp_offset(name,
+				 istate->cache[istate->cache_nr - 1]->name,
+				 &len_eq_last);
+	if (cmp_last > 0 && name[len_eq_last] != '/')
+		/*
+		 * The entry sorts AFTER the last one in the
+		 * index and their paths have no common prefix,
+		 * so there cannot be a F/D conflict.
+		 */
+		return 0;
 
 	for (;;) {
 		size_t len;
-- 
gitgitgadget
Previous: Jeff KingNext: Jeff King
Message 9 of 36 in “CodeQL-inspired fixes”
  1. 00/11 CodeQL-inspired fixesJohannes Schindelin via GitGitGadget, May 15, 2025
  2. 02/11 fetch: carefully clear local variable's address after useJohannes Schindelin via GitGitGadget, May 15, 2025
  3. Jeff KingMay 15, 2025
  4. 03/11 commit-graph: avoid malloc'ing a local variableJohannes Schindelin via GitGitGadget, May 15, 2025
  5. Jeff KingMay 15, 2025
  6. Junio C HamanoMay 15, 2025
  7. 04/11 upload-pack: rename `enum` to reflect the operationJohannes Schindelin via GitGitGadget, May 15, 2025
  8. Jeff KingMay 15, 2025
  9. 05/11 has_dir_name(): make code more obviousJohannes Schindelin via GitGitGadget, May 15, 2025
  10. Jeff KingMay 15, 2025
  11. 06/11 fetch: avoid unnecessary work when there is no current branchJohannes Schindelin via GitGitGadget, May 15, 2025
  12. Jeff KingMay 15, 2025
  13. 07/11 Avoid redundant conditionsJohannes Schindelin via GitGitGadget, May 15, 2025
  14. Jeff KingMay 15, 2025
  15. 08/11 trace2: avoid "futile conditional"Johannes Schindelin via GitGitGadget, May 15, 2025
  16. Jeff KingMay 15, 2025
  17. 09/11 commit-graph: avoid using stale stack addressesJohannes Schindelin via GitGitGadget, May 15, 2025
  18. Jeff KingMay 15, 2025
  19. 10/11 bundle-uri: avoid using undefined output of `sscanf()`Johannes Schindelin via GitGitGadget, May 15, 2025
  20. Junio C HamanoMay 15, 2025
  21. Jeff KingMay 15, 2025
  22. Phillip WoodMay 16, 2025
  23. Phillip WoodMay 16, 2025
  24. Jeff KingMay 16, 2025
  25. Phillip WoodMay 19, 2025
  26. Jeff KingMay 22, 2025
  27. 11/11 sequencer: stop pretending that an assignment is a conditionJohannes Schindelin via GitGitGadget, May 15, 2025
  28. Junio C HamanoMay 15, 2025
  29. Jeff KingMay 15, 2025
  30. Phillip WoodMay 16, 2025
  31. 01/11 commit: simplify codeJohannes Schindelin via GitGitGadget, May 15, 2025
  32. Jeff KingMay 15, 2025
  33. Junio C HamanoMay 15, 2025
  34. Jeff KingMay 15, 2025
  35. Jeff KingMay 15, 2025
  36. Junio C HamanoMay 15, 2025

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.