SYNOPSIS
--------
[verse]
-'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
+'git-clone' [--template=<template_directory>]
+ [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare]
[-o <name>] [-u <upload-pack>] [--reference <repository>]
[--depth <depth>] <repository> [<directory>]
this flag bypasses normal "git aware" transport
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.
+ 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.
+
+--no-hardlinks::
+ Optimize the cloning process from a repository on a
+ local filesystem by copying files under `.git/objects`
+ directory.
--shared::
-s::
- ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git
===============================================================
-SSH is the default transport protocol. You can optionally specify
-which user to log-in as, and an alternate, scp-like syntax is also
-supported. Both syntaxes support username expansion,
-as does the native git protocol. The following three are
-identical to the last three above, respectively:
+SSH is the default transport protocol over the network. You can
+optionally specify which user to log-in as, and an alternate,
+scp-like syntax is also supported. Both syntaxes support
+username expansion, as does the native git protocol. The following
+three are identical to the last three above, respectively:
===============================================================
- {startsb}user@{endsb}host.xz:/path/to/repo.git/
- {startsb}user@{endsb}host.xz:path/to/repo.git
===============================================================
-To sync with a local directory, use:
+To sync with a local directory, you can use:
===============================================================
- /path/to/repo.git/
+- file:///path/to/repo.git/
===============================================================
+
+They are mostly equivalent, except when cloning. See
+gitlink:git-clone[1] for details.
quiet=
local=no
-use_local=no
+use_local_hardlink=yes
local_shared=no
unset template
no_checkout=
no_checkout=yes ;;
*,--na|*,--nak|*,--nake|*,--naked|\
*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
- *,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
+ *,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local)
+ use_local_hardlink=yes ;;
+ *,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\
+ *,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks)
+ use_local_hardlink=no ;;
*,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
- local_shared=yes; use_local=yes ;;
+ local_shared=yes; ;;
1,--template) usage ;;
*,--template)
shift; template="--template=$1" ;;
rm -f "$GIT_DIR/CLONE_HEAD"
# We do local magic only when the user tells us to.
-case "$local,$use_local" in
-yes,yes)
+case "$local" in
+yes)
( cd "$repo/objects" ) ||
- die "-l flag seen but repository '$repo' is not local."
+ die "cannot chdir to local '$repo/objects'."
- case "$local_shared" in
- no)
- # See if we can hardlink and drop "l" if not.
- sample_file=$(cd "$repo" && \
- find objects -type f -print | sed -e 1q)
-
- # objects directory should not be empty since we are cloning!
- test -f "$repo/$sample_file" || exit
-
- l=
- if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
- then
- l=l
- fi &&
- rm -f "$GIT_DIR/objects/sample" &&
- cd "$repo" &&
- find objects -depth -print | cpio -pumd$l "$GIT_DIR/" || exit 1
- ;;
- yes)
- mkdir -p "$GIT_DIR/objects/info"
- echo "$repo/objects" >> "$GIT_DIR/objects/info/alternates"
- ;;
- esac
+ if test "$local_shared" = yes
+ then
+ mkdir -p "$GIT_DIR/objects/info"
+ echo "$repo/objects" >>"$GIT_DIR/objects/info/alternates"
+ else
+ l= &&
+ if test "$use_local_hardlink" = yes
+ then
+ # See if we can hardlink and drop "l" if not.
+ sample_file=$(cd "$repo" && \
+ find objects -type f -print | sed -e 1q)
+ # objects directory should not be empty because
+ # we are cloning!
+ test -f "$repo/$sample_file" || exit
+ if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
+ then
+ rm -f "$GIT_DIR/objects/sample"
+ l=l
+ else
+ echo >&2 "Warning: -l asked but cannot hardlink to $repo"
+ fi
+ fi &&
+ cd "$repo" &&
+ find objects -depth -print | cpio -pumd$l "$GIT_DIR/" || exit 1
+ fi
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
;;
*)
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 . shallow"
+test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
(cd shallow; git count-objects -v) > count.shallow
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B A D'
+'git clone --reference B file://`pwd`/A D'
cd "$base_dir"
fi
'
+test_expect_success 'With -no-hardlinks, local will make a copy' '
+ cd "$D" &&
+ git clone --bare --no-hardlinks x w &&
+ cd w &&
+ linked=$(find objects -type f ! -links 1 | wc -l) &&
+ test "$linked" = 0
+'
+
+test_expect_success 'Even without -l, local will make a hardlink' '
+ cd "$D" &&
+ rm -fr w &&
+ git clone -l --bare x w &&
+ cd w &&
+ copied=$(find objects -type f -links 1 | wc -l) &&
+ test "$copied" = 0
+'
+
test_done