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

[GSoC] [PATCH v3 4/8] dir: libify and export helper functions from clone.c

From
Atharva Raykar <raykar.ath@gmail.com>
Date
Aug 6, 2021, 12:01 UTC
Message-ID
<20210806120147.73349-5-raykar.ath@gmail.com>
In-Reply-To
<20210806120147.73349-1-raykar.ath@gmail.com>

These functions can be useful to other parts of Git. Let's move them to dir.c, while renaming them to be make their functionality more explicit.

Signed-off-by: Atharva Raykar <raykar.ath@gmail.com>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Shourya Shukla <periperidip@gmail.com>
---
 builtin/clone.c | 118 +-----------------------------------------------
 dir.c           | 114 ++++++++++++++++++++++++++++++++++++++++++++++
 dir.h           |  11 +++++
 3 files changed, 127 insertions(+), 116 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 66fe66679c..fab0a3cef6 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -217,120 +217,6 @@ static char *get_repo_path(const char *repo, int *is_bundle)
 	return canon;
 }
 
-static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
-{
-	const char *end = repo + strlen(repo), *start, *ptr;
-	size_t len;
-	char *dir;
-
-	/*
-	 * Skip scheme.
-	 */
-	start = strstr(repo, "://");
-	if (start == NULL)
-		start = repo;
-	else
-		start += 3;
-
-	/*
-	 * Skip authentication data. The stripping does happen
-	 * greedily, such that we strip up to the last '@' inside
-	 * the host part.
-	 */
-	for (ptr = start; ptr < end && !is_dir_sep(*ptr); ptr++) {
-		if (*ptr == '@')
-			start = ptr + 1;
-	}
-
-	/*
-	 * Strip trailing spaces, slashes and /.git
-	 */
-	while (start < end && (is_dir_sep(end[-1]) || isspace(end[-1])))
-		end--;
-	if (end - start > 5 && is_dir_sep(end[-5]) &&
-	    !strncmp(end - 4, ".git", 4)) {
-		end -= 5;
-		while (start < end && is_dir_sep(end[-1]))
-			end--;
-	}
-
-	/*
-	 * Strip trailing port number if we've got only a
-	 * hostname (that is, there is no dir separator but a
-	 * colon). This check is required such that we do not
-	 * strip URI's like '/foo/bar:2222.git', which should
-	 * result in a dir '2222' being guessed due to backwards
-	 * compatibility.
-	 */
-	if (memchr(start, '/', end - start) == NULL
-	    && memchr(start, ':', end - start) != NULL) {
-		ptr = end;
-		while (start < ptr && isdigit(ptr[-1]) && ptr[-1] != ':')
-			ptr--;
-		if (start < ptr && ptr[-1] == ':')
-			end = ptr - 1;
-	}
-
-	/*
-	 * Find last component. To remain backwards compatible we
-	 * also regard colons as path separators, such that
-	 * cloning a repository 'foo:bar.git' would result in a
-	 * directory 'bar' being guessed.
-	 */
-	ptr = end;
-	while (start < ptr && !is_dir_sep(ptr[-1]) && ptr[-1] != ':')
-		ptr--;
-	start = ptr;
-
-	/*
-	 * Strip .{bundle,git}.
-	 */
-	len = end - start;
-	strip_suffix_mem(start, &len, is_bundle ? ".bundle" : ".git");
-
-	if (!len || (len == 1 && *start == '/'))
-		die(_("No directory name could be guessed.\n"
-		      "Please specify a directory on the command line"));
-
-	if (is_bare)
-		dir = xstrfmt("%.*s.git", (int)len, start);
-	else
-		dir = xstrndup(start, len);
-	/*
-	 * Replace sequences of 'control' characters and whitespace
-	 * with one ascii space, remove leading and trailing spaces.
-	 */
-	if (*dir) {
-		char *out = dir;
-		int prev_space = 1 /* strip leading whitespace */;
-		for (end = dir; *end; ++end) {
-			char ch = *end;
-			if ((unsigned char)ch < '\x20')
-				ch = '\x20';
-			if (isspace(ch)) {
-				if (prev_space)
-					continue;
-				prev_space = 1;
-			} else
-				prev_space = 0;
-			*out++ = ch;
-		}
-		*out = '\0';
-		if (out > dir && prev_space)
-			out[-1] = '\0';
-	}
-	return dir;
-}
-
-static void strip_trailing_slashes(char *dir)
-{
-	char *end = dir + strlen(dir);
-
-	while (dir < end - 1 && is_dir_sep(end[-1]))
-		end--;
-	*end = '\0';
-}
-
 static int add_one_reference(struct string_list_item *item, void *cb_data)
 {
 	struct strbuf err = STRBUF_INIT;
@@ -1041,8 +927,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (argc == 2)
 		dir = xstrdup(argv[1]);
 	else
-		dir = guess_dir_name(repo_name, is_bundle, option_bare);
-	strip_trailing_slashes(dir);
+		dir = guess_target_dir_from_git_url(repo_name, is_bundle, option_bare);
+	strip_dir_trailing_slashes(dir);
 
 	dest_exists = path_exists(dir);
 	if (dest_exists && !is_empty_dir(dir))
diff --git a/dir.c b/dir.c
index 03c4d21267..9a9ab135c4 100644
--- a/dir.c
+++ b/dir.c
@@ -2970,6 +2970,120 @@ int is_empty_dir(const char *path)
 	return ret;
 }
 
+char *guess_target_dir_from_git_url(const char *repo, int is_bundle, int is_bare)
+{
+	const char *end = repo + strlen(repo), *start, *ptr;
+	size_t len;
+	char *dir;
+
+	/*
+	 * Skip scheme.
+	 */
+	start = strstr(repo, "://");
+	if (start == NULL)
+		start = repo;
+	else
+		start += 3;
+
+	/*
+	 * Skip authentication data. The stripping does happen
+	 * greedily, such that we strip up to the last '@' inside
+	 * the host part.
+	 */
+	for (ptr = start; ptr < end && !is_dir_sep(*ptr); ptr++) {
+		if (*ptr == '@')
+			start = ptr + 1;
+	}
+
+	/*
+	 * Strip trailing spaces, slashes and /.git
+	 */
+	while (start < end && (is_dir_sep(end[-1]) || isspace(end[-1])))
+		end--;
+	if (end - start > 5 && is_dir_sep(end[-5]) &&
+	    !strncmp(end - 4, ".git", 4)) {
+		end -= 5;
+		while (start < end && is_dir_sep(end[-1]))
+			end--;
+	}
+
+	/*
+	 * Strip trailing port number if we've got only a
+	 * hostname (that is, there is no dir separator but a
+	 * colon). This check is required such that we do not
+	 * strip URI's like '/foo/bar:2222.git', which should
+	 * result in a dir '2222' being guessed due to backwards
+	 * compatibility.
+	 */
+	if (memchr(start, '/', end - start) == NULL
+	    && memchr(start, ':', end - start) != NULL) {
+		ptr = end;
+		while (start < ptr && isdigit(ptr[-1]) && ptr[-1] != ':')
+			ptr--;
+		if (start < ptr && ptr[-1] == ':')
+			end = ptr - 1;
+	}
+
+	/*
+	 * Find last component. To remain backwards compatible we
+	 * also regard colons as path separators, such that
+	 * cloning a repository 'foo:bar.git' would result in a
+	 * directory 'bar' being guessed.
+	 */
+	ptr = end;
+	while (start < ptr && !is_dir_sep(ptr[-1]) && ptr[-1] != ':')
+		ptr--;
+	start = ptr;
+
+	/*
+	 * Strip .{bundle,git}.
+	 */
+	len = end - start;
+	strip_suffix_mem(start, &len, is_bundle ? ".bundle" : ".git");
+
+	if (!len || (len == 1 && *start == '/'))
+		die(_("No directory name could be guessed.\n"
+		      "Please specify a directory on the command line"));
+
+	if (is_bare)
+		dir = xstrfmt("%.*s.git", (int)len, start);
+	else
+		dir = xstrndup(start, len);
+	/*
+	 * Replace sequences of 'control' characters and whitespace
+	 * with one ascii space, remove leading and trailing spaces.
+	 */
+	if (*dir) {
+		char *out = dir;
+		int prev_space = 1 /* strip leading whitespace */;
+		for (end = dir; *end; ++end) {
+			char ch = *end;
+			if ((unsigned char)ch < '\x20')
+				ch = '\x20';
+			if (isspace(ch)) {
+				if (prev_space)
+					continue;
+				prev_space = 1;
+			} else
+				prev_space = 0;
+			*out++ = ch;
+		}
+		*out = '\0';
+		if (out > dir && prev_space)
+			out[-1] = '\0';
+	}
+	return dir;
+}
+
+void strip_dir_trailing_slashes(char *dir)
+{
+	char *end = dir + strlen(dir);
+
+	while (dir < end - 1 && is_dir_sep(end[-1]))
+		end--;
+	*end = '\0';
+}
+
 static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
 {
 	DIR *dir;
diff --git a/dir.h b/dir.h
index b3e1a54a97..6f0abdfe04 100644
--- a/dir.h
+++ b/dir.h
@@ -453,6 +453,17 @@ static inline int is_dot_or_dotdot(const char *name)
 
 int is_empty_dir(const char *dir);
 
+/*
+ * Retrieve a target directory name by reading "humanish" part of the
+ * given Git URL.
+ *
+ * For example:
+ * 	/path/to/repo.git => "repo"
+ * 	host.xz.foo/.git => "foo"
+ */
+char *guess_target_dir_from_git_url(const char *repo, int is_bundle, int is_bare);
+void strip_dir_trailing_slashes(char *dir);
+
 void setup_standard_excludes(struct dir_struct *dir);
 
 char *get_sparse_checkout_filename(void);
-- 
2.32.0
Previous: Atharva RaykarNext: Atharva Raykar
Message 39 of 78 in “submodule: convert the rest of 'add' to C”
  1. Atharva RaykarAug 5, 2021
  2. [GSoC] [PATCH 1/8] submodule--helper: refactor resolve_relative_url() helperAtharva Raykar, Aug 5, 2021
  3. [GSoC] [PATCH 2/8] submodule--helper: remove repeated code in sync_submodule()Atharva Raykar, Aug 5, 2021
  4. Đoàn Trần Công DanhAug 6, 2021
  5. Christian CouderAug 6, 2021
  6. Atharva RaykarAug 6, 2021
  7. Junio C HamanoAug 6, 2021
  8. [GSoC] [PATCH 3/8] dir: libify and export helper functions from clone.cAtharva Raykar, Aug 5, 2021
  9. [GSoC] [PATCH 4/8] submodule--helper: remove constness of sm_pathAtharva Raykar, Aug 5, 2021
  10. [GSoC] [PATCH 5/8] submodule--helper: convert the bulk of cmd_add() to CAtharva Raykar, Aug 5, 2021
  11. [GSoC] [PATCH 6/8] submodule--helper: remove add-clone subcommandAtharva Raykar, Aug 5, 2021
  12. [GSoC] [PATCH 8/8] submodule--helper: remove resolve-relative-url subcommandAtharva Raykar, Aug 5, 2021
  13. [GSoC] [PATCH 7/8] submodule--helper: remove add-config subcommandAtharva Raykar, Aug 5, 2021
  14. [GSoC] [PATCH v2 0/9] submodule: convert the rest of 'add' to CAtharva Raykar, Aug 5, 2021
  15. [GSoC] [PATCH v2 1/9] submodule--helper: add options for compute_submodule_clone_url()Atharva Raykar, Aug 5, 2021
  16. Junio C HamanoAug 5, 2021
  17. [GSoC] [PATCH v2 2/9] submodule--helper: refactor resolve_relative_url() helperAtharva Raykar, Aug 5, 2021
  18. Junio C HamanoAug 5, 2021
  19. [GSoC] [PATCH v2 3/9] submodule--helper: remove repeated code in sync_submodule()Atharva Raykar, Aug 5, 2021
  20. Junio C HamanoAug 5, 2021
  21. [GSoC] [PATCH v2 4/9] dir: libify and export helper functions from clone.cAtharva Raykar, Aug 5, 2021
  22. Junio C HamanoAug 5, 2021
  23. Atharva RaykarAug 6, 2021
  24. Junio C HamanoAug 6, 2021
  25. Atharva RaykarAug 7, 2021
  26. [GSoC] [PATCH v2 5/9] submodule--helper: remove constness of sm_pathAtharva Raykar, Aug 5, 2021
  27. Junio C HamanoAug 5, 2021
  28. Atharva RaykarAug 6, 2021
  29. [GSoC] [PATCH v2 6/9] submodule--helper: convert the bulk of cmd_add() to CAtharva Raykar, Aug 5, 2021
  30. Đoàn Trần Công DanhAug 6, 2021
  31. Atharva RaykarAug 6, 2021
  32. [GSoC] [PATCH v2 7/9] submodule--helper: remove add-clone subcommandAtharva Raykar, Aug 5, 2021
  33. [GSoC] [PATCH v2 8/9] submodule--helper: remove add-config subcommandAtharva Raykar, Aug 5, 2021
  34. [GSoC] [PATCH v2 9/9] submodule--helper: remove resolve-relative-url subcommandAtharva Raykar, Aug 5, 2021
  35. [GSoC] [PATCH v3 0/8] submodule: convert the rest of 'add' to CAtharva Raykar, Aug 6, 2021
  36. [GSoC] [PATCH v3 1/8] submodule--helper: add options for compute_submodule_clone_url()Atharva Raykar, Aug 6, 2021
  37. [GSoC] [PATCH v3 2/8] submodule--helper: refactor resolve_relative_url() helperAtharva Raykar, Aug 6, 2021
  38. [GSoC] [PATCH v3 3/8] submodule--helper: remove repeated code in sync_submodule()Atharva Raykar, Aug 6, 2021
  39. [GSoC] [PATCH v3 4/8] dir: libify and export helper functions from clone.cAtharva Raykar, Aug 6, 2021
  40. [GSoC] [PATCH v3 5/8] submodule--helper: convert the bulk of cmd_add() to CAtharva Raykar, Aug 6, 2021
  41. [GSoC] [PATCH v3 6/8] submodule--helper: remove add-clone subcommandAtharva Raykar, Aug 6, 2021
  42. [GSoC] [PATCH v3 7/8] submodule--helper: remove add-config subcommandAtharva Raykar, Aug 6, 2021
  43. [GSoC] [PATCH v3 8/8] submodule--helper: remove resolve-relative-url subcommandAtharva Raykar, Aug 6, 2021
  44. [GSoC] [PATCH v4 0/8] submodule: convert the rest of 'add' to CAtharva Raykar, Aug 7, 2021
  45. [GSoC] [PATCH v4 1/8] submodule--helper: add options for compute_submodule_clone_url()Atharva Raykar, Aug 7, 2021
  46. Kaartic SivaraamAug 8, 2021
  47. Kaartic SivaraamAug 8, 2021
  48. Atharva RaykarAug 9, 2021
  49. Atharva RaykarAug 9, 2021
  50. Kaartic SivaraamAug 10, 2021
  51. [GSoC] [PATCH v4 2/8] submodule--helper: refactor resolve_relative_url() helperAtharva Raykar, Aug 7, 2021
  52. [GSoC] [PATCH v4 3/8] submodule--helper: remove repeated code in sync_submodule()Atharva Raykar, Aug 7, 2021
  53. Kaartic SivaraamAug 8, 2021
  54. Atharva RaykarAug 9, 2021
  55. [GSoC] [PATCH v4 4/8] dir: libify and export helper functions from clone.cAtharva Raykar, Aug 7, 2021
  56. Kaartic SivaraamAug 8, 2021
  57. Atharva RaykarAug 9, 2021
  58. Kaartic SivaraamAug 10, 2021
  59. Junio C HamanoAug 10, 2021
  60. Atharva RaykarAug 11, 2021
  61. [GSoC] [PATCH v4 5/8] submodule--helper: convert the bulk of cmd_add() to CAtharva Raykar, Aug 7, 2021
  62. [GSoC] [PATCH v4 6/8] submodule--helper: remove add-clone subcommandAtharva Raykar, Aug 7, 2021
  63. [GSoC] [PATCH v4 7/8] submodule--helper: remove add-config subcommandAtharva Raykar, Aug 7, 2021
  64. [GSoC] [PATCH v4 8/8] submodule--helper: remove resolve-relative-url subcommandAtharva Raykar, Aug 7, 2021
  65. Kaartic SivaraamAug 8, 2021
  66. [GSoC] [PATCH v5 0/9] submodule: convert the rest of 'add' to CAtharva Raykar, Aug 10, 2021
  67. [GSoC] [PATCH v5 1/9] submodule--helper: add options for compute_submodule_clone_url()Atharva Raykar, Aug 10, 2021
  68. Bagas SanjayaAug 11, 2021
  69. Atharva RaykarAug 11, 2021
  70. [GSoC] [PATCH v5 3/9] submodule--helper: remove repeated code in sync_submodule()Atharva Raykar, Aug 10, 2021
  71. [GSoC] [PATCH v5 2/9] submodule--helper: refactor resolve_relative_url() helperAtharva Raykar, Aug 10, 2021
  72. [GSoC] [PATCH v5 4/9] dir: libify and export helper functions from clone.cAtharva Raykar, Aug 10, 2021
  73. [GSoC] [PATCH v5 5/9] submodule--helper: convert the bulk of cmd_add() to CAtharva Raykar, Aug 10, 2021
  74. [GSoC] [PATCH v5 6/9] submodule--helper: remove add-clone subcommandAtharva Raykar, Aug 10, 2021
  75. [GSoC] [PATCH v5 9/9] submodule--helper: rename compute_submodule_clone_url()Atharva Raykar, Aug 10, 2021
  76. [GSoC] [PATCH v5 8/9] submodule--helper: remove resolve-relative-url subcommandAtharva Raykar, Aug 10, 2021
  77. [GSoC] [PATCH v5 7/9] submodule--helper: remove add-config subcommandAtharva Raykar, Aug 10, 2021
  78. Junio C HamanoSep 8, 2021

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.