{"thread":{"id":"3058","subject":"[RFD] what should \"git push remote.host:path\" do?","startedAt":"2006-01-12T09:13:30Z","lastAt":"2006-01-13T01:54:55Z","messageCount":7,"participants":["Junio C Hamano","Sean","Nick Hengeveld","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"14542","messageId":"7vslrtq05h.fsf@assigned-by-dhcp.cox.net","threadId":"3058","inReplyTo":null,"subject":"[RFD] what should \"git push remote.host:path\" do?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-01-12T09:13:30Z","receivedAt":"2006-01-12T09:13:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The underlying \"git send-pack remote.host:path\" pushes all the\nmatching refs that both local and remote has, and \"git push\"\nblindly inherits this property.\n\nThis is bad.  A typical cloned repository (e.g. a subsystem\nmaintainer repository cloned from Linus repository) has at least\ntwo branches, \"master\" to keep the subsystem and \"origin\" that\nrecords tip of Linus \"master\" when the repository was cloned.\nIf this is the public repository, then subsystem developers\nwould clone from this one, and then cloned ones have \"master\"\nand \"origin\".  When developers use this public subsystem\nrepository as a shared repository, \"git push subsys:path\" would\ntry to push the matching refs, \"master\" and \"origin\".\n\nOne workaround is to delete \"origin\" branch from the public\nrepository, because having \"origin\" there is meaningless.\nNobody is supposed to pull directly into it from Linus after\ncloning; rather, changes in upstream would trickle in by a\ndeveloper who cloned from this subsystem repository and then\npulled from Linus into his repository and then pushed his merge\nresult into this public repository.\n\nNevertheless, exposing the default behaviour of \"git send-pack\"\nto \"git push\" was probably a mistake.  I'd propose to require at\nleast one refspec to be specified, either on the command line or\nvia $GIT_DIR/remotes mechanism.  So my answer to the \"Subject: \"\nline question is \"Barf\".\n\nUnlike pull that can happen pretty much promiscuously, people\nwill push into the same set of a limited number of remote\nrepositories repeatedly over the life of the project, so it is\nreasonable to assume they would want to keep a $GIT_DIR/remotes/\nentry for those repositories to save typing.  Then always\nrequiring one or more refspecs for push is not too much to ask\nfor.\n\nOpinions?\n\nBTW, Nick, what does http-push do with \"git push http://foo\"\nwithout refspecs?\n"},{"id":"14544","messageId":"BAYC1-PASMTP099ED34B41FFA02EDEEF25AE270@CEZ.ICE","threadId":"3058","inReplyTo":"7vslrtq05h.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFD] what should \"git push remote.host:path\" do?","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-01-12T10:18:41Z","receivedAt":"2006-01-12T10:18:41Z","isPatch":false,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Thu, January 12, 2006 4:13 am, Junio C Hamano said:\n> The underlying \"git send-pack remote.host:path\" pushes all the\n> matching refs that both local and remote has, and \"git push\"\n> blindly inherits this property.\n[snip]\n> Unlike pull that can happen pretty much promiscuously, people\n> will push into the same set of a limited number of remote\n> repositories repeatedly over the life of the project, so it is\n> reasonable to assume they would want to keep a $GIT_DIR/remotes/\n> entry for those repositories to save typing.  Then always\n> requiring one or more refspecs for push is not too much to ask\n> for.\n>\n> Opinions?\n\nWhat about assuming a refspec of  \"current-branch:current-branch\" ?\nThat is, if the branch name that is currently checked out locally\nalso exists upstream, push into it (only if fast forward).\n\nThis should allow multiple branches to be updated locally, and pushed\nupstream selectively.  If you force all push-refspecs to be listed\nin a remotes file, they'll all be updated every time you push and\nyou'd lose the ability to push just one branch upstream without\nresorting to multiple $GIT_DIR/remotes/ entries.\n\nSean\n"},{"id":"14556","messageId":"20060112163157.GB3873@reactrix.com","threadId":"3058","inReplyTo":"7vslrtq05h.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFD] what should \"git push remote.host:path\" do?","fromName":"Nick Hengeveld","fromEmail":"nickh@reactrix.com","sentAt":"2006-01-12T16:31:57Z","receivedAt":"2006-01-12T16:31:57Z","isPatch":false,"sender":{"key":"nickh@reactrix.com","avatar":null},"body":"On Thu, Jan 12, 2006 at 01:13:30AM -0800, Junio C Hamano wrote:\n\n> BTW, Nick, what does http-push do with \"git push http://foo\"\n> without refspecs?\n\nIt won't push anything unless refspecs are specified.  If there are\nnone, it will still verify remote DAV locking is available and then\nexit quietly.\n\n-- \nFor a successful technology, reality must take precedence over public\nrelations, for nature cannot be fooled.\n"},{"id":"14558","messageId":"Pine.LNX.4.64.0601121006040.3535@g5.osdl.org","threadId":"3058","inReplyTo":"7vslrtq05h.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFD] what should \"git push remote.host:path\" do?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-01-12T18:10:31Z","receivedAt":"2006-01-12T18:10:31Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 12 Jan 2006, Junio C Hamano wrote:\n> \n> Nevertheless, exposing the default behaviour of \"git send-pack\"\n> to \"git push\" was probably a mistake.  I'd propose to require at\n> least one refspec to be specified, either on the command line or\n> via $GIT_DIR/remotes mechanism.  So my answer to the \"Subject: \"\n> line question is \"Barf\".\n\nWell, I don't have objections, but from ym usage schenario, I'd at least \nthen want flags for \"all tags\" (--tags - like \"pull\") and \"all branches\" \n(--all).\n\nHaving to list all tags/branches is slightly painful. I currently push out \nall my tags with\n\n\t./push-all $(cd .git/refs ; find -type f tags)\n\nwhich works but isn't exactly user-friendly (\"push-all\" is just a script \nthat uses \"git push\" to push to multiple repositories).\n\n> Unlike pull that can happen pretty much promiscuously, people\n> will push into the same set of a limited number of remote\n> repositories repeatedly over the life of the project, so it is\n> reasonable to assume they would want to keep a $GIT_DIR/remotes/\n> entry for those repositories to save typing.  Then always\n> requiring one or more refspecs for push is not too much to ask\n> for.\n\nWell, especially if you want to use \"git push\" to basically back up your \nown repo, you do want the \"--all\" flag. Otherwise you will then forget to \nadd a branch name to every remotes file whenyou create a new branch.\n\n\t\tLinus\n"},{"id":"14564","messageId":"7vbqyhp9ah.fsf@assigned-by-dhcp.cox.net","threadId":"3058","inReplyTo":"Pine.LNX.4.64.0601121006040.3535@g5.osdl.org","subject":"Re: [RFD] what should \"git push remote.host:path\" do?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-01-12T18:53:42Z","receivedAt":"2006-01-12T18:53:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> Well, especially if you want to use \"git push\" to basically back up your \n> own repo, you do want the \"--all\" flag. Otherwise you will then forget to \n> add a branch name to every remotes file whenyou create a new branch.\n\nSorry, I was unclear in my original message, but I meant to\nrequire at least one refspec to be given to the command.  Ways\nto give refspec to the command are:\n\n (1) give one or more from the command line\n (2) give --all from the command line\n (3) give none from the command line, but in this case you need\n     at least one \"Push:\" the \"remotes\" file you use.\n\nWe already have --all, but your \"git push --tags $remote\" makes\nsense.  For backups, \"only matching things\" is not good enough,\nand we need --all.\n"},{"id":"14565","messageId":"7v64opp8zh.fsf@assigned-by-dhcp.cox.net","threadId":"3058","inReplyTo":"BAYC1-PASMTP099ED34B41FFA02EDEEF25AE270@CEZ.ICE","subject":"Re: [RFD] what should \"git push remote.host:path\" do?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-01-12T19:00:18Z","receivedAt":"2006-01-12T19:00:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Sean\" <seanlkml@sympatico.ca> writes:\n\n> What about assuming a refspec of  \"current-branch:current-branch\" ?\n> That is, if the branch name that is currently checked out locally\n> also exists upstream, push into it (only if fast forward).\n>\n> This should allow multiple branches to be updated locally, and pushed\n> upstream selectively.\n\nRequiring at least one refspec to be given to the command has\nthe same property.  Ways to give refspec to the command are:\n\n (1) give one or more from the command line\n (2) give --all from the command line\n (3) give none from the command line, but in this case you need\n     at least one \"Push:\" the \"remotes\" file you use.\n\nSo it really boils down to \"is pushing the current branch a\nbetter default\"?\n\nEven if a project uses CVS style shared repository setup,\nindividual developers would want to use topic branches to\nprepare things that they eventually push to the shared common,\nand I suspect that it would lead to more mistakes if we default\nthe push to push the current branch.  \"Push: master\" in the\nremotes/ file to publish your results to the shared repository\nwould be safer; \"git push\" when you are still in your topic\nbranch and have not merged things up into your master branch for\npublication would be no-op, as opposed to pushing the topic\nbranch, probably resulting in the topic branch in the shared\nrepository, even though the topic was meant to be internal to\nhis repository.\n"},{"id":"14583","messageId":"7v1wzcj3io.fsf@assigned-by-dhcp.cox.net","threadId":"3058","inReplyTo":"Pine.LNX.4.64.0601121006040.3535@g5.osdl.org","subject":"[PATCH] git-push: avoid falling back on pushing \"matching\" refs.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-01-13T01:54:55Z","receivedAt":"2006-01-13T01:54:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> Having to list all tags/branches is slightly painful. I currently push out \n> all my tags with\n>\n> \t./push-all $(cd .git/refs ; find -type f tags)\n>\n> which works but isn't exactly user-friendly (\"push-all\" is just a script \n> that uses \"git push\" to push to multiple repositories).\n\nSo here it is, to add --tags and avoid falling back to\n\"matching\" default.\n\n-- >8 --\nThe underlying \"git send-pack remote.host:path\" pushes all the\nmatching refs that both local and remote have, and \"git push\"\nblindly inherits this property.  Which probably was a mistake.\n\nA typical cloned repository (e.g. a subsystem repository cloned\nfrom Linus repository) has at least two branches, \"master\" to\nkeep the subsystem and \"origin\" that records tip of Linus\n\"master\" when the repository was cloned.  If this is the public\nrepository for the subsystem, then subsystem developers would\nclone it, and then cloned ones have \"master\" and \"origin\".  When\ndevelopers use this public subsystem repository as a shared\nrepository, pushing into it via \"git push subsys:/path/name\"\nwould try to push the matching refs, \"master\" and \"origin\", from\nthe developers' repositories.  The \"origin\" in the public shared\nrepository does not have much relevance, yet pushing into\n\"origin\" would cause \"not a fast forward\" checks to be\ntriggered.  Arguably \"git push subsys:/path/name master\" would\nwork it around, but having them to say it explicitly to avoid\npushing into \"origin\" as well is bad.\n\nThis commit requires you to give at least one refspec to\ngit-push.  You could \"give\" by either:\n\n (1) Listing the refspec(s) explicitly on the command line.\n     E.g. \"git push subsys:/path/name master\".\n\n (2) Using --all or --tags on the command line.\n     E.g. \"git push --tags subsys:/path/name\".\n\n (3) Using a $GIT_DIR/remotes shorthand with 'Push: refspec'\n     line in it.\n\nUnlike pull that can happen pretty much promiscuously, people\nwill push into the same set of a limited number of remote\nrepositories repeatedly over the life of the project, so it is\nreasonable to assume they would want to keep a $GIT_DIR/remotes/\nentry for those repositories even only to save typing the URL,\nso keeping the default 'Push: refspec' line in such is a\nsensible thing to do.\n\nIt was suggested to further fall back on pushing the current\nbranch, but this commit does not implement it.  If developers\nadopt topic branch workflow, pushing to public while on a topic\nbranch by mistake would expose the topic branch to the public\nrepository.  Not falling back to the current branch prevents\nthat mistake from happening.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n git-push.sh |   21 +++++++++++++++++++++\n 1 files changed, 21 insertions(+), 0 deletions(-)\n\n85393139981c28a2df93950b00e4712dc4bca56c\ndiff --git a/git-push.sh b/git-push.sh\nindex 1c5cf80..2b97e09 100755\n--- a/git-push.sh\n+++ b/git-push.sh\n@@ -9,12 +9,15 @@ has_all=\n has_force=\n has_exec=\n remote=\n+do_tags=\n \n while case \"$#\" in 0) break ;; esac\n do\n \tcase \"$1\" in\n \t--all)\n \t\thas_all=--all ;;\n+\t--tags)\n+\t\tdo_tags=yes ;;\n \t--force)\n \t\thas_force=--force ;;\n \t--exec=*)\n@@ -33,6 +36,10 @@ case \"$#\" in\n \techo \"Where would you want to push today?\"\n         usage ;;\n esac\n+if test \",$has_all,$do_tags,\" = \",--all,yes,\"\n+then\n+\tdo_tags=\n+fi\n \n . git-parse-remote\n remote=$(get_remote_url \"$@\")\n@@ -42,6 +49,20 @@ case \"$has_all\" in\n esac\n shift\n \n+case \"$do_tags\" in\n+yes)\n+\tset \"$@\" $(cd \"$GIT_DIR/refs\" && find tags -type f -print) ;;\n+esac\n+\n+# Now we have explicit refs from the command line or from remotes/\n+# shorthand, or --tags.  Falling back on the current branch if we still\n+# do not have any may be an alternative, but prevent mistakes for now.\n+\n+case \"$#,$has_all\" in\n+0,)\n+\tdie \"No refs given to be pushed.\" ;;\n+esac\n+\n case \"$remote\" in\n git://*)\n \tdie \"Cannot use READ-ONLY transport to push to $remote\" ;;\n-- \n1.1.1-g6009\n"}]}