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

[PATCH 12/17] clone: support --narrow option

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Sep 5, 2010, 06:47 UTC
Message-ID
<1283669264-15759-13-git-send-email-pclouds@gmail.com>
In-Reply-To
<1283669264-15759-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-clone.txt |   14 +++++++++++++-
 builtin/clone.c             |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index dc7d3d1..d9a5729 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -12,7 +12,8 @@ SYNOPSIS
 'git clone' [--template=<template_directory>]
 	  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
 	  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
-	  [--depth <depth>] [--recursive] [--] <repository> [<directory>]
+	  [--depth <depth>] [--narrow <path>] [--recursive]
+	  [--] <repository> [<directory>]
 
 DESCRIPTION
 -----------
@@ -161,6 +162,17 @@ objects from the source repository into a pack in the cloned repository.
 	with a long history, and would want to send in fixes
 	as patches.
 
+--narrow <path>::
+	Create a 'narrow' clone with all commit trees limited to
+	the given path. A narrow repository has a number of
+	limititations (you cannot clone or fech from it, nor push
+	into it), but is adequate if you are only interested in
+	certain paths of a large repository, and would want to
+	push some fixes.
++
+Multiple --narrow can be given. This option can also be used together
+with --depth to truncate both history and path.
+
 --recursive::
 	After the clone is created, initialize all submodules within,
 	using their default settings. This is equivalent to running
diff --git a/builtin/clone.c b/builtin/clone.c
index efb1e6f..439ce8a 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -23,6 +23,7 @@
 #include "branch.h"
 #include "remote.h"
 #include "run-command.h"
+#include "narrow-tree.h"
 
 /*
  * Overall FIXMEs:
@@ -40,11 +41,15 @@ static const char * const builtin_clone_usage[] = {
 static int option_no_checkout, option_bare, option_mirror;
 static int option_local, option_no_hardlinks, option_shared, option_recursive;
 static char *option_template, *option_reference, *option_depth;
+static const char **option_narrow;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbosity;
 static int option_progress;
+static int narrow_nr;
+
+static int add_narrow_prefix(const struct option *opt, const char *arg, int unset);
 
 static struct option builtin_clone_options[] = {
 	OPT__VERBOSITY(&option_verbosity),
@@ -78,6 +83,8 @@ static struct option builtin_clone_options[] = {
 		   "path to git-upload-pack on the remote"),
 	OPT_STRING(0, "depth", &option_depth, "depth",
 		    "create a shallow clone of that depth"),
+	OPT_CALLBACK(0, "narrow", NULL, "prefix", "narrow clone",
+		     add_narrow_prefix),
 
 	OPT_END()
 };
@@ -86,6 +93,22 @@ static const char *argv_submodule[] = {
 	"submodule", "update", "--init", "--recursive", NULL
 };
 
+static int add_narrow_prefix(const struct option *opt, const char *arg, int unset)
+{
+	if (unset)
+		die("--no-narrow is not supported");
+
+	narrow_nr++;
+	option_narrow = xrealloc(option_narrow, sizeof(*option_narrow)*narrow_nr);
+	option_narrow[narrow_nr-1] = arg;
+	return 0;
+}
+
+static int narrow_cmp(const void *a, const void *b)
+{
+	return strcmp(*(const char**)a, *(const char **)b);
+}
+
 static char *get_repo_path(const char *repo, int *is_bundle)
 {
 	static char *suffix[] = { "/.git", ".git", "" };
@@ -443,6 +466,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		git_dir = xstrdup(mkpath("%s/.git", dir));
 	}
 
+	if (option_narrow) {
+		int i;
+		qsort(option_narrow, narrow_nr, sizeof(*option_narrow), narrow_cmp);
+		for (i = 0; i < narrow_nr; i++)
+			if (!valid_narrow_prefix(option_narrow[i], i ? option_narrow[i-1] : NULL, 0))
+				die("Invalid narrow prefix");
+	}
+
 	if (!option_bare) {
 		junk_work_tree = work_tree;
 		if (safe_create_leading_directories_const(work_tree) < 0)
@@ -515,6 +546,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	strbuf_reset(&value);
 
 	if (path && !is_bundle) {
+		if (option_narrow)
+			die("--narrow is not really for local clone. Please consider --shared");
 		refs = clone_local(path, git_dir);
 		mapped_refs = wanted_peer_refs(refs, refspec);
 	} else {
@@ -530,6 +563,16 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 			transport_set_option(transport, TRANS_OPT_DEPTH,
 					     option_depth);
 
+		/* Do this early in order to set get_narrow_prefix() != NULL */
+		if (option_narrow) {
+			int i;
+			FILE *fp = fopen(git_path("narrow"), "w+");
+			for (i = 0; i < narrow_nr; i++)
+				fprintf(fp, "%s\n", option_narrow[i]);
+			fclose(fp);
+			check_narrow_prefix(); /* Install the prefix */
+		}
+
 		transport_set_verbosity(transport, option_verbosity, option_progress);
 
 		if (option_upload_pack)
-- 
1.7.1.rc1.69.g24c2f7
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 13 of 25 in “Narrow clone v3 (was subtree clone)”
  1. 00/17 Narrow clone v3 (was subtree clone)Nguyễn Thái Ngọc Duy, Sep 5, 2010
  2. 01/17 rev-list: do not do commit simplification if simplify_history = 0Nguyễn Thái Ngọc Duy, Sep 5, 2010
  3. 02/17 tree.c: add path_to_sha1()Nguyễn Thái Ngọc Duy, Sep 5, 2010
  4. 03/17 Introduce $GIT_DIR/narrowNguyễn Thái Ngọc Duy, Sep 5, 2010
  5. 04/17 index: make narrow index incompatible with older gitNguyễn Thái Ngọc Duy, Sep 5, 2010
  6. 05/17 pack-objects: support narrow packs with pathspecsNguyễn Thái Ngọc Duy, Sep 5, 2010
  7. 06/17 {fetch,upload}-pack: support narrow repositoryNguyễn Thái Ngọc Duy, Sep 5, 2010
  8. 07/17 unpack-trees: split traverse_trees() code into a separate functionNguyễn Thái Ngọc Duy, Sep 5, 2010
  9. 08/17 unpack-trees: support unpack trees in narrow repositoryNguyễn Thái Ngọc Duy, Sep 5, 2010
  10. 09/17 cache-tree: only cache tree within narrow areaNguyễn Thái Ngọc Duy, Sep 5, 2010
  11. 10/17 get_pathspec(): support narrow pathspec rewritingNguyễn Thái Ngọc Duy, Sep 5, 2010
  12. 11/17 pathspec retrieval fixNguyễn Thái Ngọc Duy, Sep 5, 2010
  13. 12/17 clone: support --narrow optionNguyễn Thái Ngọc Duy, Sep 5, 2010
  14. 13/17 commit: add narrow's commit_tree versionNguyễn Thái Ngọc Duy, Sep 5, 2010
  15. 14/17 commit: use commit_narrow_tree() to support narrow repoNguyễn Thái Ngọc Duy, Sep 5, 2010
  16. 15/17 write-tree: requires --narrow-base in narrow repositoryNguyễn Thái Ngọc Duy, Sep 5, 2010
  17. 16/17 merge: try to do local merge if possible in narrow repoNguyễn Thái Ngọc Duy, Sep 5, 2010
  18. 17/17 Add narrow clone demonstration testNguyễn Thái Ngọc Duy, Sep 5, 2010
  19. Sverre RabbelierSep 5, 2010
  20. Nguyen Thai Ngoc DuySep 5, 2010
  21. Elijah NewrenSep 5, 2010
  22. Elijah NewrenSep 6, 2010
  23. Nguyen Thai Ngoc DuySep 6, 2010
  24. Sverre RabbelierSep 6, 2010
  25. Elijah NewrenSep 6, 2010

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.