X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-clone.sh;h=de51983584bb0fd015ed75704b72bec8fdb55430;hb=0053e902b4f777ba454b62263d3695e5292b1559;hp=1f5d07a057ed04dd9ffc7eb705d0c752d250bf72;hpb=abcb49cb56fc6fa047a8838cd47fbdfa48791798;p=git.git diff --git a/git-clone.sh b/git-clone.sh index 1f5d07a05..de5198358 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -14,7 +14,7 @@ die() { } usage() { - die "Usage: $0 [--template=] [--no-separate-remote] [--reference ] [--bare] [-l [-s]] [-q] [-u ] [--origin ] [-n] []" + die "Usage: $0 [--template=] [--reference ] [--bare] [-l [-s]] [-q] [-u ] [--origin ] [--depth ] [-n] []" } get_repo_base() { @@ -36,7 +36,7 @@ clone_dumb_http () { clone_tmp="$GIT_DIR/clone-tmp" && mkdir -p "$clone_tmp" || exit 1 if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-repo-config --bool http.noEPSV`" = true ]; then + "`git-config --bool http.noEPSV`" = true ]; then curl_extra_args="${curl_extra_args} --disable-epsv" fi http_fetch "$1/info/refs" "$clone_tmp/refs" || @@ -66,48 +66,6 @@ Perhaps git-update-server-info needs to be run there?" rm -f "$GIT_DIR/REMOTE_HEAD" } -# Read git-fetch-pack -k output and store the remote branches. -copy_refs=' -use File::Path qw(mkpath); -use File::Basename qw(dirname); -my $git_dir = $ARGV[0]; -my $use_separate_remote = $ARGV[1]; -my $origin = $ARGV[2]; - -my $branch_top = ($use_separate_remote ? "remotes/$origin" : "heads"); -my $tag_top = "tags"; - -sub store { - my ($sha1, $name, $top) = @_; - $name = "$git_dir/refs/$top/$name"; - mkpath(dirname($name)); - open O, ">", "$name"; - print O "$sha1\n"; - close O; -} - -open FH, "<", "$git_dir/CLONE_HEAD"; -while () { - my ($sha1, $name) = /^([0-9a-f]{40})\s(.*)$/; - next if ($name =~ /\^\173/); - if ($name eq "HEAD") { - open O, ">", "$git_dir/REMOTE_HEAD"; - print O "$sha1\n"; - close O; - next; - } - if ($name =~ s/^refs\/heads\///) { - store($sha1, $name, $branch_top); - next; - } - if ($name =~ s/^refs\/tags\///) { - store($sha1, $name, $tag_top); - next; - } -} -close FH; -' - quiet= local=no use_local=no @@ -120,6 +78,9 @@ reference= origin= origin_override= use_separate_remote=t +depth= +no_progress= +test -t 1 || no_progress=--no-progress while case "$#,$1" in 0,*) break ;; @@ -137,11 +98,9 @@ while *,--template=*) template="$1" ;; *,-q|*,--quiet) quiet=-q ;; - *,--use-separate-remote) - # default - use_separate_remote=t ;; + *,--use-separate-remote) ;; *,--no-separate-remote) - use_separate_remote= ;; + die "clones are always made with separate-remote layout" ;; 1,--reference) usage ;; *,--reference) shift; reference="$1" ;; @@ -164,7 +123,13 @@ while 1,-u|1,--upload-pack) usage ;; *,-u|*,--upload-pack) shift - upload_pack="--exec=$1" ;; + upload_pack="--upload-pack=$1" ;; + *,--upload-pack=*) + upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;; + 1,--depth) usage;; + *,--depth) + shift + depth="--depth=$1";; *,-*) usage ;; *) break ;; esac @@ -211,23 +176,36 @@ yes) GIT_DIR="$D" ;; *) GIT_DIR="$D/.git" ;; -esac && export GIT_DIR && git-init-db ${template+"$template"} || usage +esac && export GIT_DIR && git-init ${template+"$template"} || usage if test -n "$reference" then + ref_git= if test -d "$reference" then if test -d "$reference/.git/objects" then - reference="$reference/.git" + ref_git="$reference/.git" + elif test -d "$reference/objects" + then + ref_git="$reference" fi - reference=$(cd "$reference" && pwd) - echo "$reference/objects" >"$GIT_DIR/objects/info/alternates" - (cd "$reference" && tar cf - refs) | - (cd "$GIT_DIR/refs" && - mkdir reference-tmp && - cd reference-tmp && - tar xf -) + fi + if test -n "$ref_git" + then + ref_git=$(cd "$ref_git" && pwd) + echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates" + ( + GIT_DIR="$ref_git" git for-each-ref \ + --format='%(objectname) %(*objectname)' + ) | + while read a b + do + test -z "$a" || + git update-ref "refs/reference-tmp/$a" "$a" + test -z "$b" || + git update-ref "refs/reference-tmp/$b" "$b" + done else die "reference repository '$reference' is not a local directory." fi @@ -269,6 +247,10 @@ yes,yes) *) case "$repo" in rsync://*) + case "$depth" in + "") ;; + *) die "shallow over rsync not supported" ;; + esac rsync $quiet -av --ignore-existing \ --exclude info "$repo/objects/" "$GIT_DIR/objects/" || exit @@ -297,6 +279,10 @@ yes,yes) git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1 ;; https://*|http://*|ftp://*) + case "$depth" in + "") ;; + *) die "shallow over http or ftp not supported" ;; + esac if test -z "@@NO_CURL@@" then clone_dumb_http "$repo" "$D" @@ -306,8 +292,8 @@ yes,yes) ;; *) case "$upload_pack" in - '') git-fetch-pack --all -k $quiet "$repo" ;; - *) git-fetch-pack --all -k $quiet "$upload_pack" "$repo" ;; + '') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";; + *) git-fetch-pack --all -k $quiet "$upload_pack" $depth $no_progress "$repo" ;; esac >"$GIT_DIR/CLONE_HEAD" || die "fetch-pack from '$repo' failed." ;; @@ -319,20 +305,37 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp" if test -f "$GIT_DIR/CLONE_HEAD" then # Read git-fetch-pack -k output and store the remote branches. - @@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" || - exit + if [ -n "$use_separate_remote" ] + then + branch_top="remotes/$origin" + else + branch_top="heads" + fi + tag_top="tags" + while read sha1 name + do + case "$name" in + *'^{}') + continue ;; + HEAD) + destname="REMOTE_HEAD" ;; + refs/heads/*) + destname="refs/$branch_top/${name#refs/heads/}" ;; + refs/tags/*) + destname="refs/$tag_top/${name#refs/tags/}" ;; + *) + continue ;; + esac + git-update-ref -m "clone: from $repo" "$destname" "$sha1" "" + done < "$GIT_DIR/CLONE_HEAD" fi cd "$D" || exit if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD" then - # Figure out which remote branch HEAD points at. - case "$use_separate_remote" in - '') remote_top=refs/heads ;; - *) remote_top="refs/remotes/$origin" ;; - esac - + # a non-bare repository is always in separate-remote layout + remote_top="refs/remotes/$origin" head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"` case "$head_sha1" in 'ref: refs/'*) @@ -348,7 +351,7 @@ then # The name under $remote_top the remote HEAD seems to point at. head_points_at=$( ( - echo "master" + test -f "$GIT_DIR/$remote_top/master" && echo "master" cd "$GIT_DIR/$remote_top" && find . -type f -print | sed -e 's/^\.\///' ) | ( @@ -366,48 +369,33 @@ then ) ) - # Write out remotes/$origin file, and update our "$head_points_at". + # Write out remote.$origin config, and update our "$head_points_at". case "$head_points_at" in ?*) - mkdir -p "$GIT_DIR/remotes" && + # Local default branch git-symbolic-ref HEAD "refs/heads/$head_points_at" && - case "$use_separate_remote" in - t) origin_track="$remote_top/$head_points_at" - git-update-ref HEAD "$head_sha1" ;; - *) origin_track="$remote_top/$origin" - git-update-ref "refs/heads/$origin" "$head_sha1" ;; - esac && - git-repo-config remote."$origin".url "$repo" && - git-repo-config remote."$origin".fetch \ - "refs/heads/$head_points_at:$origin_track" && - (cd "$GIT_DIR/$remote_top" && find . -type f -print) | - while read dotslref - do - name=`expr "$dotslref" : './\(.*\)'` - if test "z$head_points_at" = "z$name" - then - continue - fi - if test "$use_separate_remote" = '' && - test "z$origin" = "z$name" - then - continue - fi - git-repo-config remote."$origin".fetch "refs/heads/${name}:$remote_top/${name}" '^$' - done && - case "$use_separate_remote" in - t) - rm -f "refs/remotes/$origin/HEAD" - git-symbolic-ref "refs/remotes/$origin/HEAD" \ - "refs/remotes/$origin/$head_points_at" - esac && - git-repo-config branch."$head_points_at".remote "$origin" && - git-repo-config branch."$head_points_at".merge "refs/heads/$head_points_at" + + # Tracking branch for the primary branch at the remote. + origin_track="$remote_top/$head_points_at" && + git-update-ref HEAD "$head_sha1" && + + # Upstream URL + git-config remote."$origin".url "$repo" && + + # Set up the mappings to track the remote branches. + git-config remote."$origin".fetch \ + "+refs/heads/*:$remote_top/*" '^$' && + rm -f "refs/remotes/$origin/HEAD" + git-symbolic-ref "refs/remotes/$origin/HEAD" \ + "refs/remotes/$origin/$head_points_at" && + + git-config branch."$head_points_at".remote "$origin" && + git-config branch."$head_points_at".merge "refs/heads/$head_points_at" esac case "$no_checkout" in '') - test "z$quiet" = z && v=-v || v= + test "z$quiet" = z -a "z$no_progress" = z && v=-v || v= git-read-tree -m -u $v HEAD HEAD esac fi