From 9197a10c7188a74356384a7ce46e05104ac68240 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 30 May 2012 07:09:08 -0400 Subject: [PATCH 1/2] docs/clone: mention that --local may be ignored The --local flag is not "treat this like a local repository", but rather "if we are local, turn on optimizations". Therefore it does nothing in the case of: git clone --local file:///path/to/repo Let's make that more clear in the documentation. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 6e22522c4f..1d267f4712 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -46,13 +46,16 @@ OPTIONS mechanism and clones the repository by making a copy of HEAD and everything under objects and refs directories. The files under `.git/objects/` directory are hardlinked - to save space when possible. This is now the default when - the source repository is specified with `/path/to/repo` - syntax, so it essentially is a no-op option. To force - copying instead of hardlinking (which may be desirable - if you are trying to make a back-up of your repository), - but still avoid the usual "git aware" transport - mechanism, `--no-hardlinks` can be used. + to save space when possible. ++ +If the repository is specified as a local path (e.g., `/path/to/repo`), +this is the default, and --local is essentially a no-op. If the +repository is specified as a URL, then this flag is ignored (and we +never use the local optimizations). ++ +To force copying instead of hardlinking (which may be desirable if you +are trying to make a back-up of your repository), but still avoid the +usual "git aware" transport mechanism, `--no-hardlinks` can be used. --no-hardlinks:: Optimize the cloning process from a repository on a From 189260b190be845f0e24ede93f9ac539627d72fa Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 30 May 2012 07:10:16 -0400 Subject: [PATCH 2/2] clone: allow --no-local to turn off local optimizations This is basically the same as using "file://", but is a little less subtle for the end user. It also allows relative paths to be specified. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 4 +++- builtin/clone.c | 10 +++++----- t/t5701-clone-local.sh | 10 ++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 1d267f4712..c1ddd4c2cc 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -51,7 +51,9 @@ OPTIONS If the repository is specified as a local path (e.g., `/path/to/repo`), this is the default, and --local is essentially a no-op. If the repository is specified as a URL, then this flag is ignored (and we -never use the local optimizations). +never use the local optimizations). Specifying `--no-local` will +override the default when `/path/to/repo` is given, using the regular +git transport instead. + To force copying instead of hardlinking (which may be desirable if you are trying to make a back-up of your repository), but still avoid the diff --git a/builtin/clone.c b/builtin/clone.c index a4d8d25ee3..7f3b9823ce 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -38,7 +38,7 @@ static const char * const builtin_clone_usage[] = { }; static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1; -static int option_local, option_no_hardlinks, option_shared, option_recursive; +static int option_local = -1, option_no_hardlinks, option_shared, option_recursive; static char *option_template, *option_depth; static char *option_origin = NULL; static char *option_branch = NULL; @@ -70,8 +70,8 @@ static struct option builtin_clone_options[] = { PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, OPT_BOOLEAN(0, "mirror", &option_mirror, "create a mirror repository (implies bare)"), - OPT_BOOLEAN('l', "local", &option_local, - "to clone from a local repository"), + OPT_BOOL('l', "local", &option_local, + "to clone from a local repository"), OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks, "don't use local hardlinks, always copy"), OPT_BOOLEAN('s', "shared", &option_shared, @@ -342,7 +342,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, if (!option_no_hardlinks) { if (!link(src->buf, dest->buf)) continue; - if (option_local) + if (option_local > 0) die_errno(_("failed to create link '%s'"), dest->buf); option_no_hardlinks = 1; } @@ -668,7 +668,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) die(_("repository '%s' does not exist"), repo_name); else repo = repo_name; - is_local = path && !is_bundle; + is_local = option_local != 0 && path && !is_bundle; if (is_local && option_depth) warning(_("--depth is ignored in local clones; use file:// instead.")); diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh index c6feca44e3..7ff6e0e16c 100755 --- a/t/t5701-clone-local.sh +++ b/t/t5701-clone-local.sh @@ -124,4 +124,14 @@ test_expect_success 'cloning non-git directory fails' ' test_must_fail git clone not-a-git-repo not-a-git-repo-clone ' +test_expect_success 'cloning file:// does not hardlink' ' + git clone --bare file://"$(pwd)"/a non-local && + ! repo_is_hardlinked non-local +' + +test_expect_success 'cloning a local path with --no-local does not hardlink' ' + git clone --bare --no-local a force-nonlocal && + ! repo_is_hardlinked force-nonlocal +' + test_done