summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <junkio@cox.net>2006-01-12 15:29:12 -0800
committerLibravatar Junio C Hamano <junkio@cox.net>2006-01-13 16:53:35 -0800
commit9e9b26751a5ca7a257b3e1cfb319fe3e4efc663c (patch)
tree457748008fe30ca454deae3f4485006de71b6606
parentcheckout: merge local modifications while switching branches. (diff)
downloadtgif-9e9b26751a5ca7a257b3e1cfb319fe3e4efc663c.tar.xz
git-push: avoid falling back on pushing "matching" refs.
The underlying "git send-pack remote.host:path" pushes all the matching refs that both local and remote have, and "git push" blindly inherits this property. Which probably was a mistake. A typical cloned repository (e.g. a subsystem repository cloned from Linus repository) has at least two branches, "master" to keep the subsystem and "origin" that records tip of Linus "master" when the repository was cloned. If this is the public repository for the subsystem, then subsystem developers would clone it, and then cloned ones have "master" and "origin". When developers use this public subsystem repository as a shared repository, pushing into it via "git push subsys:/path/name" would try to push the matching refs, "master" and "origin", from the developers' repositories. The "origin" in the public shared repository does not have much relevance, yet pushing into "origin" would cause "not a fast forward" checks to be triggered. Arguably "git push subsys:/path/name master" would work it around, but having them to say it explicitly to avoid pushing into "origin" as well is bad. This commit requires you to give at least one refspec to git-push. You could "give" by either: (1) Listing the refspec(s) explicitly on the command line. E.g. "git push subsys:/path/name master". (2) Using --all or --tags on the command line. E.g. "git push --tags subsys:/path/name". (3) Using a $GIT_DIR/remotes shorthand with 'Push: refspec' line in it. Unlike pull that can happen pretty much promiscuously, people will push into the same set of a limited number of remote repositories repeatedly over the life of the project, so it is reasonable to assume they would want to keep a $GIT_DIR/remotes/ entry for those repositories even only to save typing the URL, so keeping the default 'Push: refspec' line in such is a sensible thing to do. It was suggested to further fall back on pushing the current branch, but this commit does not implement it. If developers adopt topic branch workflow, pushing to public while on a topic branch by mistake would expose the topic branch to the public repository. Not falling back to the current branch prevents that mistake from happening. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rwxr-xr-xgit-push.sh21
1 files changed, 21 insertions, 0 deletions
diff --git a/git-push.sh b/git-push.sh
index 1c5cf80f87..136093bf13 100755
--- a/git-push.sh
+++ b/git-push.sh
@@ -9,12 +9,15 @@ has_all=
has_force=
has_exec=
remote=
+do_tags=
while case "$#" in 0) break ;; esac
do
case "$1" in
--all)
has_all=--all ;;
+ --tags)
+ do_tags=yes ;;
--force)
has_force=--force ;;
--exec=*)
@@ -33,6 +36,10 @@ case "$#" in
echo "Where would you want to push today?"
usage ;;
esac
+if test ",$has_all,$do_tags," = ",--all,yes,"
+then
+ do_tags=
+fi
. git-parse-remote
remote=$(get_remote_url "$@")
@@ -42,6 +49,20 @@ case "$has_all" in
esac
shift
+case "$do_tags" in
+yes)
+ set "$@" $(cd "$GIT_DIR/refs" && find tags -type f -print) ;;
+esac
+
+# Now we have explicit refs from the command line or from remotes/
+# shorthand, or --tags. Falling back on the current branch if we still
+# do not have any may be an alternative, but prevent mistakes for now.
+
+case "$#,$has_all" in
+0,)
+ die "No refs given to be pushed." ;;
+esac
+
case "$remote" in
git://*)
die "Cannot use READ-ONLY transport to push to $remote" ;;