{"thread":{"id":"43292","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","startedAt":"2006-11-23T22:58:35Z","lastAt":"2006-11-25T00:04:50Z","messageCount":17,"participants":["Junio C Hamano","Andy Whitcroft","J. Bruce Fields","Salikh Zakirov","Petr Baudis","Jakub Narebski","Sergey Vlasov"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"297162","messageId":"20061123225835.30071.99265.stgit@machine.or.cz","threadId":"43292","inReplyTo":null,"subject":"[PATCH] Make git-clone --use-separate-remote the default","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-11-23T22:58:35Z","receivedAt":"2006-11-23T22:58:35Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"and --use-immingled-remote can be used to get the original behaviour;\nit is also implied by --bare.\n\nWe get confused, frustrated and data-losing users *daily* on #git now\nbecause git-clone still produces the crippled repositories having the\nremote and local heads freely mixed together.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n Documentation/git-clone.txt |   20 ++++++++++++++------\n git-clone.sh                |   14 +++++++-------\n 2 files changed, 21 insertions(+), 13 deletions(-)\n\ndiff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt\nindex 8606047..b1ad79f 100644\n--- a/Documentation/git-clone.txt\n+++ b/Documentation/git-clone.txt\n@@ -11,7 +11,8 @@ SYNOPSIS\n [verse]\n 'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]\n \t  [-o <name>] [-u <upload-pack>] [--reference <repository>]\n-\t  [--use-separate-remote] <repository> [<directory>]\n+\t  [--use-separate-remote | --use-immingled-remote] <repository>\n+\t  [<directory>]\n \n DESCRIPTION\n -----------\n@@ -71,9 +72,10 @@ OPTIONS\n \tMake a 'bare' GIT repository.  That is, instead of\n \tcreating `<directory>` and placing the administrative\n \tfiles in `<directory>/.git`, make the `<directory>`\n-\titself the `$GIT_DIR`. This implies `-n` option.  When\n-\tthis option is used, neither the `origin` branch nor the\n-\tdefault `remotes/origin` file is created.\n+\titself the `$GIT_DIR`. This implies the `-n` and\n+\t`--use-immingled-remote' option.  When this option is used,\n+\tneither the `origin` branch nor the default `remotes/origin`\n+\tfile is created.\n \n --origin <name>::\n -o <name>::\n@@ -97,8 +99,14 @@ OPTIONS\n \n --use-separate-remote::\n \tSave remotes heads under `$GIT_DIR/remotes/origin/` instead\n-\tof `$GIT_DIR/refs/heads/`.  Only the master branch is saved\n-\tin the latter.\n+\tof `$GIT_DIR/refs/heads/`.  Only the local master branch is\n+\tsaved in the latter. This is the default.\n+\n+--use-immingled-remote::\n+\tSave remotes heads in the same namespace as the local heads,\n+\t`$GIT_DIR/refs/heads/'.  In regular repositories, this is\n+\ta legacy setup git-clone created by default in older Git\n+\tversions.  It is also still implied by `--bare'.\n \n <repository>::\n \tThe (possibly remote) repository to clone from.  It can\ndiff --git a/git-clone.sh b/git-clone.sh\nindex 3f006d1..9ed4135 100755\n--- a/git-clone.sh\n+++ b/git-clone.sh\n@@ -14,7 +14,7 @@ die() {\n }\n \n usage() {\n-\tdie \"Usage: $0 [--template=<template_directory>] [--use-separate-remote] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [-n] <repo> [<dir>]\"\n+\tdie \"Usage: $0 [--template=<template_directory>] [--use-immingled-remote] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [-n] <repo> [<dir>]\"\n }\n \n get_repo_base() {\n@@ -115,7 +115,7 @@ bare=\n reference=\n origin=\n origin_override=\n-use_separate_remote=\n+use_separate_remote=t\n while\n \tcase \"$#,$1\" in\n \t0,*) break ;;\n@@ -134,7 +134,10 @@ while\n \t  template=\"$1\" ;;\n \t*,-q|*,--quiet) quiet=-q ;;\n \t*,--use-separate-remote)\n+\t\t# default\n \t\tuse_separate_remote=t ;;\n+\t*,--use-immingled-remote)\n+\t\tuse_separate_remote= ;;\n \t1,--reference) usage ;;\n \t*,--reference)\n \t\tshift; reference=\"$1\" ;;\n@@ -169,18 +172,15 @@ repo=\"$1\"\n test -n \"$repo\" ||\n     die 'you must specify a repository to clone.'\n \n-# --bare implies --no-checkout\n+# --bare implies --no-checkout and --use-immingled-remote\n if test yes = \"$bare\"\n then\n \tif test yes = \"$origin_override\"\n \tthen\n \t\tdie '--bare and --origin $origin options are incompatible.'\n \tfi\n-\tif test t = \"$use_separate_remote\"\n-\tthen\n-\t\tdie '--bare and --use-separate-remote options are incompatible.'\n-\tfi\n \tno_checkout=yes\n+\tuse_separate_remote=\n fi\n \n"},{"id":"298747","messageId":"7vejrtiwqd.fsf@assigned-by-dhcp.cox.net","threadId":"43292","inReplyTo":"20061123225835.30071.99265.stgit@machine.or.cz","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-23T23:12:10Z","receivedAt":"2006-11-23T23:12:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n> and --use-immingled-remote can be used to get the original behaviour;\n> it is also implied by --bare.\n\nWhat's immingled?\n\n> We get confused, frustrated and data-losing users *daily* on #git now\n> because git-clone still produces the crippled repositories having the\n> remote and local heads freely mixed together.\n>\n> Signed-off-by: Petr Baudis <pasky@suse.cz>\n\nBeing strongly opinionated, not giving enough credit for the\nevolutionary process behind the history and venting frustration\nin the proposed commit log message is never a good strategy to\nget the patch applied.\n\nEven though I fully agree that use-separate-remotes should be\nthe default, to the point that I do not think we do not even\nneed a backward compatibility option.  People who want to use\ntraditional layout for simple one-remote-branch-only project\nwould not suffer anyway because 'origin' still means origin in\nthe new layout (refs/remotes/origin/HEAD).\n\nWe would need to update the tutorials to match this,though.  I\nthink it talks about the traditional layout and say 'See, now\nyou can run \"ls .git/refs/heads/{master,origin}\"' or something\nlike that.\n"},{"id":"294334","messageId":"4566311E.7040206@shadowen.org","threadId":"43292","inReplyTo":"7vejrtiwqd.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-11-23T23:39:10Z","receivedAt":"2006-11-23T23:39:10Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> Petr Baudis <pasky@suse.cz> writes:\n> \n>> and --use-immingled-remote can be used to get the original behaviour;\n>> it is also implied by --bare.\n> \n> What's immingled?\n\nHad me reaching for the dictionary too.  Seems to mean the same as\nintermingled which would be my choice ...\n\n"},{"id":"297780","messageId":"20061123234203.GN7201@pasky.or.cz","threadId":"43292","inReplyTo":"7vejrtiwqd.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-11-23T23:42:03Z","receivedAt":"2006-11-23T23:42:03Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, Nov 24, 2006 at 12:12:10AM CET, Junio C Hamano wrote:\n> Petr Baudis <pasky@suse.cz> writes:\n> \n> > and --use-immingled-remote can be used to get the original behaviour;\n> > it is also implied by --bare.\n> \n> What's immingled?\n\nOne dictionary says\n\n   Immingle \\Im*min\"gle\\, v. t.\n      To mingle; to mix; to unite; to blend. [R.] --Thomson.\n\nbut perhaps it's too much an obscure word... better suggestions\nwelcomed.\n\n> > We get confused, frustrated and data-losing users *daily* on #git now\n> > because git-clone still produces the crippled repositories having the\n> > remote and local heads freely mixed together.\n> >\n> > Signed-off-by: Petr Baudis <pasky@suse.cz>\n> \n> Being strongly opinionated, not giving enough credit for the\n> evolutionary process behind the history and venting frustration\n> in the proposed commit log message is never a good strategy to\n> get the patch applied.\n\nYes, sorry, the last days were a bit tiring to me.\n\nI'm not sure what evolutionary process should I describe, though...\n\n> Even though I fully agree that use-separate-remotes should be\n> the default, to the point that I do not think we do not even\n> need a backward compatibility option.  People who want to use\n> traditional layout for simple one-remote-branch-only project\n> would not suffer anyway because 'origin' still means origin in\n> the new layout (refs/remotes/origin/HEAD).\n\nI don't know, we still at least need to keep the functionality for\n--bare.\n\n> We would need to update the tutorials to match this,though.  I\n> think it talks about the traditional layout and say 'See, now\n> you can run \"ls .git/refs/heads/{master,origin}\"' or something\n> like that.\n\nOops, yes. I can try to go through the tutorials during tomorrow or the\nnext week...\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nThe meaning of Stonehenge in Traflamadorian, when viewed from above, is:\n\"Replacement part being rushed with all possible speed.\"\n"},{"id":"294812","messageId":"20061123234558.GA29170@fieldses.org","threadId":"43292","inReplyTo":"20061123234203.GN7201@pasky.or.cz","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2006-11-23T23:45:58Z","receivedAt":"2006-11-23T23:45:58Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Fri, Nov 24, 2006 at 12:42:03AM +0100, Petr Baudis wrote:\n> On Fri, Nov 24, 2006 at 12:12:10AM CET, Junio C Hamano wrote:\n> > Petr Baudis <pasky@suse.cz> writes:\n> > \n> > > and --use-immingled-remote can be used to get the original behaviour;\n> > > it is also implied by --bare.\n> > \n> > What's immingled?\n> \n> One dictionary says\n> \n>    Immingle \\Im*min\"gle\\, v. t.\n>       To mingle; to mix; to unite; to blend. [R.] --Thomson.\n> \n> but perhaps it's too much an obscure word... better suggestions\n> welcomed.\n\ncommingled? legacy? flat?\n\n"},{"id":"297307","messageId":"7vlkm1hf57.fsf@assigned-by-dhcp.cox.net","threadId":"43292","inReplyTo":"20061123234203.GN7201@pasky.or.cz","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-24T00:17:24Z","receivedAt":"2006-11-24T00:17:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n>> Even though I fully agree that use-separate-remotes should be\n>> the default, to the point that I think we do not even\n>> need a backward compatibility option.  People who want to use\n>> traditional layout for simple one-remote-branch-only project\n>> would not suffer anyway because 'origin' still means origin in\n>> the new layout (refs/remotes/origin/HEAD).\n>\n> I don't know, we still at least need to keep the functionality for\n> --bare.\n\nI agree --bare should continue to be a \"snapshot mirror\"; I am\nnot advocating for the removal of the internal implementation\ndetail such as $use_separate_remote variable.\n\nHowever, I think having one sane behaviour is the right thing to\ndo for a clone that prepares a repository with a working tree\n(including the one made with -n option, which only means \"do not\ndo the check-out immediately after cloning\" for such a\nrepository).\n\nThe traditional layout is slightly simpler for a project with\nthe simplest needs (that is, a single upstream repository that\nhas a single 'master' branch), but I do think even that is not\nan advantage anymore.\n\nWith the separate-remote layout, git-fetch would still fetch and\nupdate the \"origin\" (although that is now remotes/origin/master\nwhich is pointed at by remotes/origin/HEAD) and the user can\nstill refer to it with \"origin\".  Commands \"git-pull origin\",\n\"git-pull . origin\", and \"git-merge origin\" all will continue to\nwork the same way as before for such a project as in the\ntraditional layout, and that is why I think we do not need\nbackward compatibility flag in this case.\n"},{"id":"295251","messageId":"7vzmahe6qe.fsf@assigned-by-dhcp.cox.net","threadId":"43292","inReplyTo":"7vlkm1hf57.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-24T05:47:21Z","receivedAt":"2006-11-24T05:47:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> I agree --bare should continue to be a \"snapshot mirror\"; I am\n> not advocating for the removal of the internal implementation\n> detail such as $use_separate_remote variable.\n>\n> However, I think having one sane behaviour is the right thing to\n> do for a clone that prepares a repository with a working tree\n> (including the one made with -n option, which only means \"do not\n> do the check-out immediately after cloning\" for such a\n> repository).\n\nJust to let you know, I'll take the patch almost as is (even\nwith the --use-immingled-remote), except with a slight rewording\nin the documentation to warn people that the backward\ncompatibility option will be removed before the next major\nrelease.\n\nHowever, this simple command fails:\n\n\t$ git push $URL master\n\nif the target repository $URL is made with use-separate-remote.\n\nThis is because 'master' matches more than one on the remote\nside (heads/master and remotes/origin/master) which triggers\n\"Hey, that's ambiguous, make yourself clear which one you mean!\"\ncheck.  This breaks t5400 test.  We could \"fix\" the test to make\nit more explicit, but that is just a workaround.\n\nI think the send-pack/receive-pack pair needs to be taught that\nan unadorned branch name 'master' never matches anything under\nrefs/remotes. This means that it would require an explicit\nrefspec heads/master:remotes/origin/master in order to pudate\nrefs under refs/remotes on the remote side with a push.  I do\nnot think that is a big problem, because the normal patch-flow\nfor shared repository workflow is:\n\n\tremote\t\t\tlocal\n\n\t\t      (fecth)\n\theads/master\t--->\tremotes/origin/master ---.\n\t\t\t\t\t\t\t | (merge)\n\theads/master\t<---\theads/master\t      <--'\n\nand pushing into remotes/origin/* is not a norm.\n\nThe function to fix is connect.c::match_explicit_refs() and I\n_think_ making connect.c::count_refspec_match() not to consider\n'foo' to match 'refs/remotes/origin/foo' (but still keeping it\nto match 'refs/heads/foo' or 'refs/tags/foo') is enough to make\nthis happen.\n\nThis brings up two related issues.  Currently we automatically\nprepare \"Pull: refs/heads/$branch:refs/remotes/origin/$branch\"\nfor all branches that exists at the remote site when a clone\nhappens.  Andy Parkins has a patch to allow a glob pattern to be\nthere, like this [*1*]:\n\n\tPull: refs/heads/*:refs/remotes/origin/*\n\nwhich makes sense, and we might want to have this as the default\nafter the clone [*2*].\n\nAnother is if we might want to add \"Push: \" entry in the default\nafter the clone.  I am a bit reluctant to make the default setup\ntoo specific to CVS style \"central shared repo\" workflow, but\nany stupid default would not suit people with truly distributed\nworkflow anyway, so it might be fine.\n\n[Footnotes]\n\n*1* I rewrote the patch because I wanted to deal with the\n    fallout from recent packed-refs work at the same time.  So bugs\n    in the counter-proposal patch is mine while the credit for the\n    initiative and the idea goes to Andy.\n\n*2* I think the fetch wildcarding has an issue with what remote\n    head to merge when used with \"git pull\".  I think it should\n    use the one that is pointed at by refs/remotes/origin/HEAD,\n    but there is no code for that yet.  Hints, hints...\n\n\n"},{"id":"297003","messageId":"7vpsbde4fy.fsf@assigned-by-dhcp.cox.net","threadId":"43292","inReplyTo":"7vzmahe6qe.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-24T06:36:49Z","receivedAt":"2006-11-24T06:36:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> However, this simple command fails:\n>\n> \t$ git push $URL master\n>\n> if the target repository $URL is made with use-separate-remote.\n>\n> This is because 'master' matches more than one on the remote\n> side (heads/master and remotes/origin/master) which triggers\n> \"Hey, that's ambiguous, make yourself clear which one you mean!\"\n> check.  This breaks t5400 test.  We could \"fix\" the test to make\n> it more explicit, but that is just a workaround.\n>\n> I think the send-pack/receive-pack pair needs to be taught that\n> an unadorned branch name 'master' never matches anything under\n> refs/remotes. This means that it would require an explicit\n> refspec heads/master:remotes/origin/master in order to pudate\n> refs under refs/remotes on the remote side with a push.\n> ...\n> The function to fix is connect.c::match_explicit_refs() and I\n> _think_ making connect.c::count_refspec_match() not to consider\n> 'foo' to match 'refs/remotes/origin/foo' (but still keeping it\n> to match 'refs/heads/foo' or 'refs/tags/foo') is enough to make\n> this happen.\n\nThat is,...\n\n-- >8 --\n[PATCH] refs outside refs/{heads,tags} match less strongly.\n\nThis changes the refname matching logic used to decide which ref\nis updated with git-send-pack.  We used to error out when\npushing 'master' when the other end has both 'master' branch and\na tracking branch 'remotes/$name/master' but with this, 'master'\nmatches only 'refs/heads/master' when both and no other 'master'\nexist.\n\nPushing 'foo' when both heads/foo and tags/foo exist at the\nremote end is still considered an error and you would need to\ndisambiguate between them by being more explicit.\n\nWhen neither heads/foo nor tags/foo exists at the remote,\npushing 'foo' when there is only remotes/origin/foo is not\nambiguous, while it still is ambiguous when there are more than\none such weaker match (remotes/origin/foo and remotes/alt/foo,\nfor example).\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\ndiff --git a/connect.c b/connect.c\nindex c55a20a..b9666cc 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -174,21 +174,58 @@ static int count_refspec_match(const cha\n \t\t\t       struct ref *refs,\n \t\t\t       struct ref **matched_ref)\n {\n-\tint match;\n \tint patlen = strlen(pattern);\n+\tstruct ref *matched_weak = NULL;\n+\tstruct ref *matched = NULL;\n+\tint weak_match = 0;\n+\tint match = 0;\n \n-\tfor (match = 0; refs; refs = refs->next) {\n+\tfor (weak_match = match = 0; refs; refs = refs->next) {\n \t\tchar *name = refs->name;\n \t\tint namelen = strlen(name);\n+\t\tint weak_match;\n+\n \t\tif (namelen < patlen ||\n \t\t    memcmp(name + namelen - patlen, pattern, patlen))\n \t\t\tcontinue;\n \t\tif (namelen != patlen && name[namelen - patlen - 1] != '/')\n \t\t\tcontinue;\n-\t\tmatch++;\n-\t\t*matched_ref = refs;\n+\n+\t\t/* A match is \"weak\" if it is with refs outside\n+\t\t * heads or tags, and did not specify the pattern\n+\t\t * in full (e.g. \"refs/remotes/origin/master\") or at\n+\t\t * least from the toplevel (e.g. \"remotes/origin/master\");\n+\t\t * otherwise \"git push $URL master\" would result in\n+\t\t * ambiguity between remotes/origin/master and heads/master\n+\t\t * at the remote site.\n+\t\t */\n+\t\tif (namelen != patlen &&\n+\t\t    patlen != namelen - 5 &&\n+\t\t    strncmp(name, \"refs/heads/\", 11) &&\n+\t\t    strncmp(name, \"refs/tags/\", 10)) {\n+\t\t\t/* We want to catch the case where only weak\n+\t\t\t * matches are found and there are multiple\n+\t\t\t * matches, and where more than one strong\n+\t\t\t * matches are found, as ambiguous.  One\n+\t\t\t * strong match with zero or more weak matches\n+\t\t\t * are acceptable as a unique match.\n+\t\t\t */\n+\t\t\tmatched_weak = refs;\n+\t\t\tweak_match++;\n+\t\t}\n+\t\telse {\n+\t\t\tmatched = refs;\n+\t\t\tmatch++;\n+\t\t}\n+\t}\n+\tif (!matched) {\n+\t\t*matched_ref = matched_weak;\n+\t\treturn weak_match;\n+\t}\n+\telse {\n+\t\t*matched_ref = matched;\n+\t\treturn match;\n \t}\n-\treturn match;\n }\n \n static void link_dst_tail(struct ref *ref, struct ref ***tail)\n"},{"id":"297264","messageId":"ek6dhj$n1l$1@sea.gmane.org","threadId":"43292","inReplyTo":"7vlkm1hf57.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-24T09:22:31Z","receivedAt":"2006-11-24T09:22:31Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> Petr Baudis <pasky@suse.cz> writes:\n> \n>>> Even though I fully agree that use-separate-remotes should be\n>>> the default, to the point that I think we do not even\n>>> need a backward compatibility option.  People who want to use\n>>> traditional layout for simple one-remote-branch-only project\n>>> would not suffer anyway because 'origin' still means origin in\n>>> the new layout (refs/remotes/origin/HEAD).\n>>\n>> I don't know, we still at least need to keep the functionality for\n>> --bare.\n\nBy the way, I think the backward compatibility option should be\nsimply named --dont-use-separate-remote, or --without-separate-remote,\nor --no-separate-remote (the last is probably the best choice).\n\n> I agree --bare should continue to be a \"snapshot mirror\"; I am\n> not advocating for the removal of the internal implementation\n> detail such as $use_separate_remote variable.\n> \n> However, I think having one sane behaviour is the right thing to\n> do for a clone that prepares a repository with a working tree\n> (including the one made with -n option, which only means \"do not\n> do the check-out immediately after cloning\" for such a\n> repository).\n> \n> The traditional layout is slightly simpler for a project with\n> the simplest needs (that is, a single upstream repository that\n> has a single 'master' branch), but I do think even that is not\n> an advantage anymore.\n> \n> With the separate-remote layout, git-fetch would still fetch and\n> update the \"origin\" (although that is now remotes/origin/master\n> which is pointed at by remotes/origin/HEAD) and the user can\n> still refer to it with \"origin\".  Commands \"git-pull origin\",\n> \"git-pull . origin\", and \"git-merge origin\" all will continue to\n> work the same way as before for such a project as in the\n> traditional layout, and that is why I think we do not need\n> backward compatibility flag in this case.\n \nThe exception being that with --use-separate-remote you cannot checkout\ntracking branches to see what it is there (at least for now, but IIRC we\nwant to relax this constraint; i.e. to forbid commiting to non-heads,\ninstead of forbidding checking out), you cannot use it as alternate\nsource (as alternate repo to check from) while still allowing to work\non it, and that gitweb doesn't show anything except heads and tags;\nit doesn't show remotes.\n\nBy the way, does new \"git peek-remote -a .\" show anything except\nrefs/heads/, refs/tags/ and refs/remotes (e.g. StGit refs/bases/\nand refs/patches/)?\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"295714","messageId":"ek6for$ti5$1@sea.gmane.org","threadId":"43292","inReplyTo":"20061123225835.30071.99265.stgit@machine.or.cz","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Salikh Zakirov","fromEmail":"salikh.zakirov@intel.com","sentAt":"2006-11-24T09:58:47Z","receivedAt":"2006-11-24T09:58:47Z","isPatch":true,"sender":{"key":"salikh.zakirov@gmail.com","avatar":null},"body":"Petr Baudis wrote:\n> --- a/Documentation/git-clone.txt\n> +++ b/Documentation/git-clone.txt\n> ...\n>  --use-separate-remote::\n>  \tSave remotes heads under `$GIT_DIR/remotes/origin/` instead\n> -\tof `$GIT_DIR/refs/heads/`.  Only the master branch is saved\n> -\tin the latter.\n\nThis description does not apply to repositories which do not have 'master' branch.\nMaybe \"only the HEAD branch of remote repository, where\nHEAD is the branch designated as main branch in repository\".\n"},{"id":"298274","messageId":"ek6glc$pn$1@sea.gmane.org","threadId":"43292","inReplyTo":"7vpsbde4fy.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Salikh Zakirov","fromEmail":"salikh.zakirov@intel.com","sentAt":"2006-11-24T10:14:00Z","receivedAt":"2006-11-24T10:14:00Z","isPatch":true,"sender":{"key":"salikh.zakirov@gmail.com","avatar":null},"body":"Junio C Hamano wrote:\n> -- >8 --\n> [PATCH] refs outside refs/{heads,tags} match less strongly.\n> \n> Pushing 'foo' when both heads/foo and tags/foo exist at the\n> remote end is still considered an error and you would need to\n> disambiguate between them by being more explicit.\n> \n> When neither heads/foo nor tags/foo exists at the remote,\n> pushing 'foo' when there is only remotes/origin/foo is not\n> ambiguous, while it still is ambiguous when there are more than\n> one such weaker match (remotes/origin/foo and remotes/alt/foo,\n> for example).\n\ngit-push.1 has following description:\n\n    Some short-cut notations are also supported.\n\n              o   tag <tag> means the same as refs/tags/<tag>:refs/tags/<tag>.\n\n              o  A parameter <ref> without a colon is equivalent to\n                 <ref>:<ref>, hence updates <ref>  in\n                 the destination from <ref> in the source.\n\nMaybe this is only my reading of manual page, but I understood\nit like it does not leave the room for ambiguity, because it is using\n_the same_ refspec as the local one.\n\nThat's why, when I do\n\n   git-push repo x\n\nand it results in\n\n   git-push repo refs/heads/x:refs/remotes/origin/x\n\ninstead of expected\n\n   git-push repo refs/heads/x:refs/heads/x\n\njust because the remote repo did not have refs/heads/x, but happened\nto have refs/remotes/origin/x, would be highly surprising to me.\n\nThe expected behaviour on 'git-push repo x' in my understanding is\n1) git finds the exact reference for 'x' (i.e. either refs/heads/x or\nrefs/tags/x) according to local lookup rules\n2) git uses the found reference _unambiguously_ to create or update exactly the\nsame reference in the remote repo.\n\nAm I the only one to have this understanding?\n"},{"id":"298430","messageId":"7vslg9axzv.fsf@assigned-by-dhcp.cox.net","threadId":"43292","inReplyTo":"ek6glc$pn$1@sea.gmane.org","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-24T11:24:20Z","receivedAt":"2006-11-24T11:24:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Salikh Zakirov <Salikh.Zakirov@Intel.com> writes:\n\n> git-push.1 has following description:\n>\n>     Some short-cut notations are also supported.\n>\n>               o   tag <tag> means the same as refs/tags/<tag>:refs/tags/<tag>.\n>\n>               o  A parameter <ref> without a colon is equivalent to\n>                  <ref>:<ref>, hence updates <ref>  in\n>                  the destination from <ref> in the source.\n>\n> Maybe this is only my reading of manual page, but I understood\n> it like it does not leave the room for ambiguity, because it is using\n> _the same_ refspec as the local one.\n\nIf you write\n\n\tgit push $remote tag $string\n\nit is handled exactly as if you wrote:\n\n\tgit push $remote refs/tags/${string}:refs/tags/${string}\n\nand if you write\n\n\tgit push $remote master\n\nit is handled exactly as if you wrote:\n\n\tgit push $remote master:master\n\nThe manual correctly describes the above, but the issue the fix\naddresses is about what happens to that 'master' string that\nfollows the colon, and the 'master' string becomes ambiguous if\nthe remote end uses separate-remote layout.\n\nThe way this command:\n\n\tgit push $remote $src:$dst\n\nis handled is:\n\n (0) send-pack gets ls-remote equivalent from the remote.  This\n     tells us the set of refs the remote has and the value of\n     each of them.\n\n (1) $src can be a ref that is resolved locally the usual way.\n     You could have any valid SHA-1 expression (e.g. HEAD~6).\n\n (2) $dst is compared with the list of refs that the remote\n     has, and unique match is found.  So if the set of refs the\n     remote side has:\n\n\trefs/heads/origin\n        refs/heads/master\n        refs/tags/v1.0.0\n\n     and if $dst is 'master', refs/heads/master is what will be\n     updated.\n\n (3) Then send-pack generates and sends the necessary pack to\n     update the remote side with objects needed for $src, using\n     the knowledge of what the remote has.  Also, send-pack\n     instructs the remote to update which ref with what value.\n     Continuing with the example, it tells the remote to update\n     its refs/heads/master with the value of our 'master'.\n\nThat *matching* in step (2) is what the fix is about.\n\nThe matching code of send-pack from the beginning has been the\nunique tail-match.  When the other end had a branch 'bugfix' and\na tag 'bugfix', then both of them would match because both\nrefs/heads/bugfix and refs/tags/bugfix ends with 'bugfix'\n('gfix' does not match 'refs/heads/bugfix' -- we are not that\nstupid ;-).\n\nSo you had to disambiguate this case by saying heads/bugfix if\nyou want to push the branch.  That was fine between branches and\ntags, since having a branch and a tag with the same name is\nusually not done in order to keep user's sanity.\n\nHowever, separate-remote layout poses a more serious problem,\nbecause most of the time you would expect to see similar names\nunder refs/heads/ and refs/remotes/origin/ directories.  If we\nkept the original ref matching code, a cloned remote would have\nboth refs/heads/master and refs/remotes/origin/master almost\nalways, so somebody who is pushing 'master' to such a remote\nwould have had to disambiguate it by saying:\n\n\tgit push heads/master\n\nwhich is (as described in the part of the manual you quoted) a\nshorthand for\n\n\tgit push heads/master:heads/master\n\n'heads/master' before the colon is used to find out which commit\nin your local repository we are pushing, and 'heads/master'\nafter the colon is used to match against the list of refs from\nthe remote (which contains both 'refs/heads/master' and\n'refs/remotes/origin/master'), and only because the user said\n'heads/master' (not just 'master') this avoids ambiguity.\n\nEven under separate-remote layout, we would want to be able to\nsay:\n\n\tgit push master\n\nto mean we want to push to remote's heads/master when the remote\nhas remotes/{origin,blech}/master.\n\nAnd that is what the fix is about.\n\n"},{"id":"298464","messageId":"20061124143200.52aa1901.vsu@altlinux.ru","threadId":"43292","inReplyTo":"ek6glc$pn$1@sea.gmane.org","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Sergey Vlasov","fromEmail":"vsu@altlinux.ru","sentAt":"2006-11-24T11:32:00Z","receivedAt":"2006-11-24T11:32:00Z","isPatch":true,"sender":{"key":"vsu@altlinux.ru","avatar":"https://avatars.githubusercontent.com/u/616082?v=4"},"body":"On Fri, 24 Nov 2006 13:14:00 +0300 Salikh Zakirov wrote:\n\n> git-push.1 has following description:\n>\n>     Some short-cut notations are also supported.\n>\n>               o   tag <tag> means the same as refs/tags/<tag>:refs/tags/<tag>.\n\nBTW, this is broken (and was broken even in 1.4.3.x):\n\n$ mkdir ~/tmp/test_repo\n$ ( cd ~/tmp/test_repo; git-init-db )\ndefaulting to local storage area\n$ git push ~/tmp/test_repo tag v1.4.4.1\nerror: src refspec tag does not match any.\nerror: dst refspec tag does not match any existing ref on the remote and does not start with refs/.\nfatal: unexpected EOF\n\nOmitting the \"tag\" word works:\n\n$ git push ~/tmp/test_repo v1.4.4.1\nupdating 'refs/tags/v1.4.4.1'\n  from 0000000000000000000000000000000000000000\n  to   21dff5f4982333d694d105595a701540d4d0d1db\nGenerating pack...\nDone counting 28130 objects.\nDeltifying 28130 objects.\n 100% (28130/28130) done\nWriting 28130 objects.\n 100% (28130/28130) done\nTotal 28130, written 28130 (delta 19344), reused 27628 (delta 18891)\nrefs/tags/v1.4.4.1: 0000000000000000000000000000000000000000 -> 21dff5f4982333d694d105595a701540d4d0d1db\n\nSeems that nobody really uses the \"tag NAME\" syntax...\n\n>               o  A parameter <ref> without a colon is equivalent to\n>                  <ref>:<ref>, hence updates <ref>  in\n>                  the destination from <ref> in the source.\n>\n> Maybe this is only my reading of manual page, but I understood\n> it like it does not leave the room for ambiguity, because it is using\n> _the same_ refspec as the local one.\n>\n> That's why, when I do\n>\n>    git-push repo x\n>\n> and it results in\n>\n>    git-push repo refs/heads/x:refs/remotes/origin/x\n>\n> instead of expected\n>\n>    git-push repo refs/heads/x:refs/heads/x\n>\n> just because the remote repo did not have refs/heads/x, but happened\n> to have refs/remotes/origin/x, would be highly surprising to me.\n\nSuch interpretation would indeed be horrible, but I'm afraid this is\nexactly the case now:\n\n$ mkdir ~/tmp/test_repo\n$ ( cd ~/tmp/test_repo; git-init-db )\ndefaulting to local storage area\n$ git push ~/tmp/test_repo v1.4.0^0:refs/remotes/origin/master\nupdating 'refs/remotes/origin/master' using 'v1.4.0^0'\n  from 0000000000000000000000000000000000000000\n  to   41292ddd37202ff6dce34986c87a6000c5d3fbfa\nGenerating pack...\nDone counting 19857 objects.\nDeltifying 19857 objects.\n 100% (19857/19857) done\nWriting 19857 objects.\n 100% (19857/19857) done\nTotal 19857, written 19857 (delta 13472), reused 19038 (delta 12884)\nrefs/remotes/origin/master: 0000000000000000000000000000000000000000 -> 41292ddd37202ff6dce34986c87a6000c5d3fbfa\n\n$ git push ~/tmp/test_repo master\nupdating 'refs/remotes/origin/master' using 'refs/heads/master'\n  from 41292ddd37202ff6dce34986c87a6000c5d3fbfa\n  to   e945f95157c2c515e763ade874931fc1eb671a0b\nGenerating pack...\nDone counting 8667 objects.\nResult has 8278 objects.\nDeltifying 8278 objects.\n 100% (8278/8278) done\nWriting 8278 objects.\n 100% (8278/8278) done\nTotal 8278, written 8278 (delta 5924), reused 7396 (delta 5065)\nrefs/remotes/origin/master: 41292ddd37202ff6dce34986c87a6000c5d3fbfa -> e945f95157c2c515e763ade874931fc1eb671a0b\n\nBTW, I cannot find the description of the matching algorithm used by\nconnect.c:count_refspec_match() anywhere in the git-push or git-fetch\nman page, and I cannot understand why this algorithm is different from\nthe default search order ($name, refs/$name, refs/tags/$name,\nrefs/heads/$name, refs/remotes/$name, refs/remotes/$name/HEAD).\n\n> The expected behaviour on 'git-push repo x' in my understanding is\n> 1) git finds the exact reference for 'x' (i.e. either refs/heads/x or\n> refs/tags/x) according to local lookup rules\n> 2) git uses the found reference _unambiguously_ to create or update\n> exactly the same reference in the remote repo.\n>\n> Am I the only one to have this understanding?\n\nThe problem is that \"$x\" and \"$x:$x\" would be not equivalent anymore,\nunless we add a special case for \"$x:$y\" where $x == $y - hmm, but the\ncurrent code seems to have that special case:\n\n\t\t\telse if (!strcmp(rs[i].src, rs[i].dst) &&\n\t\t\t\t matched_src) {\n\t\t\t\t/* pushing \"master:master\" when\n\t\t\t\t * remote does not have master yet.\n\t\t\t\t */\n\n(but that code triggers only in case we did not find any matching ref in\nthe destination repo).\n"},{"id":"298716","messageId":"7vodqxaxe4.fsf@assigned-by-dhcp.cox.net","threadId":"43292","inReplyTo":"20061124143200.52aa1901.vsu@altlinux.ru","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-24T11:37:23Z","receivedAt":"2006-11-24T11:37:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sergey Vlasov <vsu@altlinux.ru> writes:\n\n> BTW, this is broken (and was broken even in 1.4.3.x):\n>\n> $ mkdir ~/tmp/test_repo\n> $ ( cd ~/tmp/test_repo; git-init-db )\n> defaulting to local storage area\n> $ git push ~/tmp/test_repo tag v1.4.4.1\n> error: src refspec tag does not match any.\n> error: dst refspec tag does not match any existing ref on the remote and does not start with refs/.\n> fatal: unexpected EOF\n>\n> Omitting the \"tag\" word works:\n\nI think this was broken when git-push was made a built-in, and\nthe documentation was not updated.\n\nI use only tags in vN.M.L.. format and Linus does so too, so\nprobably that was one of the reasons why this was not noticed\nfor quite some time.\n\nFixes welcome, preferably to the builtin-push.c not to the\ndocumentation.\n"},{"id":"297804","messageId":"ek6mm5$j2f$1@sea.gmane.org","threadId":"43292","inReplyTo":"7vslg9axzv.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Salikh Zakirov","fromEmail":"salikh.zakirov@intel.com","sentAt":"2006-11-24T11:56:52Z","receivedAt":"2006-11-24T11:56:52Z","isPatch":true,"sender":{"key":"salikh.zakirov@gmail.com","avatar":null},"body":"Junio C Hamano wrote:\n> and if you write\n> \n> \tgit push $remote master\n> \n> it is handled exactly as if you wrote:\n> \n> \tgit push $remote master:master\n> \n> The manual correctly describes the above, but the issue the fix\n> addresses is about what happens to that 'master' string that\n> follows the colon, and the 'master' string becomes ambiguous if\n> the remote end uses separate-remote layout.\n\nIndeed, the manual describes it correctly.\nMy point is that this semantics fairly complex\nand easy to understand incorrectly.\n\n> Even under separate-remote layout, we would want to be able to\n> say:\n> \n> \tgit push master\n> \n> to mean we want to push to remote's heads/master when the remote\n> has remotes/{origin,blech}/master.\n\nI agree with your main point that 'git push master' should \"just work\"\nfor all existing and new repositories, however,\nit is very confusing that 'git push master' can update something other than\nrefs/heads/master, depending on the refs existing in the remote repo.\n"},{"id":"295563","messageId":"ek7v61$k89$1@sea.gmane.org","threadId":"43292","inReplyTo":"7vslg9axzv.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Salikh Zakirov","fromEmail":"salikh@gmail.com","sentAt":"2006-11-24T23:28:02Z","receivedAt":"2006-11-24T23:28:02Z","isPatch":true,"sender":{"key":"salikh@gmail.com","avatar":"https://gravatar.com/avatar/952c102bb1dcf721dab8de4f5a11d276756a65d301d021f755e265cc3251efae?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> The way this command:\n> \n> \tgit push $remote $src:$dst\n> \n> is handled is:\n> \n>  (0) send-pack gets ls-remote equivalent from the remote.  This\n>      tells us the set of refs the remote has and the value of\n>      each of them.\n> \n>  (1) $src can be a ref that is resolved locally the usual way.\n>      You could have any valid SHA-1 expression (e.g. HEAD~6).\n\n>  (2) $dst is compared with the list of refs that the remote\n>      has, and unique match is found.\n\nI think that remote matching semantics is confusing, and the following change\nwould make understanding easier.\n\nI was understanding the manual incorrectly for a long time until you've\nexplained its true meaning today (thanks!).\n\nAs a side effect, making 'git push repo master' unambiguously expanded\nto 'git push repo refs/heads/master:refs/heads/master' will make\nthe syntax 'git push repo tag v1' unneeded at all, because it would be\nexactly the same as 'git push repo v1'\n(expanded to 'git push repo refs/tags/v1:refs/tags/v1').\n\n--- connect.c\n+++ connect.c\n@@ -277,6 +277,16 @@ static int match_explicit_refs(struct re\n                              rs[i].src);\n                        break;\n                }\n+               if (!strcmp(rs[i].src,rs[i].dst)) {\n+                       /* src refspec is the same as dst,\n+                        * take the remote refpath exactly the same\n+                        * as existing local reference\n+                        */\n+                       int len = strlen(matched_src->name) + 1;\n+                       matched_dst = xcalloc(1, sizeof(*dst) + len);\n+                       memcpy(matched_dst->name, matched_src->name, len);\n+                       link_dst_tail(matched_dst, dst_tail);\n+               } else\n                switch (count_refspec_match(rs[i].dst, dst, &matched_dst)) {\n                case 1:\n                        break;\n"},{"id":"294246","messageId":"7v3b889ysd.fsf@assigned-by-dhcp.cox.net","threadId":"43292","inReplyTo":"ek7v61$k89$1@sea.gmane.org","subject":"Re: [PATCH] Make git-clone --use-separate-remote the default","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-25T00:04:50Z","receivedAt":"2006-11-25T00:04:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Salikh Zakirov <salikh@gmail.com> writes:\n\n> I think that remote matching semantics is confusing, and the following change\n> would make understanding easier.\n\nHmm.  I think this is somewhat wrong.\n\nHave you tested the patch with repositories with existing refs?\n\nYou do not seem to check if that fabricated matched_dst exists\non the other side, so matched_dst lacks \"where was this ref\ninitially\" information (aka old_sha1), if I am reading your\npatch correctly.  Wouldn't that mean that you would confuse the\nfast-forward check logic?\n\nOne setup I have that would be broken with this change is that\nthe remote end has refs/heads/up/obsd and no refs/heads/obsd,\nand local end has refs/heads/obsd.  This is to work on\nportability fix for OpenBSD.  With the current git-push, I think\n\n\tgit push $remote_openbsd_box obsd\n\nwould correctly update the remote refs/heads/up/obsd with the\nlocal tip of the obsd branch, so that then I can ssh into the\nremote and say \"git merge up/obsd\" to continue on that OpenBSD\nmachine from where I left off on the local, non-OpenBSD machine.\n\nI am not sure if people would mind breaking existing setups like\nthis.\n\nBy the way, there are other glitches with the current git-push\n(rather, git-send-pack) that we need to tighten.  For example:\n\n\tgit push $remote HEAD~6\n\ndoes not error out as it should.  'HEAD~6' is expanded to\n'HEAD~6:HEAD~6'; its left hand side is valid (6 revs before the\ntip is used to update the remote side) but its right hand side\nis not checked for validity (\"HEAD~6\" is not a valid refname)\nand creates .git/HEAD~6 at the remote end which is completely\nbogus.\n"}]}