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

Re: [PATCH] builtin-clone: Use is_dir_sep() instead of '/'

From
Johannes Sixt <johannes.sixt@telecom.at>
Date
Jul 19, 2008, 09:32 UTC
Message-ID
<200807191132.45648.johannes.sixt@telecom.at>
In-Reply-To
<7vk5fi67dx.fsf@gitster.siamese.dyndns.org>
On Samstag, 19. Juli 2008, Junio C Hamano wrote:
> Ok, but the surrounding code in this function look very suspicious.
How about this then?

-- snip -- builtin-clone: Rewrite guess_dir_name()

The function has to do three small and independent tasks, but all of them were crammed into a single loop. This rewrites the function entirely by unrolling these tasks.

We also now use is_dir_sep(c) instead of c == '/' to increase portability, which actually was the primary reason to touch this code.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
 builtin-clone.c |   55 ++++++++++++++++++++++++++-----------------------------
 1 files changed, 26 insertions(+), 29 deletions(-)
diff --git a/builtin-clone.c b/builtin-clone.c
index 8112716..91667d5 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -95,35 +95,32 @@ static char *get_repo_path(const char *repo, int *is_bundle)
 
 static char *guess_dir_name(const char *repo, int is_bundle)
 {
-	const char *p, *start, *end, *limit;
-	int after_slash_or_colon;
-
-	/* Guess dir name from repository: strip trailing '/',
-	 * strip trailing '[:/]*.{git,bundle}', strip leading '.*[/:]'. */
-
-	after_slash_or_colon = 1;
-	limit = repo + strlen(repo);
-	start = repo;
-	end = limit;
-	for (p = repo; p < limit; p++) {
-		const char *prefix = is_bundle ? ".bundle" : ".git";
-		if (!prefixcmp(p, prefix)) {
-			if (!after_slash_or_colon)
-				end = p;
-			p += strlen(prefix) - 1;
-		} else if (!prefixcmp(p, ".bundle")) {
-			if (!after_slash_or_colon)
-				end = p;
-			p += 7;
-		} else if (*p == '/' || *p == ':') {
-			if (end == limit)
-				end = p;
-			after_slash_or_colon = 1;
-		} else if (after_slash_or_colon) {
-			start = p;
-			end = limit;
-			after_slash_or_colon = 0;
-		}
+	const char *end = repo + strlen(repo), *start, *dot;
+
+	/*
+	 * Strip trailing slashes
+	 */
+	while (repo < end && is_dir_sep(end[-1]))
+		end--;
+
+	/*
+	 * Find last component, but be prepared that repo could have
+	 * the form  "remote.example.com:foo.git", i.e. no slash
+	 * in the directory part.
+	 */
+	start = end;
+	while (repo < start && !is_dir_sep(start[-1]) && start[-1] != ':')
+		start--;
+
+	/*
+	 * Strip .{bundle,git}.
+	 */
+	if (is_bundle) {
+		if (end - start > 7 && !strcmp(end - 7, ".bundle"))
+			end -= 7;
+	} else {
+		if (end - start > 4 && !strcmp(end - 4, ".git"))
+			end -= 4;
 	}
 
 	return xstrndup(start, end - start);
-- 
1.5.6.3.443.g5f70e
Previous: Junio C HamanoNext: Johannes Schindelin
Message 12 of 16 in “Windows related patches”
  1. Windows related patchesJohannes Sixt, Jul 18, 2008
  2. Teach lookup_prog not to select directoriesJohannes Sixt, Jul 18, 2008
  3. builtin-clone: Use is_dir_sep() instead of '/'Johannes Sixt, Jul 18, 2008
  4. Add ANSI control code emulation for the Windows consoleJohannes Sixt, Jul 18, 2008
  5. Windows: set gitexecdir = $(bindir)Johannes Sixt, Jul 18, 2008
  6. Junio C HamanoJul 19, 2008
  7. Johannes SixtJul 19, 2008
  8. Steffen ProhaskaJul 19, 2008
  9. Junio C HamanoJul 19, 2008
  10. Johannes SixtJul 19, 2008
  11. Junio C HamanoJul 19, 2008
  12. Johannes SixtJul 19, 2008
  13. Johannes SchindelinJul 19, 2008
  14. Johannes SixtJul 19, 2008
  15. Daniel BarkalowJul 19, 2008
  16. Kristian HøgsbergJul 21, 2008

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.