{"thread":{"id":"34487","subject":"Git Clone Parameter","startedAt":"2013-07-19T09:21:01Z","lastAt":"2013-07-19T19:10:14Z","messageCount":10,"participants":["Allan Acheampong","Ramkumar Ramachandra","Johannes Sixt","Junio C Hamano","Philip Oakley"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"223741","messageId":"FB572366-0B1D-4053-9255-979CB213B160@gmail.com","threadId":"34487","inReplyTo":null,"subject":"Git Clone Parameter","fromName":"Allan Acheampong","fromEmail":"allanadjei@gmail.com","sentAt":"2013-07-19T09:21:01Z","receivedAt":"2013-07-19T09:21:01Z","isPatch":false,"sender":{"key":"allanadjei@gmail.com","avatar":null},"body":"Hi,\n\nit would be nice to have a parameter on 'git clone' that not only clones the repo, but also creates local branches for ALL the branches that are in the repo. I'm new to git, but I found it very confusing to understand the difference between \"remote\" , \"remotes\". Is it in the cloned repo, or is it in  a remote place? If its local, why doesn't it get shown when I do 'git branch' but when I do 'git branch -a'. For example, I create a project locally with multiple branches, push it, delete it locally and clone it back to my machine. On a 'git branch' I would only see the head branch. I understand that there are projects that have a lot of branches that are not needed for that specific developer, but still it would be nice if one could specify this at clone time. Something like 'git clone <theR\n epo> -createLocalBranchesForAllBranches' . Of course the param shouldn't be that long. I could write a script with for each in but thats way too much hassle and effort for something that should be there already and I don't think I am the first to get confused by this.\n\nI'd like to know your opinions about that and what you think about the suggestion.\nAllan."},{"id":"223742","messageId":"CALkWK0=q62SmQwDPKjRv+Z8D59Uy=Kpanth8QFYFJ=xOA5JCtw@mail.gmail.com","threadId":"34487","inReplyTo":"FB572366-0B1D-4053-9255-979CB213B160@gmail.com","subject":"Re: Git Clone Parameter","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-07-19T10:01:29Z","receivedAt":"2013-07-19T10:01:29Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Allan Acheampong wrote:\n> I could write a script with for each in but thats way too much hassle\n\n  $ git for-each-ref --format=\"%(refname)\" refs/remotes/origin/ | sed\n's/refs\\/remotes\\/origin\\///;/HEAD\\|master/d' | xargs git checkout -b\n\n(completely untested ofcourse)\n\nDo you see what the problem is immediately?  There's nothing special\nabout \"origin\": I could have branches with the same name on several\nremotes.  Without detaching local branches from remote branches, there\nis no distributed workflow: your central workflow is just a special\ncase.\n"},{"id":"223760","messageId":"51E94025.3090802@viscovery.net","threadId":"34487","inReplyTo":"FB572366-0B1D-4053-9255-979CB213B160@gmail.com","subject":"Re: Git Clone Parameter","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2013-07-19T13:33:25Z","receivedAt":"2013-07-19T13:33:25Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 7/19/2013 11:21, schrieb Allan Acheampong:\n> Something like 'git clone <theRepo> -createLocalBranchesForAllBranches'\n\nPerhaps:\n\n$ git clone theRepo\n$ git fetch origin refs/heads/*:refs/heads/*\n\n(untested). There may be ways to write the same shorter, but I've lost\ntrack of what is and what is not possible in refspec.\n\n-- Hannes\n"},{"id":"223767","messageId":"7v4nbqzj7u.fsf@alter.siamese.dyndns.org","threadId":"34487","inReplyTo":"FB572366-0B1D-4053-9255-979CB213B160@gmail.com","subject":"Re: Git Clone Parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-07-19T15:02:13Z","receivedAt":"2013-07-19T15:02:13Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Allan Acheampong <allanadjei@gmail.com> writes:\n\n> ... I'm new to git, but I found it very\n> confusing to understand the difference between \"remote\" ,\n> \"remotes\". Is it in the cloned repo, or is it in a remote place?\n> If its local, why doesn't it get shown when I do 'git branch' but\n> when I do 'git branch -a'.\n> ...\n> For example, I create a project locally\n> with multiple branches, push it, delete it locally and clone it\n> back to my machine. On a 'git branch' I would only see the head\n> branch.\n> ...\n> I'd like to know your opinions about that and what you think about\n> the suggestion.\n\nNot very interested, for a few reasons:\n\n (1) It is actively harmful if the aim is to blur the distinction\n     between local branches and remote-tracking branches. New users\n     will be in a lot of hurt if they are not aware that the\n     'master' branch in their repository is unique and different\n     from the 'master' branch of everybody else's repository and the\n     'origin' remote repository they cloned from.\n\n (2) It is not necessary. You can do interesting things to the\n     history on your local branch, like creating new commits to grow\n     the branch, only after checking it out. And modern Git lets you\n     say\n\n     $ git checkout topic\n\n     and it DWIMs the request to \"check out the topic branch\" to do\n     the equivalent of\n\n     $ git branch -t topic origin/topic && git checkout topic\n\n     when 'topic' does not exist as your local branch and there is a\n     single remote (i.e. 'origin') that has a remote-tracking branch\n     of that same name 'topic'. This lets you create a corresponding\n     local branch lazily any time you want to work on extending the\n     work on a branch taken from the remote, and output from \"git\n     branch --list\" to be meaningful: it only lists your local\n     branch, the ones you have already said that you are interested\n     in working on in this repository.\n\n (3) It makes \"git branch --list\" output less useful if you create\n     local branches that correspond to all the branches taken from\n     the remote.  You cannot tell which ones you have worked on and\n     which ones you haven't even touched yet.\n\nHaving said that, it is fairly trivial to script it, if you really\nwant to do so, ignoring all of the above downsides.  Something like:\n\n\tgit for-each-ref --format='%(refname)' refs/remotes/origin/ |\n\tsed -e 's|^refs/remotes/origin/||' -e '/^HEAD$/d' |\n\twhile read branchname\n        do\n\t\tgit show-ref -q --verify \"refs/heads/$branchname\" ||\n                git branch -t \"$branchname\" \"origin/$branchname\"\n\tdone\n\nBut for the reasons stated, it is not a particularly good way to\nwork to start from many local branches that are copies of all the\nremote-tracking branches, many of which you may not even touch, so I\npersonally do not think we would want to add such an option to\n\"clone\".  The implementation would be fairly trivial, as you can see\nfrom the \"trivial script\" above, but it would encourage a wrong\nworkflow.\n\nOlder Git around 1.4.x days used to conflate remote-tracking\nbranches and local branches, and threw everything in refs/heads/\nhierarchy, which had the exact set of problems above, and that is\nwhy modern Git uses refs/remotes/origin/ hierarchy to store the\nremote-tracking branches separately, for less cluttered local branch\nnamespace.\n"},{"id":"223768","messageId":"7vzjtiy4mh.fsf@alter.siamese.dyndns.org","threadId":"34487","inReplyTo":"51E94025.3090802@viscovery.net","subject":"Re: Git Clone Parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-07-19T15:02:46Z","receivedAt":"2013-07-19T15:02:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> Am 7/19/2013 11:21, schrieb Allan Acheampong:\n>> Something like 'git clone <theRepo> -createLocalBranchesForAllBranches'\n>\n> Perhaps:\n>\n> $ git clone theRepo\n> $ git fetch origin refs/heads/*:refs/heads/*\n>\n> (untested). There may be ways to write the same shorter, but I've lost\n> track of what is and what is not possible in refspec.\n\nThat would overwrite your local branch and would not give you any\ntracking, no?\n"},{"id":"223769","messageId":"7vvc46y4il.fsf@alter.siamese.dyndns.org","threadId":"34487","inReplyTo":"CALkWK0=q62SmQwDPKjRv+Z8D59Uy=Kpanth8QFYFJ=xOA5JCtw@mail.gmail.com","subject":"Re: Git Clone Parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-07-19T15:05:06Z","receivedAt":"2013-07-19T15:05:06Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Allan Acheampong wrote:\n>> I could write a script with for each in but thats way too much hassle\n>\n>   $ git for-each-ref --format=\"%(refname)\" refs/remotes/origin/ | sed\n> 's/refs\\/remotes\\/origin\\///;/HEAD\\|master/d' | xargs git checkout -b\n>\n> (completely untested ofcourse)\n\nYou would at least need \"xargs -n 1\" for the produced command line\nto make any sense, and it is wasteful to actually check out each\nand every branch to the working tree only to create it.\n"},{"id":"223773","messageId":"CALkWK0kdVrsLy=pwZvn5de+L54gWbU0hmDTXpHHDKQbXiE_wdw@mail.gmail.com","threadId":"34487","inReplyTo":"7vvc46y4il.fsf@alter.siamese.dyndns.org","subject":"Re: Git Clone Parameter","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-07-19T15:44:11Z","receivedAt":"2013-07-19T15:44:11Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> You would at least need \"xargs -n 1\" for the produced command line\n> to make any sense, and it is wasteful to actually check out each\n> and every branch to the working tree only to create it.\n\nRight.  xargs -n 1, git branch, and refname:short.\n"},{"id":"223774","messageId":"CALkWK0nRDxV-m4Bwr2Q7kbzQr8K++0nTDqzeh=tfA=a7ahAs7A@mail.gmail.com","threadId":"34487","inReplyTo":"7v4nbqzj7u.fsf@alter.siamese.dyndns.org","subject":"Re: Git Clone Parameter","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-07-19T15:47:07Z","receivedAt":"2013-07-19T15:47:07Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n>               git branch -t \"$branchname\" \"origin/$branchname\"\n\nA couple of notes here:\n\n1. I use git branch -u personally.  Why the -t variant?\n2. Don't we auto-track? (or is that only on checkout)\n"},{"id":"223791","messageId":"101D1917805742BE86814C6E6E51C378@PhilipOakley","threadId":"34487","inReplyTo":"7v4nbqzj7u.fsf@alter.siamese.dyndns.org","subject":"Re: Git Clone Parameter","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2013-07-19T17:19:39Z","receivedAt":"2013-07-19T17:19:39Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Junio C Hamano\" <gitster@pobox.com>\nSent: Friday, July 19, 2013 4:02 PM\n> Allan Acheampong <allanadjei@gmail.com> writes:\n>\n>> ... I'm new to git, but I found it very\n>> confusing to understand the difference between \"remote\" ,\n>> \"remotes\". Is it in the cloned repo, or is it in a remote place?\n>> If its local, why doesn't it get shown when I do 'git branch' but\n>> when I do 'git branch -a'.\n\nAllan,\nThis (not being sure about local remote branches and distant remote\nbranches, while coping with multiple remote servers) appears to be a\ncommon problem for new folks, which those well versed in the use of Git\nhave become well used to so don't see the problem.\n\nFor the uninitiated, the lack of distinct terminology can cause no end\nof confusion as most explanations presume that you will implicitly\nunderstand the context, which can't be true for such newbies. It doesn't\nhelp that the 'remotes' model of the Git DVCS fits a work flow style\nthat isn't the same as the expectation of the newbie.\n\nFor example, in a larger collaboration there can be many many branches\n(on a communal server) that essentially belong to other contributors\nwhich one would never be interested in, and you (and they) would want\nignored.\n\n>> ...\n>> For example, I create a project locally\n>> with multiple branches, push it, delete it locally and clone it\n>> back to my machine. On a 'git branch' I would only see the head\n>> branch.\n\nJunio explains below how your suggestion of 'only the head branch'\nviewpoint is too limiting (among other things).\n\nThat said, if you have a terminology for the distinction between the\nconfusing aspects (once understood), then that would be worth something\nto help ease the path of understanding for others. I had the same\nconfusions for a while, and even now have to use some of the awkward\nterminology I used above, so any improvements in that area would be\nuseful. -- Branching models are an endless source of discussion!\n\nPhilip\n\n>> ...\n>> I'd like to know your opinions about that and what you think about\n>> the suggestion.\n>\n> Not very interested, for a few reasons:\n>\n> (1) It is actively harmful if the aim is to blur the distinction\n>     between local branches and remote-tracking branches. New users\n>     will be in a lot of hurt if they are not aware that the\n>     'master' branch in their repository is unique and different\n>     from the 'master' branch of everybody else's repository and the\n>     'origin' remote repository they cloned from.\n>\n> (2) It is not necessary. You can do interesting things to the\n>     history on your local branch, like creating new commits to grow\n>     the branch, only after checking it out. And modern Git lets you\n>     say\n>\n>     $ git checkout topic\n>\n>     and it DWIMs the request to \"check out the topic branch\" to do\n>     the equivalent of\n>\n>     $ git branch -t topic origin/topic && git checkout topic\n>\n>     when 'topic' does not exist as your local branch and there is a\n>     single remote (i.e. 'origin') that has a remote-tracking branch\n>     of that same name 'topic'. This lets you create a corresponding\n>     local branch lazily any time you want to work on extending the\n>     work on a branch taken from the remote, and output from \"git\n>     branch --list\" to be meaningful: it only lists your local\n>     branch, the ones you have already said that you are interested\n>     in working on in this repository.\n>\n> (3) It makes \"git branch --list\" output less useful if you create\n>     local branches that correspond to all the branches taken from\n>     the remote.  You cannot tell which ones you have worked on and\n>     which ones you haven't even touched yet.\n>\n> Having said that, it is fairly trivial to script it, if you really\n> want to do so, ignoring all of the above downsides.  Something like:\n>\n> git for-each-ref --format='%(refname)' refs/remotes/origin/ |\n> sed -e 's|^refs/remotes/origin/||' -e '/^HEAD$/d' |\n> while read branchname\n>        do\n> git show-ref -q --verify \"refs/heads/$branchname\" ||\n>                git branch -t \"$branchname\" \"origin/$branchname\"\n> done\n>\n> But for the reasons stated, it is not a particularly good way to\n> work to start from many local branches that are copies of all the\n> remote-tracking branches, many of which you may not even touch, so I\n> personally do not think we would want to add such an option to\n> \"clone\".  The implementation would be fairly trivial, as you can see\n> from the \"trivial script\" above, but it would encourage a wrong\n> workflow.\n>\n> Older Git around 1.4.x days used to conflate remote-tracking\n> branches and local branches, and threw everything in refs/heads/\n> hierarchy, which had the exact set of problems above, and that is\n> why modern Git uses refs/remotes/origin/ hierarchy to store the\n> remote-tracking branches separately, for less cluttered local branch\n> namespace.\n>\n"},{"id":"223794","messageId":"7v38rawell.fsf@alter.siamese.dyndns.org","threadId":"34487","inReplyTo":"101D1917805742BE86814C6E6E51C378@PhilipOakley","subject":"Re: Git Clone Parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-07-19T19:10:14Z","receivedAt":"2013-07-19T19:10:14Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Philip Oakley\" <philipoakley@iee.org> writes:\n\n>> Allan Acheampong <allanadjei@gmail.com> writes:\n>>\n>>> ... I'm new to git, but I found it very\n>>> confusing to understand the difference between \"remote\" ,\n>>> \"remotes\". Is it in the cloned repo, or is it in a remote place?\n>>> If its local, why doesn't it get shown when I do 'git branch' but\n>>> when I do 'git branch -a'.\n>\n> For the uninitiated, the lack of distinct terminology can cause no end\n> of confusion as most explanations presume that you will implicitly\n> understand the context, which can't be true for such newbies.\n\nTrue.\n\n * You work in a local repository.\n\n * You interact with repositories other than the local repository.\n   Here, \"to interact\" mean \"exchange the history with\", either by\n   pushing the commits in the local repository to the other one(s),\n   or fetching the commits in the other one(s) to the local\n   repository.\n\n   These \"other repositories\" are \"remote repositories\" from the\n   point of view of the local repository.\n\n   Note that you may have two repositories you use for working on\n   the same project, one on your desktop and one on your notebook.\n   As far as the repository on your notebook is concerned, the\n   repository on your desktop, if you interact with it from the\n   repository on your notebook, is a \"remote repository\" (and the\n   one on the desktop views the one on the notebook as \"remote\").\n\n * Often we call a \"remote repository\" just a \"remote\".  Especially\n   when we give a convenience short-name to it, like \"origin\".\n\n * When you \"clone\" from a repository to create a \"copy\" to work in,\n   from that new repository's point of view, the original repository\n   is a \"remote repository\", and \"git clone\" configures things in\n   the new repository so that you can conveniently interact with\n   that original repository.  The last part is what lets you say\n   \"git fetch origin\", for example, to interact with the \"origin\"\n   remote.\n\n * Branches are local to each repository.  It is merely a social\n   convention that the primary branch in the repository you cloned\n   from (i.e. your \"origin\") is often called 'master', the primary\n   branch in the local repository is called 'master', and you often\n   interact with the history of the 'master' branch of the \"origin\"\n   when you are on your 'master' branch.  There is no stronger tie\n   between their 'master' and your 'master' other than the social\n   convention, but Git makes it easier for you to work that way by\n   setting a few configuration variables.\n\n * Some of the social conventions, and the configuration Git sets up\n   to let you follow them easily, allows you to find out where the\n   tips of branches at your remotes were, when you last observed\n   them (remember, Git is distributed, so you do not ask \"right\n   now\"; instead you have \"when you last observed\" and \"make an\n   observation right now\" separately).  This is achieved by keeping\n   the record of the last observation in \"remote-tracking branches\".\n\n   The last observed value of the 'master' branch of the remote\n   repository \"origin\" is stored as 'origin/master' (its full name\n   is 'refs/remotes/origin/master', but you rarely have to spell it\n   out) remote-tracking branch.\n\n   CAVEAT: some older documentation call a \"remote-tracking branch\"\n   just \"remote branch\", but we have been trying to move away from\n   that practice, as it is confusing, because the 'master' branch at\n   the 'origin' remote is often called a 'remote branch'.  When you\n   see 'remote branch', you need to make sure which one the writer\n   meant.\n\n * \"git fetch\" (and \"git pull\", which internally invokes \"git\n   fetch\") is a way to \"make the observation now\".  \"git fetch\n   origin\" updates your remote-tracking branches for the \"origin\".\n\n * \"git pull\" (and \"git pull --rebase\") is a way to do the \"fetch\"\n   above and then integrate the history of the branch at the remote\n   (which now you know its latest state, because you just observed\n   it) with the history you have on your branch.  Again, these\n   branches may be named 'master' but the user needs to be aware\n   that they are two separate branches (your 'master' branch is just\n   as a different entity from the 'master' branch of the remote\n   repository as it is your 'next' or any other branch).\n\n   To make it easier to work, git configures the history of which\n   branch you obtained/observed from what remote is to be integrated\n   with your history per your local branch.  Immediately after \"git\n   clone\", you will typically have your 'master' branch, and the\n   branch \"knows\" that it wants to integrate with the 'master'\n   branch at 'origin' remote.  So \"git pull\" becomes:\n\n    - \"git fetch origin\", because you will integrate with the\n      history that comes from that remote, not other remotes;\n\n    - which updates 'origin/master' remote-tracking branch, and\n      possibly other remote-tracking branches under 'origin/'; and\n\n    - integrate your branch with the history of 'origin/master'\n      remote-tracking branch.\n\n   We say \"your 'master' branch is set to integrate with\n   remote-tracking branch 'origin/master'\".  It is morally\n   equivalent to say \"your 'master' branch integrates with the\n   'master' branch of 'origin'\".\n\n  CAVEAT: people often call this relationship between your 'master'\n  branch and 'origin/master' (or the 'master' branch of 'origin'\n  remote) \"tracking\", e.g. \"your 'master' branch tracks\n  'origin/master'\".  Unfortunately, this is a confusing misnomer, as\n  the relationship between the 'master' branch of 'origin' and the\n  remote-tracking branch 'orign/master' you have in your local\n  repository is also called \"tracking\" (the latter keeps track of\n  the former).  You are better off avoid using the word \"track\" for\n  this purose, unless it is very clear from the context.\n"}]}