git-fetch: auto-following tags.

I added things to ls-remote so that Cogito can auto-follow tags
easily and correctly a while ago, but git-fetch did not use the
facility.  Recently added git-describe command relies on
repository keeping up-to-date set of tags, which made it much
more attractive to automatically follow tags, so we do that as
well.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano 2006-01-07 00:48:04 -08:00
parent 026351a035
commit 03febf99bc
2 changed files with 169 additions and 124 deletions

View File

@ -10,15 +10,23 @@
fetches is a descendant of `<lbranch>`. This option fetches is a descendant of `<lbranch>`. This option
overrides that check. overrides that check.
\--no-tags::
By default, `git-fetch` fetches tags that point at
objects that are downloaded from the remote repository
and stores them locally. This option disables this
automatic tag following.
-t, \--tags:: -t, \--tags::
By default, the git core utilities will not fetch and store Most of the tags are fetched automatically as branch
tags under the same name as the remote repository; ask it heads are downloaded, but tags that do not point at
to do so using `--tags`. Using this option will bound the objects reachable from the branch heads that are being
list of objects pulled to the remote tags. Commits in branches tracked will not be fetched by this mechanism. This
beyond the tags will be ignored. flag lets all tags and their associated objects be
downloaded.
-u, \--update-head-ok:: -u, \--update-head-ok::
By default `git-fetch` refuses to update the head which By default `git-fetch` refuses to update the head which
corresponds to the current branch. This flag disables the corresponds to the current branch. This flag disables the
check. Note that fetching into the current branch will not check. Note that fetching into the current branch will not
update the index and working directory, so use it with care. update the index and working directory, so use it with care.

View File

@ -11,6 +11,7 @@ LF='
' '
IFS="$LF" IFS="$LF"
no_tags=
tags= tags=
append= append=
force= force=
@ -28,6 +29,9 @@ do
-t|--t|--ta|--tag|--tags) -t|--t|--ta|--tag|--tags)
tags=t tags=t
;; ;;
-n|--n|--no|--no-|--no-t|--no-ta|--no-tag|--no-tags)
no_tags=t
;;
-u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\ -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
--update-he|--update-hea|--update-head|--update-head-|\ --update-he|--update-hea|--update-head|--update-head-|\
--update-head-o|--update-head-ok) --update-head-o|--update-head-ok)
@ -212,6 +216,10 @@ then
fi fi
fi fi
fetch_main () {
reflist="$1"
refs=
for ref in $reflist for ref in $reflist
do do
refs="$refs$LF$ref" refs="$refs$LF$ref"
@ -264,8 +272,8 @@ do
"$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit "$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
# Look at objects/info/alternates for rsync -- http will # Look at objects/info/alternates for rsync -- http will
# support it natively and git native ones will do it on the remote # support it natively and git native ones will do it on
# end. Not having that file is not a crime. # the remote end. Not having that file is not a crime.
rsync -q "$remote/objects/info/alternates" \ rsync -q "$remote/objects/info/alternates" \
"$GIT_DIR/TMP_ALT" 2>/dev/null || "$GIT_DIR/TMP_ALT" 2>/dev/null ||
rm -f "$GIT_DIR/TMP_ALT" rm -f "$GIT_DIR/TMP_ALT"
@ -298,6 +306,7 @@ case "$remote" in
http://* | https://* | rsync://* ) http://* | https://* | rsync://* )
;; # we are already done. ;; # we are already done.
*) *)
( : subshell because we muck with IFS
IFS=" $LF" IFS=" $LF"
( (
git-fetch-pack "$remote" $rref || echo failed "$remote" git-fetch-pack "$remote" $rref || echo failed "$remote"
@ -337,8 +346,36 @@ http://* | https://* | rsync://* )
local_name=$(expr "$found" : '[^:]*:\(.*\)') local_name=$(expr "$found" : '[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" \ append_fetch_head "$sha1" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge" "$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done || exit done
;; ) || exit ;;
esac
}
fetch_main "$reflist"
# automated tag following
case "$no_tags$tags" in
'')
taglist=$(IFS=" " &&
git-ls-remote --tags "$remote" |
sed -ne 's|^\([0-9a-f]*\)[ ]\(refs/tags/.*\)^{}$|\1 \2|p' |
while read sha1 name
do
test -f "$GIT_DIR/$name" && continue
git-check-ref-format "$name" || {
echo >&2 "warning: tag ${name} ignored"
continue
}
git-cat-file -t "$sha1" >/dev/null 2>&1 || continue
echo >&2 "Auto-following $name"
echo ".${name}:${name}"
done)
case "$taglist" in
'') ;;
?*)
fetch_main "$taglist" ;;
esac
esac esac
# If the original head was empty (i.e. no "master" yet), or # If the original head was empty (i.e. no "master" yet), or