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

[PATCH] builtin clone: support bundles

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Mar 2, 2008, 07:46 UTC
Message-ID
<alpine.LSU.1.00.0803020743170.22527@racer.site>
In-Reply-To
<alpine.LSU.1.00.0803020622190.22527@racer.site>

This forward-ports c6fef0bb(clone: support cloning full bundles) to the builtin clone.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
	Now my private tree passes all tests again.
	Daniel, do you have a branch where you have your current version 
	of builting clone?  Mine is in "my-next" of 
	http://repo.or.cz/w/git/dscho.git.
 builtin-clone.c |   59 ++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/builtin-clone.c b/builtin-clone.c
index f27d205..29cd09d 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -64,42 +64,52 @@ static struct option builtin_clone_options[] = {
 	OPT_END()
 };
 
-static char *get_repo_path(const char *repo)
+static char *get_repo_path(const char *repo, int *is_bundle)
 {
-	const char *path;
-	struct stat buf;
-
-	path = mkpath("%s/.git", repo);
-	if (!stat(path, &buf) && S_ISDIR(buf.st_mode))
-		return xstrdup(make_absolute_path(path));
-
-	path = mkpath("%s.git", repo);
-	if (!stat(path, &buf) && S_ISDIR(buf.st_mode))
-		return xstrdup(make_absolute_path(path));
+	static char *suffix[] = { "/.git", ".git", "" };
+	static char *bundle_suffix[] = { ".bundle", "" };
+	struct stat st;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(suffix); i++) {
+		const char *path;
+		path = mkpath("%s%s", repo, suffix[i]);
+		if (!stat(path, &st) && S_ISDIR(st.st_mode)) {
+			*is_bundle = 0;
+			return xstrdup(make_absolute_path(path));
+		}
+	}
 
-	if (!stat(repo, &buf) && S_ISDIR(buf.st_mode))
-		return xstrdup(make_absolute_path(repo));
+	for (i = 0; i < ARRAY_SIZE(bundle_suffix); i++) {
+		const char *path;
+		path = mkpath("%s%s", repo, bundle_suffix[i]);
+		if (!stat(path, &st) && S_ISREG(st.st_mode)) {
+			*is_bundle = 1;
+			return xstrdup(make_absolute_path(path));
+		}
+	}
 
 	return NULL;
 }
 
-static char *guess_dir_name(const char *repo)
+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', strip leading '.*[/:]'. */
+	 * 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++) {
-		if (!prefixcmp(p, ".git")) {
+		const char *prefix = is_bundle ? ".bundle" : ".git";
+		if (!prefixcmp(p, prefix)) {
 			if (!after_slash_or_colon)
 				end = p;
-			p += 3;
+			p += strlen(prefix) - 1;
 		} else if (*p == '/' || *p == ':') {
 			if (end == limit)
 				end = p;
@@ -287,7 +297,7 @@ walk_objects(char *src, char *dest)
 }
 
 static const struct ref *
-clone_local(const char *src_repo, const char *dest_repo)
+clone_local(const char *src_repo, const char *dest_repo, int is_bundle)
 {
 	const struct ref *ret;
 	char src[PATH_MAX];
@@ -295,7 +305,9 @@ clone_local(const char *src_repo, const char *dest_repo)
 	struct remote *remote;
 	struct transport *transport;
 
-	if (option_shared) {
+	if (is_bundle)
+		; /* do nothing */
+	else if (option_shared) {
 		write_alternates_file(dest_repo, src_repo);
 	} else {
 		snprintf(src, PATH_MAX, "%s/objects", src_repo);
@@ -307,6 +319,8 @@ clone_local(const char *src_repo, const char *dest_repo)
 	remote = remote_get(src_repo);
 	transport = transport_get(remote, src_repo);
 	ret = transport_get_remote_refs(transport);
+	if (is_bundle && transport_fetch_refs(transport, (struct ref *)ret))
+		die ("Could not read bundle");
 	transport_disconnect(transport);
 	return ret;
 }
@@ -339,6 +353,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 {
 	int use_local_hardlinks = 1;
 	int use_separate_remote = 1;
+	int is_bundle;
 	struct stat buf;
 	const char *repo, *work_tree, *git_dir;
 	char *path, *dir, *head, *ref_temp;
@@ -369,12 +384,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		option_origin = "origin";
 
 	repo = argv[0];
-	path = get_repo_path(repo);
+	path = get_repo_path(repo, &is_bundle);
 
 	if (argc == 2) {
 		dir = xstrdup(argv[1]);
 	} else {
-		dir = guess_dir_name(repo);
+		dir = guess_dir_name(repo, is_bundle);
 	}
 
 	if (!stat(dir, &buf))
@@ -429,7 +444,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		git_config_set("core.bare", "true");
 
 	if (path != NULL) {
-		refs = clone_local(path, git_dir);
+		refs = clone_local(path, git_dir, is_bundle);
 		repo = make_absolute_path(path);
 	} else {
 		struct remote *remote = remote_get(argv[0]);
-- 
1.5.4.3.446.gbe8932
Previous: Johannes SchindelinNext: Daniel Barkalow
Message 27 of 47 in “[RFC] Build in clone”
  1. Daniel BarkalowFeb 25, 2008
  2. Johan HerlandFeb 26, 2008
  3. Johannes SchindelinFeb 26, 2008
  4. Johan HerlandFeb 26, 2008
  5. Johan HerlandFeb 26, 2008
  6. Johan HerlandFeb 26, 2008
  7. Fix premature free of ref_lists while writing temporary refs to fileJohan Herland, Feb 26, 2008
  8. Johannes SchindelinFeb 26, 2008
  9. Johan HerlandFeb 26, 2008
  10. Daniel BarkalowFeb 26, 2008
  11. Johan HerlandFeb 26, 2008
  12. Fix premature call to git_config() causing t1020-subdirectory to failJohan Herland, Feb 26, 2008
  13. Johannes SchindelinFeb 26, 2008
  14. Daniel BarkalowFeb 26, 2008
  15. Johannes SchindelinFeb 26, 2008
  16. Daniel BarkalowFeb 26, 2008
  17. Junio C HamanoFeb 27, 2008
  18. Daniel BarkalowFeb 27, 2008
  19. Junio C HamanoFeb 27, 2008
  20. Daniel BarkalowFeb 27, 2008
  21. Junio C HamanoFeb 27, 2008
  22. Daniel BarkalowFeb 27, 2008
  23. Daniel BarkalowFeb 26, 2008
  24. Kristian HøgsbergFeb 26, 2008
  25. builtin-clone: create remotes/origin/HEAD symref, if guessedJohannes Schindelin, Mar 2, 2008
  26. builtin-clone: create remotes/origin/HEAD symref, if guessedJohannes Schindelin, Mar 2, 2008
  27. builtin clone: support bundlesJohannes Schindelin, Mar 2, 2008
  28. Daniel BarkalowMar 2, 2008
  29. Santi BéjarMar 3, 2008
  30. Daniel BarkalowMar 2, 2008
  31. Johannes SchindelinMar 2, 2008
  32. Junio C HamanoMar 2, 2008
  33. Junio C HamanoMar 2, 2008
  34. Add test for cloning with "--reference" repo being a subset of source repoJohan Herland, Mar 3, 2008
  35. Daniel BarkalowMar 3, 2008
  36. Daniel BarkalowMar 3, 2008
  37. Johan HerlandMar 4, 2008
  38. 1/2 Add test illustrating issues with sha1_file_name() and switching reposJohan Herland, Mar 4, 2008
  39. 2/2 Overly simplistic fix for issue with sha1_file_name() and switching reposJohan Herland, Mar 4, 2008
  40. Daniel BarkalowMar 4, 2008
  41. Daniel BarkalowMar 5, 2008
  42. Johan HerlandMar 5, 2008
  43. Kristian HøgsbergMar 3, 2008
  44. Pierre HabouzitMar 3, 2008
  45. Johannes SchindelinMar 3, 2008
  46. Johannes SchindelinMar 3, 2008
  47. Johan HerlandMar 3, 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.