From: Junio C Hamano Date: Sat, 16 Jul 2005 07:16:24 +0000 (-0700) Subject: [PATCH] fetch/pull: short-hand notation for remote repositories. X-Git-Tag: v0.99.2~54 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=f170e4b39d87365cda17b80436ba6db4a2044e88;p=git.git [PATCH] fetch/pull: short-hand notation for remote repositories. Since pull and fetch are done often against the same remote repository repeatedly, keeping the URL to pull from along with the name of the head to use in $GIT_DIR/branches/$name makes a lot of sense. Adopt that convention from Cogito, and try to be compatible when possible; storing a partial URL and completing it with a trailing path may not be understood by Cogito. While we are at it, fix pulling a tag. Earlier, we updated only refs/tags/$tag without updating FETCH_HEAD, and called resolve-script using a stale (or absent) FETCH_HEAD. Signed-off-by: Junio C Hamano Signed-off-by: Linus Torvalds --- diff --git a/Makefile b/Makefile index 8492b0857..bf3cd8d73 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \ git-reset-script git-add-script git-checkout-script git-clone-script \ gitk git-cherry git-rebase-script git-relink-script git-repack-script \ git-format-patch-script git-sh-setup-script git-push-script \ - git-branch-script + git-branch-script git-parse-remote PROG= git-update-cache git-diff-files git-init-db git-write-tree \ git-read-tree git-commit-tree git-cat-file git-fsck-cache \ diff --git a/git-fetch-script b/git-fetch-script index acb1e56e7..fce43e6dc 100755 --- a/git-fetch-script +++ b/git-fetch-script @@ -1,33 +1,39 @@ #!/bin/sh # -destination=FETCH_HEAD - -merge_repo=$1 -merge_name=${2:-HEAD} -if [ "$2" = "tag" ]; then - merge_name="refs/tags/$3" - destination="$merge_name" -fi - . git-sh-setup-script || die "Not a git archive" +. git-parse-remote "$@" +merge_repo="$_remote_repo" +merge_head="$_remote_head" +merge_store="$_remote_store" TMP_HEAD="$GIT_DIR/TMP_HEAD" case "$merge_repo" in http://*) - head=$(wget -q -O - "$merge_repo/$merge_name") || exit 1 - echo Fetching $head using http - git-http-pull -v -a "$head" "$merge_repo/" + head=$(wget -q -O - "$merge_repo/$merge_head") || exit 1 + echo Fetching "$merge_head" using http + git-http-pull -v -a "$merge_head" "$merge_repo/" ;; rsync://*) - rsync -L "$merge_repo/$merge_name" "$TMP_HEAD" || exit 1 + rsync -L "$merge_repo/$merge_head" "$TMP_HEAD" || exit 1 head=$(git-rev-parse TMP_HEAD) rm -f "$TMP_HEAD" rsync -avz --ignore-existing "$merge_repo/objects/" "$GIT_OBJECT_DIRECTORY/" ;; *) - head=$(git-fetch-pack "$merge_repo" "$merge_name") + head=$(git-fetch-pack "$merge_repo" "$merge_head") ;; esac || exit 1 + git-rev-parse --verify "$head" > /dev/null || exit 1 -echo "$head" > "$GIT_DIR/$destination" + +case "$merge_store" in +'') + echo "$head" > "$GIT_DIR/$merge_store" +esac && + +# FETCH_HEAD is fed to git-resolve-script which will eventually be +# passed to git-commit-tree as one of the parents. Make sure we do +# not give a tag object ID. + +git-rev-parse "$head^0" >"$GIT_DIR/FETCH_HEAD" diff --git a/git-parse-remote b/git-parse-remote new file mode 100755 index 000000000..bfe7a906d --- /dev/null +++ b/git-parse-remote @@ -0,0 +1,79 @@ +: To be included in git-pull and git-fetch scripts. + +# A remote repository can be specified on the command line +# in one of the following formats: +# +# +# +# tag +# +# where could be one of: +# +# a URL (including absolute or local pathname) +# a short-hand +# a short-hand followed by a trailing path +# +# A short-hand has a corresponding file $GIT_DIR/branches/, +# whose contents is a URL, possibly followed by a URL fragment # +# to name the default branch on the remote side to fetch from. + +_remote_repo= _remote_store= _remote_head= _remote_name= + +case "$1" in +*:* | /* | ../* | ./* ) + _remote_repo="$1" + ;; +* ) + # otherwise, it is a short hand. + case "$1" in + */*) + # a short-hand followed by a trailing path + _token=$(expr "$1" : '\([^/]*\)/') + _rest=$(expr "$1" : '[^/]*\(/.*\)$') + ;; + *) + _token="$1" + _rest= + _remote_store="refs/heads/$_token" + ;; + esac + test -f "$GIT_DIR/branches/$_token" || + die "No such remote branch: $_token" + + _remote_repo=$(cat "$GIT_DIR/branches/$_token")"$_rest" + ;; +esac + +case "$_remote_repo" in +*"#"*) + _remote_head=`expr "$_remote_repo" : '.*#\(.*\)$'` + _remote_repo=`expr "$_remote_repo" : '\(.*\)#'` + ;; +esac + +_remote_name=$(echo "$_remote_repo" | sed 's|\.git/*$||') + +case "$2" in +tag) + _remote_name="tag '$3' of $_remote_name" + _remote_head="refs/tags/$3" + _remote_store="$_remote_head" + ;; +?*) + # command line specified a head explicitly; do not + # store the fetched head as a branch head. + _remote_name="head '$2' of $_remote_name" + _remote_head="refs/heads/$2" + _remote_store='' + ;; +'') + case "$_remote_head" in + '') + _remote_head=HEAD ;; + *) + _remote_head="refs/heads/$_remote_head" + _remote_name="head '$_remote_head' of $_remote_name" + ;; + esac + ;; +esac diff --git a/git-pull-script b/git-pull-script index 8e309fc98..fc463260b 100755 --- a/git-pull-script +++ b/git-pull-script @@ -1,23 +1,10 @@ #!/bin/sh # . git-sh-setup-script || die "Not a git archive" +. git-parse-remote "$@" +merge_name="$_remote_name" -merge_repo=$1 - -merge_name=$(echo "$1" | sed 's:\.git/*$::') -merge_head=HEAD -type=head -if [ "$2" = "tag" ]; then - type=tag - shift -fi -if [ "$2" ] -then - merge_name="$type '$2' of $merge_name" - merge_head="refs/${type}s/$2" -fi - -git-fetch-script "$merge_repo" "$merge_head" || exit 1 +git-fetch-script "$@" || exit 1 git-resolve-script \ "$(cat "$GIT_DIR"/HEAD)" \