Skip to content

Commit 9e9b267

Browse files
author
Junio C Hamano
committed
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>
1 parent 1be0659 commit 9e9b267

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

git-push.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ has_all=
99
has_force=
1010
has_exec=
1111
remote=
12+
do_tags=
1213

1314
while case "$#" in 0) break ;; esac
1415
do
1516
case "$1" in
1617
--all)
1718
has_all=--all ;;
19+
--tags)
20+
do_tags=yes ;;
1821
--force)
1922
has_force=--force ;;
2023
--exec=*)
@@ -33,6 +36,10 @@ case "$#" in
3336
echo "Where would you want to push today?"
3437
usage ;;
3538
esac
39+
if test ",$has_all,$do_tags," = ",--all,yes,"
40+
then
41+
do_tags=
42+
fi
3643

3744
. git-parse-remote
3845
remote=$(get_remote_url "$@")
@@ -42,6 +49,20 @@ case "$has_all" in
4249
esac
4350
shift
4451

52+
case "$do_tags" in
53+
yes)
54+
set "$@" $(cd "$GIT_DIR/refs" && find tags -type f -print) ;;
55+
esac
56+
57+
# Now we have explicit refs from the command line or from remotes/
58+
# shorthand, or --tags. Falling back on the current branch if we still
59+
# do not have any may be an alternative, but prevent mistakes for now.
60+
61+
case "$#,$has_all" in
62+
0,)
63+
die "No refs given to be pushed." ;;
64+
esac
65+
4566
case "$remote" in
4667
git://*)
4768
die "Cannot use READ-ONLY transport to push to $remote" ;;

0 commit comments

Comments
 (0)