{"thread":{"id":"6731","subject":"Git rescue mission","startedAt":"2007-02-08T00:18:35Z","lastAt":"2007-02-12T06:53:19Z","messageCount":51,"participants":["Bill Lear","Johannes Schindelin","Junio C Hamano","Alexander Litvinov","Jakub Narebski","Linus Torvalds","Kalle Pokki","Shawn O. Pearce","Jeff King","Theodore Tso","Michael S. Tsirkin","Theodore Ts'o"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"33896","messageId":"17866.27739.701406.722074@lisa.zopyra.com","threadId":"6731","inReplyTo":null,"subject":"Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T00:18:35Z","receivedAt":"2007-02-08T00:18:35Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"A perfect example of the sort of trouble I'm having with git just\nhappened again.\n\nI have a public bare repo on my machine that I have cloned to make a\nprivate repo.  I just want to sync my branches on my public and\nprivate repos.  I do not want to merge across branches, I just want to\n\"sync\".\n\nSo, here's what I did.\n\nIn my private repo:\n\n%  cat .git/remotes/origin\nURL: /repos/git/project\nPull: refs/heads/master:refs/heads/origin\nPull: refs/heads/topic:refs/heads/topic\n\nAnd this is the sequence of unfortunate events:\n\nStarting on topic branch:\n\n% git commit -a -m \"Fix spacing rules\"\n% git checkout master\n% git pull\n[Won't pull non-fast-forward on my topic, so I try to get that synced.]\n% git checkout topic\n% git push\n[ok, fine, seems good.]\n[Now, instead of remembering to move back to master, I do this:]\n% git pull\nTrying really trivial in-index merge...\nfatal: Merge requires file-level merging\nNope.\n[AAAAGH!]\nMerging HEAD with 37e229835103a11365b1e081f9b9987a88437e62\nMerging:\ne298e7f Skip rails in user nets\n37e2298 Typofixen.\n[NO NO NO!  This is not what I want!]\nfound 1 common ancestor(s):\na2ba736 Try #2: Fixed (mostly harmless) bugs in handling of time variable.\nAuto-merging src/ast/tstD.cc\nAuto-merging src/meth/XMLImporter.cc\nAuto-merging src/meth/XMLImporter.hh\nAuto-merging src/meth/tstXMLI.cc\nmerge: warning: conflicts during merge\nCONFLICT (content): Merge conflict in src/meth/tstXMLF.cc\nAuto-merging src/nat/MacroFanLoader.cc\nAuto-merging src/nat/VPE.cc\nAuto-merging src/nat/PnDef.cc\nAuto-merging src/nat/VLExporter.hh\nAuto-merging src/nat/tstMod.cc\nAutomatic merge failed; fix conflicts and then commit the result.\n\nOk, now I'm hosed.  Putting aside WHY git would do this to me (yes, I\nknow the answer is that I asked for it), on my topic branch I now have\ntons of files listed when I do git status.  git diff shows tons of\nstuff I don't want in my branch.\n\nSo, I edit the file and \"fix\" the merge conflict, then realize that\nthis is probably not what I want to do at all.\n\nSo, 1) how do I get back to the status quo ante?  I have about 30 files\nlisted as \"Updated but not checked in\", then this:\n\n# Changed but not updated:\n#   (use git-update-index to mark for commit)\n#\n#       unmerged:   src/methodic/tstXMLI.cc\n#       modified:   src/methodic/tstXMLI.cc\n\nwhich I don't want, as I just want them to go away...\n\n2) Why does git pull do the right thing when on master, but seemingly\nchanges behavior when on topic?  I mean, the origin file seems to say\nupdate topic from topic.  It says nothing about updating topic from\nmaster, which is what seems to have happened.  When on master I get my\ndesired \"sync\" behavior, but when on topic, it merges cross-branch...\n\n\nBill\n"},{"id":"33897","messageId":"Pine.LNX.4.63.0702080121240.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6731","inReplyTo":"17866.27739.701406.722074@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-08T00:22:24Z","receivedAt":"2007-02-08T00:22:24Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 7 Feb 2007, Bill Lear wrote:\n\n> So, 1) how do I get back to the status quo ante?  I have about 30 files \n> listed as \"Updated but not checked in\", then this:\n\ngit reset --hard\n\nIt's probably explained in the new user manual (I did not check).\n\nCiao,\nDscho\n"},{"id":"33898","messageId":"17866.28092.167065.520654@lisa.zopyra.com","threadId":"6731","inReplyTo":"Pine.LNX.4.63.0702080121240.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T00:24:28Z","receivedAt":"2007-02-08T00:24:28Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Thursday, February 8, 2007 at 01:22:24 (+0100) Johannes Schindelin writes:\n>Hi,\n>\n>On Wed, 7 Feb 2007, Bill Lear wrote:\n>\n>> So, 1) how do I get back to the status quo ante?  I have about 30 files \n>> listed as \"Updated but not checked in\", then this:\n>\n>git reset --hard\n>\n>It's probably explained in the new user manual (I did not check).\n\nHmm ... from my topic branch:\n\n% git reset -hard\nUsage: /usr/bin/git-reset [--mixed | --soft | --hard]  [<commit-ish>]\n\n\nBill\n"},{"id":"33899","messageId":"Pine.LNX.4.63.0702080125290.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6731","inReplyTo":"17866.28092.167065.520654@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-08T00:25:47Z","receivedAt":"2007-02-08T00:25:47Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 7 Feb 2007, Bill Lear wrote:\n\n> On Thursday, February 8, 2007 at 01:22:24 (+0100) Johannes Schindelin writes:\n> >Hi,\n> >\n> >On Wed, 7 Feb 2007, Bill Lear wrote:\n> >\n> >> So, 1) how do I get back to the status quo ante?  I have about 30 files \n> >> listed as \"Updated but not checked in\", then this:\n> >\n> >git reset --hard\n> >\n> >It's probably explained in the new user manual (I did not check).\n> \n> Hmm ... from my topic branch:\n> \n> % git reset -hard\n> Usage: /usr/bin/git-reset [--mixed | --soft | --hard]  [<commit-ish>]\n\nPlease use two dashes: \"--\" instead of \"-\".\n\nCiao,\nDscho\n"},{"id":"33902","messageId":"17866.28676.442459.501529@lisa.zopyra.com","threadId":"6731","inReplyTo":"Pine.LNX.4.63.0702080125290.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T00:34:12Z","receivedAt":"2007-02-08T00:34:12Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Thursday, February 8, 2007 at 01:25:47 (+0100) Johannes Schindelin writes:\n>\n>Please use two dashes: \"--\" instead of \"-\".\n\nMy apologies.  That does seem to work better...\n\n\nBill\n"},{"id":"33904","messageId":"7vr6t13251.fsf@assigned-by-dhcp.cox.net","threadId":"6731","inReplyTo":"17866.27739.701406.722074@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-08T00:48:42Z","receivedAt":"2007-02-08T00:48:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Bill Lear <rael@zopyra.com> writes:\n\n> 2) Why does git pull do the right thing when on master, but seemingly\n> changes behavior when on topic?\n\nBecause you told it to.\n\n      %  cat .git/remotes/origin\n      URL: /repos/git/project\n      Pull: refs/heads/master:refs/heads/origin\n      Pull: refs/heads/topic:refs/heads/topic\n\nIt tells \"git pull\" to drive \"git fetch\" to copy their master to\nyour origin and overwrite your topic with their topic, and then\nmerge their master to whatever branch you are currently on.\n\nThe sane/safe thing to do in the traditional layout (I'll talk\nabout non-traditional one in a second) is:\n\n - do your 'pull' only and always while on your 'master' and not\n   anywhere else.\n\n - never build on a branch that appears on the RHS of ':'.\n\nThis layout is convenient when you always do fetches and pulls\nwhile on 'master', but has burned enough people.  So what people\non the list seem to recommend is to use a separate remote layout\nin the repository.\n\nThe principle is:\n\n * The branches you work on in the repository are kept in refs/heads/\n\n * Copies of branches from other repositories (it does not\n   matter who is in control of them -- some of them may be your\n   repository) are kept in refs/remotes/<symbolic name>.\n\nSo the current \"git clone\" (if you are using 1.4.4 series, you\ncan say \"git clone --use-separate-remote\") creates something\nlike this instead:\n\n      URL: /repos/git/project\n      Pull: refs/heads/master:refs/remotes/origin/master\n      Pull: refs/heads/topic:refs/remotes/origin/topic\n\n(git-clone from 1.5.0 does not actually make remotes/origin file\nin .git/ that has the above -- it creates the moral equivalent\nin .git/config).\n\nSo whatever you do the first step of \"git pull\", which is \"git\nfetch\", will _not_ overwrite the current branch.\n\nIn order to prevent merging their 'master' into your 'topic'\nwhen you are on 'topic', git-fetch/git-pull from 1.5.0 uses\nfurther safety which is left by 'git clone'.  The real\nconfiguration created by 'git clone' looks like this:\n\n\t[remote \"origin\"]\n        \turl = /repos/git/project\n                fetch = refs/heads/*:refs/remotes/origin/*\n\t[branch \"master\"]\n        \tremote = origin\n                merge = refs/heads/master\n\nThe 'fetch' lines correspond to 'Pull' in .git/remotes/origin file;\nit uses globbing pattern so if there are new branches on the\nremote side you can automatically track them, which is a plus.\n\nBut more importantly, when 'fetch' lines only do the globbing\npattern, 'git pull' without explicitly saying which remote\nbranch you want to merge to the current branch (perhaps by\nmistake) refuses to do a merge, if there is no branch.*.merge\nconfiguration (\"refs/heads/master\" in the above example).  So\nwith the above configuration, 'git pull' from 1.5.0 will fetch\ntwo remote branches and keep them in remotes/origin/master and\nremotes/origin/topic, and if you are on 'master' their\nrefs/heads/master is merged into your current branch, but if you\nare on 'topic', it will not do the merge step (this only applies\nto \"git pull\" without any refspec parameters).\n\nWith 1.4.4 series, I think you can create the [branch] section\nyourself and do something like this:\n\n\t[remote \"origin\"]\n        \turl = /repos/git/project\n                fetch = refs/heads/master:refs/remotes/origin/master\n                fetch = refs/heads/topic:refs/remotes/origin/topic\n\t[branch \"master\"]\n        \tremote = origin\n                merge = refs/heads/master\n\t[branch \"topic\"]\n        \tremote = origin\n                merge = refs/heads/topic\n\nThis configuration also works with 1.5.0, so if you are happy\nwith this (I am assuming you are using 1.4.4 series, preferably\nthe last one, 1.4.4.4), after you upgrade to 1.5.0, it will\ncontinue to do its thing (but you would want to upgrade the\nfetch line).\n"},{"id":"33910","messageId":"200702081028.31493.litvinov2004@gmail.com","threadId":"6731","inReplyTo":"7vr6t13251.fsf@assigned-by-dhcp.cox.net","subject":"Re: Git rescue mission","fromName":"Alexander Litvinov","fromEmail":"litvinov2004@gmail.com","sentAt":"2007-02-08T04:28:31Z","receivedAt":"2007-02-08T04:28:31Z","isPatch":false,"sender":{"key":"litvinov2004@gmail.com","avatar":null},"body":"> In order to prevent merging their 'master' into your 'topic'\n> when you are on 'topic', git-fetch/git-pull from 1.5.0 uses\n> further safety which is left by 'git clone'.  The real\n> configuration created by 'git clone' looks like this:\n>\n> \t[remote \"origin\"]\n>         \turl = /repos/git/project\n>                 fetch = refs/heads/*:refs/remotes/origin/*\n> \t[branch \"master\"]\n>         \tremote = origin\n>                 merge = refs/heads/master\n>\n> The 'fetch' lines correspond to 'Pull' in .git/remotes/origin file;\n> it uses globbing pattern so if there are new branches on the\n> remote side you can automatically track them, which is a plus.\n>\n> But more importantly, when 'fetch' lines only do the globbing\n> pattern, 'git pull' without explicitly saying which remote\n> branch you want to merge to the current branch (perhaps by\n> mistake) refuses to do a merge, if there is no branch.*.merge\n> configuration (\"refs/heads/master\" in the above example).  So\n> with the above configuration, 'git pull' from 1.5.0 will fetch\n> two remote branches and keep them in remotes/origin/master and\n> remotes/origin/topic, and if you are on 'master' their\n> refs/heads/master is merged into your current branch, but if you\n> are on 'topic', it will not do the merge step (this only applies\n> to \"git pull\" without any refspec parameters).\n>\n> With 1.4.4 series, I think you can create the [branch] section\n> yourself and do something like this:\n>\n> \t[remote \"origin\"]\n>         \turl = /repos/git/project\n>                 fetch = refs/heads/master:refs/remotes/origin/master\n>                 fetch = refs/heads/topic:refs/remotes/origin/topic\n> \t[branch \"master\"]\n>         \tremote = origin\n>                 merge = refs/heads/master\n> \t[branch \"topic\"]\n>         \tremote = origin\n>                 merge = refs/heads/topic\n>\n> This configuration also works with 1.5.0, so if you are happy\n> with this (I am assuming you are using 1.4.4 series, preferably\n> the last one, 1.4.4.4), after you upgrade to 1.5.0, it will\n> continue to do its thing (but you would want to upgrade the\n> fetch line).\n\nI think this should go to git-pull/git-clone man pages. Personaly for me this \npost dispels dark magic about git-pull's merging logic. I always did \ngit-fetch and then git-pull . <some-branch> to control what and where should \nbe merged.\n"},{"id":"33940","messageId":"17867.16740.875694.789664@lisa.zopyra.com","threadId":"6731","inReplyTo":"7vr6t13251.fsf@assigned-by-dhcp.cox.net","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T15:27:32Z","receivedAt":"2007-02-08T15:27:32Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Wednesday, February 7, 2007 at 16:48:42 (-0800) Junio C Hamano writes:\n>Bill Lear <rael@zopyra.com> writes:\n>\n>> 2) Why does git pull do the right thing when on master, but seemingly\n>> changes behavior when on topic?\n>\n>Because you told it to.\n>\n>      %  cat .git/remotes/origin\n>      URL: /repos/git/project\n>      Pull: refs/heads/master:refs/heads/origin\n>      Pull: refs/heads/topic:refs/heads/topic\n>\n>It tells \"git pull\" to drive \"git fetch\" to copy their master to\n>your origin and overwrite your topic with their topic, and then\n>merge their master to whatever branch you are currently on.\n>\n>The sane/safe thing to do in the traditional layout (I'll talk\n>about non-traditional one in a second) is:\n>\n> - do your 'pull' only and always while on your 'master' and not\n>   anywhere else.\n\nThis I understand, and can follow.  Sorry, but there my comprehension\nstops.  Lots of confusion and befuddlement follow.  Thank you in\nadvance for being patient.\n\n> - never build on a branch that appears on the RHS of ':'.\n\nThis I don't quite understand.  So, if it is on the LHS, it is ok?\nBut, if it is ALSO on the RHS it is not?\n\nSo, this:\n\n      Pull: refs/heads/topic:refs/heads/topic\n\nreally means don't don't work on a branch named topic in this\nrepository?\n\nI assume by \"build on\" you mean \"work, compile, check stuff in,\netc.\"?.  Did you have something else in mind when you said \"build on\"?\n\n>This layout is convenient when you always do fetches and pulls\n>while on 'master', but has burned enough people.  So what people\n>on the list seem to recommend is to use a separate remote layout\n>in the repository.\n>\n>The principle is:\n>\n> * The branches you work on in the repository are kept in refs/heads/\n>\n> * Copies of branches from other repositories (it does not\n>   matter who is in control of them -- some of them may be your\n>   repository) are kept in refs/remotes/<symbolic name>.\n\nI don't currently have any 'refs/remotes' of any sort, so I guess you\nmean that the new principle, using git clone --use-separate-remote\nwill effect this.\n\n>So the current \"git clone\" (if you are using 1.4.4 series, you\n>can say \"git clone --use-separate-remote\") creates something\n>like this instead:\n>\n>      URL: /repos/git/project\n>      Pull: refs/heads/master:refs/remotes/origin/master\n>      Pull: refs/heads/topic:refs/remotes/origin/topic\n>\n>(git-clone from 1.5.0 does not actually make remotes/origin file\n>in .git/ that has the above -- it creates the moral equivalent\n>in .git/config).\n\nSo, using 1.4.4 series, or 1.5, the \"sane\" way to work in git\nis to use clone --use-separate-remotes.\n\n>So whatever you do the first step of \"git pull\", which is \"git\n>fetch\", will _not_ overwrite the current branch.\n\nI assume by this you mean that if I do the separate remote trick, I\nwill not shoot myself by doing a 'git pull' while on my topic branch,\nas the setup will cause git to refuse to do it.\n\n>In order to prevent merging their 'master' into your 'topic'\n>when you are on 'topic', git-fetch/git-pull from 1.5.0 uses\n>further safety which is left by 'git clone'.  The real\n>configuration created by 'git clone' looks like this:\n>\n>\t[remote \"origin\"]\n>        \turl = /repos/git/project\n>                fetch = refs/heads/*:refs/remotes/origin/*\n>\t[branch \"master\"]\n>        \tremote = origin\n>                merge = refs/heads/master\n>\n>The 'fetch' lines correspond to 'Pull' in .git/remotes/origin file;\n>it uses globbing pattern so if there are new branches on the\n>remote side you can automatically track them, which is a plus.\n>\n>But more importantly, when 'fetch' lines only do the globbing\n>pattern, 'git pull' without explicitly saying which remote\n>branch you want to merge to the current branch (perhaps by\n>mistake) refuses to do a merge, if there is no branch.*.merge\n>configuration (\"refs/heads/master\" in the above example).  So\n>with the above configuration, 'git pull' from 1.5.0 will fetch\n>two remote branches and keep them in remotes/origin/master and\n>remotes/origin/topic, and if you are on 'master' their\n>refs/heads/master is merged into your current branch, but if you\n>are on 'topic', it will not do the merge step (this only applies\n>to \"git pull\" without any refspec parameters).\n\nOk, so if I am on master, I do this:\n\n[master] % git pull\n\nand this will fetch the remote master and merge it to my master, and\nfetch the remote topic and merge it to my local topic.\n\nWhile, if I am on my topic branch, if I do this:\n\n[topic] % git pull\n\nit sill fetches from the remote master and the remote topic, but will\nnot merge at all.\n\nCould you verify if I have stated your position correctly?\n\nIf I am, this still seems bizarre.  I really just want a way to sync\ntwo repos that works consistently, and is invoked consistently, no\nmatter what branch I am currently on.  And, again, by \"sync\", I just\nmean no cross-branch merging --- no \"crossing of the streams\".  Even\nif it were limited to syncing the current branch only, that would be\nok, but this variable behavior seems rather odd and confusing.  In\nother words, I just want to type the equivalent of 'git sync' and have\nit work, and not have to give a branch name, or be in the \"right\nplace\" for it to work as I expect.\n\nThus, I don't want to have to think \"oh, I'm on my topic branch, and\nif I really want to sync from my remote repo, I need to get on my\nmaster branch\".  It seems that the only difference in the \"insane\" way\nI was doing things and the \"sane\" way you propose is that in my way, I\nhad to make this mental leap or get burned by a cross-branch merge,\nbut in the new way, I still have to make this mental leap if I want it\nto work, but if I don't, at least I don't get burned.\n\n\nBill\n"},{"id":"33941","messageId":"eqfh3l$unn$1@sea.gmane.org","threadId":"6731","inReplyTo":"17867.16740.875694.789664@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-02-08T15:56:06Z","receivedAt":"2007-02-08T15:56:06Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Bill Lear wrote:\n> On Wednesday, February 7, 2007 at 16:48:42 (-0800) Junio C Hamano writes:\n>> Bill Lear <rael@zopyra.com> writes:\n>>\n>>> 2) Why does git pull do the right thing when on master, but seemingly\n>>> changes behavior when on topic?\n>>\n>> Because you told it to.\n>>\n>>      %  cat .git/remotes/origin\n>>      URL: /repos/git/project\n>>      Pull: refs/heads/master:refs/heads/origin\n>>      Pull: refs/heads/topic:refs/heads/topic\n>>\n>> It tells \"git pull\" to drive \"git fetch\" to copy their master to\n>> your origin and overwrite your topic with their topic, and then\n>> merge their master to whatever branch you are currently on.\n>>\n>> The sane/safe thing to do in the traditional layout (I'll talk\n>> about non-traditional one in a second) is:\n>>\n>> - do your 'pull' only and always while on your 'master' and not\n>>   anywhere else.\n> \n> This I understand, and can follow.  Sorry, but there my comprehension\n> stops.  Lots of confusion and befuddlement follow.  Thank you in\n> advance for being patient.\n> \n>> - never build on a branch that appears on the RHS of ':'.\n> \n> This I don't quite understand.  So, if it is on the LHS, it is ok?\n> But, if it is ALSO on the RHS it is not?\n\nRHS = right hand side (of refspec). You should not \"build\" on branches\nwhich appear on the right hand side of ':' in the \"Pull:\" lines, in\nthis example they are 'origin' and 'topic'.\n\n> So, this:\n> \n>       Pull: refs/heads/topic:refs/heads/topic\n> \n> really means don't don't work on a branch named topic in this\n> repository?\n\nYes, with this line you should not work on a branch named 'topic';\notherwise badness might follow.\n\n> I assume by \"build on\" you mean \"work, compile, check stuff in,\n> etc.\"?.  Did you have something else in mind when you said \"build on\"?\n\nBy \"build on\" we mean build in SCM (in version control) sense, i.e.\nadding commits on top of given branch (committing when on given branch).\nWell, also do not rewind the branch (reset, rebase,...).\n\n>> This layout is convenient when you always do fetches and pulls\n>> while on 'master', but has burned enough people.  So what people\n>> on the list seem to recommend is to use a separate remote layout\n>> in the repository.\n>>\n>> The principle is:\n>>\n>>  * The branches you work on in the repository are kept in refs/heads/\n>>\n>>  * Copies of branches from other repositories (it does not\n>>    matter who is in control of them -- some of them may be your\n>>    repository) are kept in refs/remotes/<symbolic name>.\n> \n> I don't currently have any 'refs/remotes' of any sort, so I guess you\n> mean that the new principle, using git clone --use-separate-remote\n> will effect this.\n\nIn git 1.4.4 series, \"git clone --use-separate-remote\"; in git 1.5.0\nthis layout is default when making non-bare clone (the only layout,\nI think; were --use-separate-remote and --no-separate-remote removed,\nor only removed from Documentation, by the way? this affects backwards\ncompatibility a bit).\n\n>> So the current \"git clone\" (if you are using 1.4.4 series, you\n>> can say \"git clone --use-separate-remote\") creates something\n>> like this instead:\n>>\n>>      URL: /repos/git/project\n>>      Pull: refs/heads/master:refs/remotes/origin/master\n>>      Pull: refs/heads/topic:refs/remotes/origin/topic\n>>\n>> (git-clone from 1.5.0 does not actually make remotes/origin file\n>> in .git/ that has the above -- it creates the moral equivalent\n>> in .git/config).\n> \n> So, using 1.4.4 series, or 1.5, the \"sane\" way to work in git\n> is to use clone --use-separate-remotes.\n> \n>> So whatever you do the first step of \"git pull\", which is \"git\n>> fetch\", will _not_ overwrite the current branch.\n> \n> I assume by this you mean that if I do the separate remote trick, I\n> will not shoot myself by doing a 'git pull' while on my topic branch,\n> as the setup will cause git to refuse to do it.\n\nYou would _never_ shoot yourself in foot doing \"git fetch\".\n\n\"git pull\" would refuse merge wwhen not on correct branch only if you\nuse new 1.5.0 globbing (as described below).\n\nBut it is fairly easy to recover from errorneous pull. \n\"git reset --hard\" should be enough (if fetch screwed something\n\"git reset --hard ORIG_HEAD\" should be enough).\n\n>> In order to prevent merging their 'master' into your 'topic'\n>> when you are on 'topic', git-fetch/git-pull from 1.5.0 uses\n>> further safety which is left by 'git clone'.  The real\n>> configuration created by 'git clone' looks like this:\n>>\n>>      [remote \"origin\"]\n>>              url   = /repos/git/project\n>>              fetch = refs/heads/*:refs/remotes/origin/*\n>>      [branch \"master\"]\n>>              remote = origin\n>>              merge  = refs/heads/master\n>>\n>> The 'fetch' lines correspond to 'Pull' in .git/remotes/origin file;\n>> it uses globbing pattern so if there are new branches on the\n>> remote side you can automatically track them, which is a plus.\n>>\n>> But more importantly, when 'fetch' lines only do the globbing\n>> pattern, 'git pull' without explicitly saying which remote\n>> branch you want to merge to the current branch (perhaps by\n>> mistake) refuses to do a merge, if there is no branch.*.merge\n>> configuration (\"refs/heads/master\" in the above example).  So\n>> with the above configuration, 'git pull' from 1.5.0 will fetch\n>> two remote branches and keep them in remotes/origin/master and\n>> remotes/origin/topic, and if you are on 'master' their\n>> refs/heads/master is merged into your current branch, but if you\n>> are on 'topic', it will not do the merge step (this only applies\n>> to \"git pull\" without any refspec parameters).\n\nWe assume for later discussion that we use git 1.5.0 (well, 1.5.0-rc4)\nin the situation below.\n\n> Ok, so if I am on master, I do this:\n> \n> [master] % git pull\n> \n> and this will fetch the remote master and merge it to my master, and\n> fetch the remote topic and merge it to my local topic.\n\nThis would fetch remote master (refs/heads/master) into your local\ntracking branch origin/master (refs/remotes/origin/master), and fetch\nremote topic into origin/topic. Then it would merge remote master\n(which is equivalent to merging local origin/master) into your local\nmaster branch.\n\n> While, if I am on my topic branch, if I do this:\n> \n> [topic] % git pull\n> \n> it sill fetches from the remote master and the remote topic, but will\n> not merge at all.\n\nTrue, it would fetch but refuse to merge.\n\n> If I am, this still seems bizarre.  I really just want a way to sync\n> two repos that works consistently, and is invoked consistently, no\n> matter what branch I am currently on.  And, again, by \"sync\", I just\n> mean no cross-branch merging --- no \"crossing of the streams\".  Even\n> if it were limited to syncing the current branch only, that would be\n> ok, but this variable behavior seems rather odd and confusing.  In\n> other words, I just want to type the equivalent of 'git sync' and have\n> it work, and not have to give a branch name, or be in the \"right\n> place\" for it to work as I expect.\n\n\"Crossing of the streams\" is _required_ if you do parallel work. If you\nwork only on one repository or the other, never doing parallel work, it\nwould be easier to just use 1:1 mapping (like in bare repository), and\nuse only \"git fetch\" and \"git push\".\n \nIf you do parallel work (well, unless you send changes via patches), then\nyou have to do merges. BTW git would detect if only one side made any\nchanges: this would result in so called fast-forward case, and no true\nmerge at all.\n\nBTW. what had happened to git merge strategy \"subordinate\" (later renamed to\nmore proper \"rebase\" strategy)?\n\n> Thus, I don't want to have to think \"oh, I'm on my topic branch, and\n> if I really want to sync from my remote repo, I need to get on my\n> master branch\".  It seems that the only difference in the \"insane\" way\n> I was doing things and the \"sane\" way you propose is that in my way, I\n> had to make this mental leap or get burned by a cross-branch merge,\n> but in the new way, I still have to make this mental leap if I want it\n> to work, but if I don't, at least I don't get burned.\n\nParallel distributed development is intrinsically difficult, but also much\nmore elastic than rigid centralized CVS-like development.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"33947","messageId":"Pine.LNX.4.64.0702080858430.8424@woody.linux-foundation.org","threadId":"6731","inReplyTo":"17866.27739.701406.722074@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-08T17:27:50Z","receivedAt":"2007-02-08T17:27:50Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 7 Feb 2007, Bill Lear wrote:\n> \n> I have a public bare repo on my machine that I have cloned to make a\n> private repo.  I just want to sync my branches on my public and\n> private repos.  I do not want to merge across branches, I just want to\n> \"sync\".\n\nOk, others already replied, but here's a few rules to ease your mind in \ngeneral:\n\n - First off: you can always _trivially_ get back to whatever state you \n   had before, as long as you committed it, and didn't have any dirty \n   state (uncommitted patches) in your working tree.\n\nThis is something that it's worth repeating, and even perhaps \nexperimenting with to get really comfortable with. Why? Because once you \nlearn to get back to any random state you had before, and once you are \ncomfortable with that, you suddenly lose the fear of experimenting. \nWhatever you screw up, if you're confident you can get back, who cares?\n\nSo the \"get back from a mistake\" should probably be at the very front of \nour manuals and tutorials. I don't think it currently is, but it's \nactually not that hard. There's just one command to remember: \"git reset\", \nand the only issue you might ever have with it is:\n\n - make sure you're on the right branch first! If the problem you had is \n   that you're on the wrong branch, switch branches first! Don't try to \n   make the wrong branch \"look right\". But once you know you're on the \n   right branch, you know that \"git reset\" is your friend to getting it \n   anywhere you want.\n\n - do you want to throw away all your working tree changes (and if \n   you screwed up some git operation, the answer is usually \"Yes!\"). If \n   so, add the \"--hard\" flag. It's not on by default, exactly because it \n   *will* throw away all state in your tracked working tree, and reset it \n   to whatever you want to go back to.\n\n - exactly *what* do you want to go back to? The default is to go back to \n   the state at the last successful commit, but sometimes what you screwed \n   up was exactly the last commit (eg an unintentional \"pull\" that \n   actually succeeded), and then you need to tell it *what* to reset to.\n\nThat's really all there is to it. It's really simple, although especially \nthe second point can take some practice to get right.\n\nSo NORMALLY, if you did something bad - say, you edited a file, and just \nrealized that the whole edit was just crap, and you want to start over - \nyou just do a simple\n\n\tgit reset --hard\n\nand it will just reset all your git state to the last commit you did. \n\nThis is what you'd do in this case, when you had a \"git pull\" that simply \n*failed* due to conflicts, and you realize that you didn't do that merge \nat all.\n\nHowever, what happens if you actually do a \"git pull\" that doesn't have \nany conflicts (or at least they merge fine), so the pull actually \n*succeeds*, but you realize that wasn't what you wanted to do at all?\n\nIn that case, you need to say\n\n\tgit reset --hard <point-you-want-to-go-back-to>\n\nto just reset to the previous state. Now we get to that \"how do I figure \nout what state that was?\" part of the question, and usually it's trivial \nto answer.\n\nFor example, a command like \"git pull\" will leave a special magic name \naround to tell you what the original HEAD was before the pull, and that \nmagic name is (surprise surprise) called ORIG_HEAD. So if the pull \nsucceeded, but you realized it was an error (perhaps you had even intended \nto do it, but once you pulled, you just saw that what you pulled was crap, \nso you decide that you didn't really want to do it after all), you can \njust do\n\n\tgit reset --hard ORIG_HEAD\n\nand you're back to where you were _before_ the pull.\n\nIt really is that easy. And once you get comfortable with it, and you \nreally know deep down how easy it is, that should just relax you a lot. \nWhen you go \"AIEE! I made a horrible mistake!\" you should just laugh, and \nsay \"and I don't *care*, because I can just trivially undo it!\".\n\nNow, usually it's really as simple as just using ORIG_HEAD (or the \ntop-of-the-branch itself when the pull simply failed), but you can \nactually do it for any commit. Say, you've worked for a week, and have \ncommitted five or six things (and you don't even quite remember), and you \nare just weary, and realize that IT IS ALL CRAP!\n\nNow, before you just decide to drown your sorrows in a bottle (or, \nperhaps, the morning after), you realize that you haven't actually pushed \nit out to anybody else yet (because it wasn't ready anyway), and that you \ncan just undo the whole thing!\n\nSo what do you do?\n\nYou just fire up gitk, or whatever your favourite history viewer is (git \nlog, qgit, whatever), and you select the last good commit by hand, and do\n\n\tgit reset --hard <selected-commit-sha1-name>\n\nwhich you just cut-and-paste from your history viewer. And magic happens. \nIt's all gone, and you're now at that old state in history, and all your \ncrap is gone, gone, gone. You can now have a drink or five, happy in the \nknowledge that you just wasted five days of your life, but nobody will \never even know your dark dirty little secret, and hopefully you're getting \npaid by the hour, not by the end result anyway.\n\nOf course, if you have reflogs enabled (see previous discussions), it's \neven easier. In particular, it's easier if you do a \"git reset\" to some \nother point in history, and suddenly realize that what you want to undo is \nreally that \"git reset\" itself ;)\n\n(Even if you undo things, that's also recoverable, as long as you haven't \ndone any garbage collection. But it can be harder, because now you won't \nget \"git log\" or \"gitk\" to show the stuff you undid, so this is where \nreflogs can save your bacon, since they will remember the old stuff too. \nWithout reflogs, you either need to have it in ORIG_HEAD, or you need to \nrun \"git fsck-objects\" and look at all the dangling commits by hand).\n\nSo be happy. \"git reset\" can be dangerous (you *are* throwing things \naway), but it's also very powerful, and pretty easy to use. And git makes \nit fairly hard to *really* throw anything committed away, so even if you \nundo something, and realize you want to re-do it again, it's possible to \ngo back - at most it's just a bit more involved to *find* the place to go \nback to.\n\nOne final (and unrelated) note. If all you want to do is \"sync up\", and \nnot actually merge anything new into your current branch, you should just \ndo \"git fetch\". Not \"git pull\". Doing a \"pull\" implies merging into your \ncurrent branch, and thus does more than just \"sync up\" the branches you \nare tracking.\n\n\t\t\tLinus\n"},{"id":"33966","messageId":"87fy9gz9vu.fsf@host94.eke.fi","threadId":"6731","inReplyTo":"Pine.LNX.4.64.0702080858430.8424@woody.linux-foundation.org","subject":"Re: Git rescue mission","fromName":"Kalle Pokki","fromEmail":"kalle.pokki@iki.fi","sentAt":"2007-02-08T20:12:37Z","receivedAt":"2007-02-08T20:12:37Z","isPatch":false,"sender":{"key":"kalle.pokki@iki.fi","avatar":null},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> For example, a command like \"git pull\" will leave a special magic name \n> around to tell you what the original HEAD was before the pull, and that \n> magic name is (surprise surprise) called ORIG_HEAD. So if the pull \n> succeeded, but you realized it was an error (perhaps you had even intended \n> to do it, but once you pulled, you just saw that what you pulled was crap, \n> so you decide that you didn't really want to do it after all), you can \n> just do\n> \n> \tgit reset --hard ORIG_HEAD\n> \n> and you're back to where you were _before_ the pull.\n\nI usually undo a pull by throwing away just the merge commit by\n\n        git reset --hard HEAD^\n\nThis seems to always get me back to the head commit I had previously, but I'm\nwondering would git in some circumstances leave me with the commits I just pulled\nand throw away my own work instead. Or is it guaranteed that I always reset\nto the parent commit I had before the pull (i.e. ORIG_HEAD)?\n\nOf course HEAD^ doesn't work the same with fast-forward merges, so it would\nprobably make more sense to just use ORIG_HEAD all the time.\n"},{"id":"33977","messageId":"Pine.LNX.4.64.0702081321040.8424@woody.linux-foundation.org","threadId":"6731","inReplyTo":"87fy9gz9vu.fsf@host94.eke.fi","subject":"Re: Git rescue mission","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-08T21:23:32Z","receivedAt":"2007-02-08T21:23:32Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 8 Feb 2007, Kalle Pokki wrote:\n> \n> I usually undo a pull by throwing away just the merge commit by\n> \n>         git reset --hard HEAD^\n\nDon't do this.\n\nIf the merge just fast-forwarded, you'll do the wrong thing.\n\nSo yes, it _works_, but it only works if you actually ended up having a \nreal merge. In contrast, the ORIG_HEAD thing always works.\n\nORIG_HEAD is also particularly useful for doing things like \"ok, what did \nI get from that pull?\" especially when you track somebody elses work (in \nwhich case it will basically _always_ be a fast-forward). So I do\n\n\tgitk ORIG_HEAD..\n\nin git almost every time I pull from Junio's git thing, just because it's \na wonderful way to see what has changed, if you're interested in that kind \nof detail.\n\n\t\tLinus\n"},{"id":"33980","messageId":"17867.40122.51865.575762@lisa.zopyra.com","threadId":"6731","inReplyTo":"Pine.LNX.4.64.0702080858430.8424@woody.linux-foundation.org","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T21:57:14Z","receivedAt":"2007-02-08T21:57:14Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Thursday, February 8, 2007 at 09:27:50 (-0800) Linus Torvalds writes:\n>On Wed, 7 Feb 2007, Bill Lear wrote:\n>> \n>> I have a public bare repo on my machine that I have cloned to make a\n>> private repo.  I just want to sync my branches on my public and\n>> private repos.  I do not want to merge across branches, I just want to\n>> \"sync\".\n>\n>Ok, others already replied, but here's a few rules to ease your mind in \n>general:\n>\n> - First off: you can always _trivially_ get back to whatever state you \n>   had before, as long as you committed it, and didn't have any dirty \n>   state (uncommitted patches) in your working tree.\n>...\n\nWell, I have read all of the very welcome advice and am comfortable\nwith all of it.\n\nHowever, I still have a few open issues with the other branch of this\ndiscussion, i.e., why can we not have an update operation that\nrespects branches in the first place, as 'git pull' seems to do, when\nrun from the master branch?  I do realize that the branch 'foo' in my\nrepo is different from the branch 'foo' in your repo.  However, I want\nto track things, and \"track\" here is a very appropriate word.  Tracks\ndon't cross, and I don't want to cross my \"logically equivalent\"\nbranches (at least yet), even though, as Linus pointed out in great\ndetail, this is easy to undo (though, do see below for a qualification\nof \"easy\").\n\nSo, why should I care?\n\nBecause, an ounce of prevention is worth a pound of cure.  So, if a\npound of undo is so very easy, then, in my mind, an ounce of\npreventing the problem in the first place is at least 1/16th that.\n\nWhen working in a peer-to-peer relationship, I often push and pull\nwith my peers, perhaps on a daily basis, perhaps weekly.  Just the\nother day, my peer was the one who goofed up his branches and I pulled\nthem into my public repo, all tangled up, and did not realize it.\nThence pulled into my private repo, did lots of work, pushed back to\nmy public repo, and after more time intervened, realized something was\nwrong.  It took a LOT of work (for me, I'm sure for others here it\nwould have been much, much less) for me to 1) figure out the genesis\nof the problem, and 2) figure out how to undo it all without\ndestroying my subsequent work.  When we both do this, and merge\nunexpectedly, at different points on one branch from a different\npoint on another, and then pollute each others' repos, it does become\nrather ... well, annoying is the best way to put it.\n\nIn CVS, if I am on branch topic and say 'cvs update', it updates my\nbranch topic.  If I am on branch master and say 'cvs update', it\nupdates my branch master.  Etc., etc.  It doesn't matter that you move\nfrom one branch to the other, the update behavior is the same.  In\ngit, if I am on master, things seem to work wonderfully --- one 'git\npull' and my entire repo is synced (that is, merged) as I expect with\nthe other repo.\n\nI really don't want to do 'git fetch'.  I really want 'git pull'.  I\nreally want the changes put into my repo, from that repo's branch X\nonto my branch X, and that repo's branch Y onto my branch Y.  I really\ndon't want to have to remember to switch to my master branch before I\ndo git pull (this, however, as it stands, does seem to me to be the\nbest option).  Perhaps I'll just write a script 'git-sync' that does\n'git checkout master; git pull'...\n\nJakub is of course literally correct when he says \"'Crossing of the\nstreams' is _required_ ... If you do parallel work ... you have to\ndo merges\".  Again, I recognize that my \"foo\" branch is different\nfrom your \"foo\" branch, and that when they come together they are\nin fact merged, but logically they are one thing --- one stream of\nshared work that we don't want to slip over into another one, at\nleast not until we are ready.\n\nAgain, thanks to everyone for their patience.  We really do enjoy\nusing git --- very cool, fast, and flexible.\n\n\nBill\n"},{"id":"33982","messageId":"87bqk4z4qw.fsf@host94.eke.fi","threadId":"6731","inReplyTo":"Pine.LNX.4.64.0702081321040.8424@woody.linux-foundation.org","subject":"Re: Git rescue mission","fromName":"Kalle Pokki","fromEmail":"kalle.pokki@iki.fi","sentAt":"2007-02-08T22:03:35Z","receivedAt":"2007-02-08T22:03:35Z","isPatch":false,"sender":{"key":"kalle.pokki@iki.fi","avatar":null},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Thu, 8 Feb 2007, Kalle Pokki wrote:\n> > \n> > I usually undo a pull by throwing away just the merge commit by\n> > \n> >         git reset --hard HEAD^\n> \n> Don't do this.\n> \n> If the merge just fast-forwarded, you'll do the wrong thing.\n\nYes, I know. But when looking at the history with gitk, it feels\nquite intuitive to just get rid of the one new commit that appeared\non top of the \"good\" history. Without that kind of visualisation\nI would surely always just use ORIG_HEAD as a reference.\n\nPerhaps gitk could (optionally) also show ORIG_HEAD. That way we could\njust do\n\n        gitk --all\n\nafter a pull and see what got pulled, and everything else was already\nthere, too, if needed.\n"},{"id":"33984","messageId":"20070208221023.GB1091@spearce.org","threadId":"6731","inReplyTo":"87bqk4z4qw.fsf@host94.eke.fi","subject":"Re: Git rescue mission","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-08T22:10:23Z","receivedAt":"2007-02-08T22:10:23Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Kalle Pokki <kalle.pokki@iki.fi> wrote:\n> Perhaps gitk could (optionally) also show ORIG_HEAD. That way we could\n> just do\n> \n>         gitk --all\n> \n> after a pull and see what got pulled, and everything else was already\n> there, too, if needed.\n\n\tgit config alias.new \"gitk --all --not ORIG_HEAD\"\n\nWould give you a new git subcommand:\n\n\tgit new\n\nwhich shows all of the new stuff, on all branches, but doesn't show\nyour prior commit history.\n\n-- \nShawn.\n"},{"id":"33986","messageId":"Pine.LNX.4.64.0702081408140.8424@woody.linux-foundation.org","threadId":"6731","inReplyTo":"17867.40122.51865.575762@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-08T22:13:47Z","receivedAt":"2007-02-08T22:13:47Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 8 Feb 2007, Bill Lear wrote:\n> \n> However, I still have a few open issues with the other branch of this\n> discussion, i.e., why can we not have an update operation that\n> respects branches in the first place, as 'git pull' seems to do, when\n> run from the master branch?\n\nActually, git does that all correctly for other branches too, but only in \ngit-1.5.\n\nIt's one of the bigger UI warts that got fixed since the last release \n(although it got fixed by better config management, and as such you'll \nonly *see* the fixes if you end up doing the initial clone with the new \ngit version - if you use a new git version with an old repo, many - but \nnot all - bad semantics will remain).\n\nConsidering how stable the -rc kernels are (and actually, git \"master\" in \ngeneral), there's really very little reason to wait for the real release. \nJunio has been very careful, and I think a lot of the delay in 1.5 has \nbeen about trying to get all the new stuff that changes semantics subtly \nin before the release, so that Junio will not have to do any real user- \nvisible changes later.\n\nSo it might be worth while trying out git-1.5.0-rc4, and seeing if that \nsolves some of the UI issues for you guys. It changes things like where \nthe default remote branches are, and makes the distinction between \"my \nlocal copy of branch X\" and \"the remote branch X\" much clearer, which has \nclearly been a UI problem.\n\n\t\t\tLinus\n"},{"id":"33988","messageId":"200702082329.12572.jnareb@gmail.com","threadId":"6731","inReplyTo":"17867.40122.51865.575762@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-02-08T22:29:11Z","receivedAt":"2007-02-08T22:29:11Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Bill Lear wrote:\n[cut]\n\nWith git 1.5.0-rc4 cloned repository, with globbing refspecs for origin\nyou don't have the problem. When you are on branch 'master', \"git pull\"\nfetches and merges 'origin/master' into 'master'. When on any other\nbranch, \"git pull\" would fetch only (unless configured otherwise).\n\nNote: you cannot pull into 'master' if you are not on 'master' because\nof possibility of merge conflict: you need working area for that.\n\n> In CVS, if I am on branch topic and say 'cvs update', it updates my\n> branch topic.  If I am on branch master and say 'cvs update', it\n> updates my branch master.  Etc., etc.  It doesn't matter that you move\n> from one branch to the other, the update behavior is the same.  In\n> git, if I am on master, things seem to work wonderfully --- one 'git\n> pull' and my entire repo is synced (that is, merged) as I expect with\n> the other repo.\n\nIn CVS branches are totally f**ked up. And enforced update before commit \nworkflow doesn't help, also. Get rid of bad CVS habits. Please.\n\n> I really don't want to do 'git fetch'.  I really want 'git pull'.  I\n> really want the changes put into my repo, from that repo's branch X\n> onto my branch X, and that repo's branch Y onto my branch Y.  I really\n> don't want to have to remember to switch to my master branch before I\n> do git pull (this, however, as it stands, does seem to me to be the\n> best option).  Perhaps I'll just write a script 'git-sync' that does\n> 'git checkout master; git pull'...\n\nIt's the only option.\n\n> Jakub is of course literally correct when he says \"'Crossing of the\n> streams' is _required_ ... If you do parallel work ... you have to\n> do merges\".  Again, I recognize that my \"foo\" branch is different\n> from your \"foo\" branch, and that when they come together they are\n> in fact merged, but logically they are one thing --- one stream of\n> shared work that we don't want to slip over into another one, at\n> least not until we are ready.\n\nSo do fetch, and do pull only when changes are ready...\n\nRTFM. Take a look at http://git.or.cz/gitwiki/GitLinks namely section\n\"Seminars and presentations\", read new Git User's Manual also at\nhttp://www.fieldses.org/~bfields/git-user-manual.html, browse GitWiki.\n\nBy the way, the workflow looks slightly different if you pull directly\nfrom one another (A pulls or fetches from B, B pulls or fetches from A),\nand if you have one central public bare repository (A pulls or fetches\nfrom 'public' and pushes her changes to 'public', B pulls or fetches\nfrom 'public' and pushes his changes to 'public'). In the latter git\nasks you to pull (fetch) before pushing if you are not up to date. Notice\nthat it is on push, not on commit!\n\n\nWe should really update http://git.or.cz/gitwiki/GitWorkflows ...\nbut how to make diagrams: ASCII art is hard because it needs monospace,\nupload of images attachements is not possible...\n-- \nJakub Narebski\nPoland\n"},{"id":"33991","messageId":"17867.42280.577214.422651@lisa.zopyra.com","threadId":"6731","inReplyTo":"Pine.LNX.4.64.0702081408140.8424@woody.linux-foundation.org","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T22:33:12Z","receivedAt":"2007-02-08T22:33:12Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Thursday, February 8, 2007 at 14:13:47 (-0800) Linus Torvalds writes:\n>On Thu, 8 Feb 2007, Bill Lear wrote:\n>> \n>> However, I still have a few open issues with the other branch of this\n>> discussion, i.e., why can we not have an update operation that\n>> respects branches in the first place, as 'git pull' seems to do, when\n>> run from the master branch?\n>\n>Actually, git does that all correctly for other branches too, but only in \n>git-1.5.\n>\n>...\n>So it might be worth while trying out git-1.5.0-rc4, and seeing if that \n>solves some of the UI issues for you guys. It changes things like where \n>the default remote branches are, and makes the distinction between \"my \n>local copy of branch X\" and \"the remote branch X\" much clearer, which has \n>clearly been a UI problem.\n\nOk, very reasonable.  I've been our corporate guinea pig, so I'll give\nthis a whirl.  One thing I'm very, very happy about in git is the\nability to quickly experiment.  Believe it or not, I have solved\nactual git problems in our company by doing just that.  Of necessity,\nit's largely my complaints and problems that are aired here, though.\n\n\nBill\n"},{"id":"34001","messageId":"20070208232404.GA9493@coredump.intra.peff.net","threadId":"6731","inReplyTo":"17867.16740.875694.789664@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-02-08T23:24:04Z","receivedAt":"2007-02-08T23:24:04Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 08, 2007 at 09:27:32AM -0600, Bill Lear wrote:\n\n> > - never build on a branch that appears on the RHS of ':'.\n> \n> This I don't quite understand.  So, if it is on the LHS, it is ok?\n> But, if it is ALSO on the RHS it is not?\n\nIf it is on the LHS, it's talking about the branch in the _remote_ repo.\n\n> So, this:\n> \n>       Pull: refs/heads/topic:refs/heads/topic\n> \n> really means don't don't work on a branch named topic in this\n> repository?\n\nIt means to fetch the remote's branch \"refs/heads/topic\" and store the\ncurrent head in _your_ \"refs/heads/topic\" as a tracking branch, but only\nif it's a fast-forward. Yes, I know it says \"Pull:\", but it's really\nabout fetching.\n\nYou can then merge the result of that fetch into your current branch. So\nwhat you want is something like:\n\nPull: refs/heads/topics:refs/heads/remote-topic\n\nwhich will use 'remote-topic' as a tracking branch, always updating it\nat fetch time to reflect the remote's version of topic. You can then\nmerge remote-topic into your local topic branch by fetching+merging, or\nby doing 'git-pull remote refs/heads/topic:refs/heads/remote-topic'.\n\n> I assume by \"build on\" you mean \"work, compile, check stuff in,\n> etc.\"?.  Did you have something else in mind when you said \"build on\"?\n\nI believe he means 'store commits in'. That is, the RHS of the refspec\nshould be used solely for tracking fetches from the remote. If you make\na commit on top of it (either directly, or by doing a merge), then the\nfetch must either throw away your commits, or fail to fast-forward to\nthe remote's new position for that branch.\n\n> I don't currently have any 'refs/remotes' of any sort, so I guess you\n> mean that the new principle, using git clone --use-separate-remote\n> will effect this.\n\nYes. It will basically give you a RHS of \"refs/remotes/$REMOTE/$BRANCH\"\nto track a branch $BRANCH coming from $REMOTE (generally \"origin\"); it's\na more organized way of doing what I mentioned above (RHS of\nrefs/heads/remote-topic).\n\n> >(git-clone from 1.5.0 does not actually make remotes/origin file\n> >in .git/ that has the above -- it creates the moral equivalent\n> >in .git/config).\n> \n> So, using 1.4.4 series, or 1.5, the \"sane\" way to work in git\n> is to use clone --use-separate-remotes.\n\nMost people think so (though I think Junio actually still uses the\ntraditional layout, because he finds it more convenient). Note that in\n1.5, --use-separate-remote is the default (the option is still\naccepted, but has no effect; note also that the option is singular).\n\n> I assume by this you mean that if I do the separate remote trick, I\n> will not shoot myself by doing a 'git pull' while on my topic branch,\n> as the setup will cause git to refuse to do it.\n\nNo, you will not shoot yourself because the fetch part of the pull will\nstore the remote's position of 'refs/heads/topic' at\n'refs/remotes/origin/topic' instead of trying to overwrite the branch\nyou've been working on.\n\nAs an additional bonus, you can put this in your .git/config:\n\n[branch \"topic\"]\nremote = origin\nmerge = refs/heads/topic\n\nwhich means \"When I'm on my refs/heads/topic branch and I issue a\ngit-pull without any arguments, do a git-fetch on origin. Then, merge\nwhat the remote end calls refs/heads/topic into my current branch.\"\nWithout this, git-pull in v1.4.* will attempt to merge the remote's\n'master' branch. In v1.5, I believe it will refuse to make a merge.\n\n> Ok, so if I am on master, I do this:\n> \n> [master] % git pull\n> \n> and this will fetch the remote master and merge it to my master, and\n> fetch the remote topic and merge it to my local topic.\n> \n> While, if I am on my topic branch, if I do this:\n> \n> [topic] % git pull\n> \n> it sill fetches from the remote master and the remote topic, but will\n> not merge at all.\n> \n> Could you verify if I have stated your position correctly?\n\nThat is correct. If you add the config I mentioned above, you can get\nthe \"automatically merge from remote topic into my topic\" behavior that\nyou get for master.\n\n> If I am, this still seems bizarre.  I really just want a way to sync\n> two repos that works consistently, and is invoked consistently, no\n> matter what branch I am currently on.  And, again, by \"sync\", I just\n> mean no cross-branch merging --- no \"crossing of the streams\".  Even\n> if it were limited to syncing the current branch only, that would be\n> ok, but this variable behavior seems rather odd and confusing.  In\n> other words, I just want to type the equivalent of 'git sync' and have\n> it work, and not have to give a branch name, or be in the \"right\n> place\" for it to work as I expect.\n\nSyncing repositories doesn't involve pulling. It just involves fetching.\nSo in either case, you can simply do a 'git-fetch origin'. In v1.5,\nthe repositories won't be exactly identical; your remote branches will\nbe stored in refs/remotes/origin instead of refs/heads.\n\nHowever, your original setup is still broken for syncing. You are doing\nlocal work on refs/heads/topic, but you also are claiming you want to\nstore the sync of the remote in refs/heads/topic. You obviously can't do\nboth.\n\n> Thus, I don't want to have to think \"oh, I'm on my topic branch, and\n> if I really want to sync from my remote repo, I need to get on my\n> master branch\".  It seems that the only difference in the \"insane\" way\n\nMaybe I don't understand what you mean by sync here, but I don't see the\nmental leap. Whenever you fetch, from whatever branch, using the\n'origin' remote, it will update all tracking branches in your local\nrepository. You can then selectively do merges to any local branches\nyou're working on. You _can't_ do an operation that is \"for every local\nbranch I have, merge the matching remote branch into my local branch\".\nAnd I don't think you'd want to: a merge may or may not be a trivial\nthing, since it might have conflicts.\n\nThe workflows I suspect you want are:\n\n1. I'm working on my topic, and somebody else is working on topic. Pull\n   their work from the remote 'origin':\n\n     git checkout topic\n     hack hack hack\n     git commit\n     git pull origin\n\n  Using separate remotes, you'll get a copy of the remote topic branch\n  in your refs/remotes/origin/topic. If you have the config magic I\n  mentioned above, it will automagically pull from his topic branch. If\n  not, it will either pull from his master (v1.4) or complain (v1.5).\n\n2. I'm working on my topic, and now I want to pull from the remote\n   master to do some testing.\n\n     git checkout topic\n     hack hack hack\n     git commit\n     git fetch origin\n     git merge origin/master\n\n   This will only work in v1.5.  Using separate remotes, the\n   'origin/master' branch refers to the 'refs/remotes/origin/master'\n   tracking branch. You could do it in v1.4 like this (without using a\n   tracking branch at all):\n\n     git pull origin master\n\n3. I'm interested in what's happening on the topic branch, but I don't\n   care about making local commits. I just want to build it.\n\n     git checkout origin/topic\n     build build build\n\n   It assumes you are tracking using separate remotes (hence the\n   origin/topic branch). This will _only_ work in v1.5, since you're\n   not allowed to checkout any non-branch refs in v1.4 (including tags\n   or remote tracking branches). The moral equivalent in v1.4 using\n   separate remotes is:\n\n     git checkout -b topic origin/topic\n     build build build\n\n   which leaves you with your own local 'topic' branch, which you can\n   then merge into if you want.\n\nHope that makes sense.\n\n-Peff\n"},{"id":"34002","messageId":"17867.45437.922483.805945@lisa.zopyra.com","threadId":"6731","inReplyTo":"Pine.LNX.4.64.0702081408140.8424@woody.linux-foundation.org","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T23:25:49Z","receivedAt":"2007-02-08T23:25:49Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Thursday, February 8, 2007 at 14:13:47 (-0800) Linus Torvalds writes:\n>...\n>It's one of the bigger UI warts that got fixed since the last release \n>(although it got fixed by better config management, and as such you'll \n>only *see* the fixes if you end up doing the initial clone with the new \n>git version - if you use a new git version with an old repo, many - but \n>not all - bad semantics will remain).\n>...\n\nWith regard to the new version and old repos, am I correct in assuming\nthat we can upgrade our old repo (a bare one) to the new git by first\ninstalling the new git, and then doing this:\n\n% cd /repos/git\n% mv project project.old_git\n% git --bare clone project.old_git project\n\nor is there something else we must do?\n\n\nBill\n"},{"id":"34003","messageId":"17867.45813.15301.479436@lisa.zopyra.com","threadId":"6731","inReplyTo":"20070208232404.GA9493@coredump.intra.peff.net","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T23:32:05Z","receivedAt":"2007-02-08T23:32:05Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Thursday, February 8, 2007 at 18:24:04 (-0500) Jeff King writes:\n>...\n>Maybe I don't understand what you mean by sync here, but I don't see the\n>mental leap. Whenever you fetch, from whatever branch, using the\n>'origin' remote, it will update all tracking branches in your local\n>repository. You can then selectively do merges to any local branches\n>you're working on. You _can't_ do an operation that is \"for every local\n>branch I have, merge the matching remote branch into my local branch\".\n>And I don't think you'd want to: a merge may or may not be a trivial\n>thing, since it might have conflicts.\n>...\n\nA very good point, and an obvious one in retrospect.  I guess I will\nbe entirely satisfied if I am on branch X I can just say 'git pull'\nand it will NOT pull from any other branch.  You have added to my\nunderstanding on this, and thank you for taking the time.\n\n\nBill\n"},{"id":"34004","messageId":"20070208233324.GA1556@spearce.org","threadId":"6731","inReplyTo":"17867.45437.922483.805945@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-08T23:33:24Z","receivedAt":"2007-02-08T23:33:24Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Bill Lear <rael@zopyra.com> wrote:\n> With regard to the new version and old repos, am I correct in assuming\n> that we can upgrade our old repo (a bare one) to the new git by first\n> installing the new git, and then doing this:\n> \n> % cd /repos/git\n> % mv project project.old_git\n> % git --bare clone project.old_git project\n> \n> or is there something else we must do?\n\nIn the case of a bare repo, there isn't anything to do.\n\n-- \nShawn.\n"},{"id":"34008","messageId":"eqgc69$8i3$1@sea.gmane.org","threadId":"6731","inReplyTo":"17867.45437.922483.805945@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-02-08T23:38:21Z","receivedAt":"2007-02-08T23:38:21Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"<opublikowany i wysłany>\n\nBill Lear wrote:\n\n> On Thursday, February 8, 2007 at 14:13:47 (-0800) Linus Torvalds writes:\n>>...\n>> It's one of the bigger UI warts that got fixed since the last release \n>> (although it got fixed by better config management, and as such you'll \n>> only *see* the fixes if you end up doing the initial clone with the new \n>> git version - if you use a new git version with an old repo, many - but \n>> not all - bad semantics will remain).\n>> ...\n> \n> With regard to the new version and old repos, am I correct in assuming\n> that we can upgrade our old repo (a bare one) to the new git by first\n> installing the new git, and then doing this:\n> \n> % cd /repos/git\n> % mv project project.old_git\n> % git --bare clone project.old_git project\n\n  % git clone --bare project.old_git project\n\nalthough usually notation project.git is used, so I think it would be\n\n  % git clone --bare project.old_git project.git\n\n\"git --bare <cmd>\" is equivalent to \"git --git-dir=pwd\". You want to make\nbare clone \"git clone --bare\", not invoke git command in bare repository\n\"git --bare <cmd>\": there is no repository yet!\n\nYou can just edit .git/config (prehaps generate it first\nfrom .git/remotes/origin file using remotes2config.sh script from contrib\nsection), and move (rename) branches.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"34009","messageId":"17867.46325.433406.974582@lisa.zopyra.com","threadId":"6731","inReplyTo":"20070208233324.GA1556@spearce.org","subject":"Re: Git rescue mission","fromName":"Bill Lear","fromEmail":"rael@zopyra.com","sentAt":"2007-02-08T23:40:37Z","receivedAt":"2007-02-08T23:40:37Z","isPatch":false,"sender":{"key":"rael@zopyra.com","avatar":"https://gravatar.com/avatar/c4f2d2790ca3828d3b4e7dfebabf61d2fe94fd82fa49cdac2a5295dd2d46a874?d=mp&s=160"},"body":"On Thursday, February 8, 2007 at 18:33:24 (-0500) Shawn O. Pearce writes:\n>Bill Lear <rael@zopyra.com> wrote:\n>> With regard to the new version and old repos, am I correct in assuming\n>> that we can upgrade our old repo (a bare one) to the new git by first\n>> installing the new git, and then doing this:\n>> \n>> % cd /repos/git\n>> % mv project project.old_git\n>> % git --bare clone project.old_git project\n>> \n>> or is there something else we must do?\n>\n>In the case of a bare repo, there isn't anything to do.\n\nSo, I assume I need to tell our developers that once we have installed\nthe new git, they will need to set aside their old repos and just\nclone again from our company repo?\n\n\nBill\n"},{"id":"34011","messageId":"Pine.LNX.4.64.0702081538160.8424@woody.linux-foundation.org","threadId":"6731","inReplyTo":"17867.45437.922483.805945@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-08T23:46:12Z","receivedAt":"2007-02-08T23:46:12Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 8 Feb 2007, Bill Lear wrote:\n\n> \n> With regard to the new version and old repos, am I correct in assuming\n> that we can upgrade our old repo (a bare one) to the new git by first\n> installing the new git, and then doing this:\n> \n> % cd /repos/git\n> % mv project project.old_git\n> % git --bare clone project.old_git project\n> \n> or is there something else we must do?\n\nI would actually suggest against that. Why? Because it will set a new \n\"origin\" (pointing to your old repo), and if you had something else \nbefore, that's probably not what you want.\n\nAnyway, for the *shared* repositories, the git-1.5 changes really don't \ntend to make any difference anyway (since they don't even tend to really \n_care_ about things like origin branches - they are just used to push and \npull from).\n\nIt's much more noticeable for the actual *development* repositories, \nbecause they are the ones that have \"origin\" pointing to something else.\n\nAnd yes, for those development repositories, it's usually a good idea to \njust do\n\n\tmv project old-project\n\tgit clone /repos/git/project\n\tcd project \n\t.. work work work ..\n\nand be happy.\n\nYou can also set up the new configurations by hand in an old repository, \nbut there really doesn't tend to be a lot of reason to do that. Just as an \nexample: the above was _literally_ what I did myself, just because I was \ntoo lazy to start editing .git/config files and setting things up in other \nways (renaming origin branches etc).\n\nIn fact, I just did it the other day for my \"sparse\" repository (which is \nanother project I started, but that is maintained by others these days). \nSo here's a snippet from my bash history:\n\n  ...\n  837  mv sparse old-sparse\n  838  cat old-sparse/.git/config\n  839  git clone master.kernel.org:/pub/scm/linux/kernel/git/josh/sparse\n  ...\n\n(that \"cat old-sparse/.git/config\" was just because I had forgotten \nexactly where the origin of that repo was, so I did that cat just to do a \ncut-and-paste for the subsequent \"git clone\" ;^).\n\nAnd yes, I did that just to get the nicer branch layout, something that my \nold sparse git repo didn't have, because I had set it up with an old \nversion of git (and done some minimal manual maintenance).\n\n\t\t\tLinus\n"},{"id":"34012","messageId":"20070208235006.GC1556@spearce.org","threadId":"6731","inReplyTo":"17867.46325.433406.974582@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-08T23:50:06Z","receivedAt":"2007-02-08T23:50:06Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Bill Lear <rael@zopyra.com> wrote:\n> So, I assume I need to tell our developers that once we have installed\n> the new git, they will need to set aside their old repos and just\n> clone again from our company repo?\n\nRight.  Otherwise they need to do the config changes by hand in their\nexisting repository, which may be annoying/tedious/painful/difficult,\ndepending on your knowledge level with git.\n\nYou can actually use the old developer repositories with the newer\nGit without doing anything specific to upgrade them.  Its just that\n1.5.0 sets up the initial config of the repository differently,\nand that's exactly the change in functionality you are looking for.\n\nThey can save their old topic branches (if they are important)\nby doing something like:\n\n\tmv proj old_proj\n\tgit clone git://server/proj proj\n\tcd proj\n\tgit fetch ../old_proj topicA:topicA [topicB:topicB ...]\n\nat which point ../old_proj can be tossed.\n\n-- \nShawn.\n"},{"id":"34015","messageId":"200702090103.05510.jnareb@gmail.com","threadId":"6731","inReplyTo":"17867.46325.433406.974582@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-02-09T00:03:04Z","receivedAt":"2007-02-09T00:03:04Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Bill Lear wrote:\n> On Thursday, February 8, 2007 at 18:33:24 (-0500) Shawn O. Pearce writes:\n>> Bill Lear <rael@zopyra.com> wrote:\n>>>\n>>> With regard to the new version and old repos, am I correct in assuming\n>>> that we can upgrade our old repo (a bare one) to the new git by first\n>>> installing the new git, and then doing this:\n>>> \n>>> % cd /repos/git\n>>> % mv project project.old_git\n>>> % git --bare clone project.old_git project\n>>> \n>>> or is there something else we must do?\n>>\n>> In the case of a bare repo, there isn't anything to do.\n> \n> So, I assume I need to tell our developers that once we have installed\n> the new git, they will need to set aside their old repos and just\n> clone again from our company repo?\n\nNope.\n\n\n1. New git works with old repositories, and would continue to work.\nNevertheless you need new layout and new configuration to make use\nof some new features.\n\n\n2. They need to clone _their own_ repositories. It's the simplest\nway, but\n\n\n3. You can simply\n\n a) convert remotes configuration from .git/remotes/origin file\n    to .git/config using remotes2config.sh script in contrib area\n    of git, or http://repo.or.cz/w/git.git?a=blob_plain;f=contrib/remotes2config.sh\n\n b) hand edit remotes configuration to use globbing for refspec,\n    and per branch configuration\n\nIf old repository was _not_ cloned with --use-separate-remote (using\nseparate remote layout), you would also have to:\n\n c) move branches from old layout to new layout using \"git branch -m\"\n    command: 'refs/heads/origin' branch to 'refs/remotes/origin/master',\n    all branches except 'master' (refs/heads/master) from \n    'refs/heads/<branch>' to 'refs/remotes/origin/<branch>'.\n\nThat's all. You have new layout and new configuration without re-cloning.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"34016","messageId":"Pine.LNX.4.64.0702081613370.8424@woody.linux-foundation.org","threadId":"6731","inReplyTo":"17867.46325.433406.974582@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-09T00:17:43Z","receivedAt":"2007-02-09T00:17:43Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 8 Feb 2007, Bill Lear wrote:\n> \n> So, I assume I need to tell our developers that once we have installed\n> the new git, they will need to set aside their old repos and just\n> clone again from our company repo?\n\nNot unless they want to take advantage of *all* the new features.\n\nThe new version of git will work fine with old repositories, both on the \n\"server\" side and the \"user\" side. And people can use a lot of the new \nfeatures even if they do nothing at all.\n\nBut for the _specific_ case of having a clearly separated \"local branch\" \nvs \"remote branch\" case, you do need to make that distinction clear when \nyou create the repository (unless you want to get really down and dirty \nwith the repo and just modify it yourself: certainly possible but \ngenerally just not worth the effort since it's just easier to clone a new \none instead).\n\nSo it's really a matter of how you use it. Switching to a new version of \ngit on the \"server side\" (ie the shared repository operations) won't \nreally affect anything at all. \n\n\t\tLinus\n"},{"id":"34026","messageId":"7vy7n8up6b.fsf@assigned-by-dhcp.cox.net","threadId":"6731","inReplyTo":"200702081028.31493.litvinov2004@gmail.com","subject":"Re: Git rescue mission","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-09T00:53:32Z","receivedAt":"2007-02-09T00:53:32Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alexander Litvinov <litvinov2004@gmail.com> writes:\n\n> I think this should go to git-pull/git-clone man\n> pages. Personaly for me this post dispels dark magic about\n> git-pull's merging logic. I always did git-fetch and then\n> git-pull . <some-branch> to control what and where should be\n> merged.\n\nFair enough.  But I am known to be very bad at writing, so I\nwould ask the list to proofread this to see if it makes sense,\nand prefereably rewrite it to make it easier to understand.\n\nI think it is technically accurate -- I just do not know if I am\nnot writing enough, leaving certain necessary things unsaid,\nbecause I assumed (wrongly) too much knowledge on the reader's\nside.\n\n\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex a81d68c..94478ed 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -33,6 +33,60 @@ include::urls.txt[]\n \n include::merge-strategies.txt[]\n \n+DEFAULT BEHAVIOUR\n+-----------------\n+\n+Often people use `git pull` without giving any parameter.\n+Traditionally, this has been equivalent to saying `git pull\n+origin`.  However, when configuration `branch.<name>.remote` is\n+present while on branch `<name>`, that value is used instead of\n+`origin`.\n+\n+In order to determine what URL to use to fetch from, the value\n+of the configuration `remote.<origin>.url` is consulted\n+and if there is not any such variable, the value on `URL: ` line\n+in `$GIT_DIR/remotes/<origin>` file is used.\n+\n+In order to determine what remote branches to fetch (and\n+optionally store in the tracking branches) when the command is\n+run without any refspec parameters on the command line, values\n+of the configuration variable `remote.<origin>.fetch` are\n+consulted, and if there aren't any, `$GIT_DIR/remotes/<origin>`\n+file is consulted and its `Pull: ` lines are used.\n+In addition to the refspec formats described in the OPTIONS\n+section, you can have a globbing refspec that looks like this:\n+\n+------------\n+refs/heads/*:refs/remotes/origin/*\n+------------\n+\n+A globbing refspec must have a non-empty RHS (i.e. must store\n+what were fetched in tracking branches), and its LHS and RHS\n+must end with `/*`.  The above specifies that all remote\n+branches are tracked using tracking branches in\n+`refs/remotes/origin/` hierarchy under the same name.\n+\n+The rule to determine which remote branch to merge after\n+fetching is a bit involved, in order not to break backward\n+compatibility.\n+\n+If explicit refspecs were given on the command\n+line of `git pull`, they are all merged.\n+\n+When no refspec was given on the command line, then `git pull`\n+uses the refspec from the configuration or\n+`$GIT_DIR/remotes/<origin>`.  In such cases, the following\n+rules apply:\n+\n+. If `branch.<name>.merge` configuration for the current\n+  branch `<name>` exists, that is the name of the branch at the\n+  remote site that is merged.\n+\n+. If the refspec is a globbing one, nothing is merged.\n+\n+. Otherwise the remote branch of the first refspec is merged.\n+\n+\n EXAMPLES\n --------\n \n"},{"id":"34027","messageId":"20070209014852.GA13207@thunk.org","threadId":"6731","inReplyTo":"20070208221023.GB1091@spearce.org","subject":"Re: Git rescue mission","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-02-09T01:48:52Z","receivedAt":"2007-02-09T01:48:52Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Thu, Feb 08, 2007 at 05:10:23PM -0500, Shawn O. Pearce wrote:\n> \tgit config alias.new \"gitk --all --not ORIG_HEAD\"\n> \n> Would give you a new git subcommand:\n> \n> \tgit new\n> \n> which shows all of the new stuff, on all branches, but doesn't show\n> your prior commit history.\n\nAliases don't seem to be working for me; I'm using git 1.5.0-rc4.  Am\nI doing something wrong?\n\n<tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n37% git version\ngit version 1.5.0.rc4\n<tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n38% git config alias.new \"gitk --all --not ORIG_HEAD\"\n<tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n39% git new\ngit: 'new' is not a git-command\n\nThe most commonly used git commands are:\n    add            Add file contents to the changeset to be committed next\n    apply          Apply a patch on a git index file and a working tree\n    archive        Creates an archive of files from a named tree\n\t...\n\n<tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n40% tail .git/config \n\n[user]\n        name = Theodore Ts'o\n        email = tytso@mit.edu\n\n[remote \"iwlwifi\"]\n        url = http://bughost.org/repos/iwlwifi.git/\n        fetch = +refs/heads/*:refs/remotes/iwlwifi/*\n[alias]\n        new = gitk --all --not ORIG_HEAD\n\t\t\t\t\t\n"},{"id":"34028","messageId":"20070209015839.GG1556@spearce.org","threadId":"6731","inReplyTo":"20070209014852.GA13207@thunk.org","subject":"Re: Git rescue mission","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-09T01:58:39Z","receivedAt":"2007-02-09T01:58:39Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Theodore Tso <tytso@mit.edu> wrote:\n> On Thu, Feb 08, 2007 at 05:10:23PM -0500, Shawn O. Pearce wrote:\n> > \tgit config alias.new \"gitk --all --not ORIG_HEAD\"\n> > \n> > Would give you a new git subcommand:\n> > \n> > \tgit new\n> > \n> > which shows all of the new stuff, on all branches, but doesn't show\n> > your prior commit history.\n> \n> Aliases don't seem to be working for me; I'm using git 1.5.0-rc4.  Am\n> I doing something wrong?\n\nIts not you.  The problem is 'gitk' is not an internal command,\nnor is there a 'git-gitk'.  So we cannot execute it.  Instead we\nare giving back a horrible error message.\n\nSymlink git-gitk to gitk and it works.\n\nSorry about giving false hopes.  :-)\n\n-- \nShawn.\n"},{"id":"34030","messageId":"eqgkj2$2nl$1@sea.gmane.org","threadId":"6731","inReplyTo":"20070209014852.GA13207@thunk.org","subject":"Re: Git rescue mission","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-02-09T02:01:41Z","receivedAt":"2007-02-09T02:01:41Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"<opublikowany i wysłany>\n\nTheodore Tso wrote:\n\n> On Thu, Feb 08, 2007 at 05:10:23PM -0500, Shawn O. Pearce wrote:\n>>      git config alias.new \"gitk --all --not ORIG_HEAD\"\n>> \n>> Would give you a new git subcommand:\n>> \n>>      git new\n>> \n>> which shows all of the new stuff, on all branches, but doesn't show\n>> your prior commit history.\n> \n> Aliases don't seem to be working for me; I'm using git 1.5.0-rc4.  Am\n> I doing something wrong?\n> \n> <tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n> 37% git version\n> git version 1.5.0.rc4\n> <tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n> 38% git config alias.new \"gitk --all --not ORIG_HEAD\"\n> <tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n> 39% git new\n> git: 'new' is not a git-command\n\n> <tytso@candygram> {/usr/projects/linux/linux-2.6}  [master]\n> 40% tail .git/config \n> \n> [user]\n>         name = Theodore Ts'o\n>         email = tytso@mit.edu\n> \n> [remote \"iwlwifi\"]\n>         url = http://bughost.org/repos/iwlwifi.git/\n>         fetch = +refs/heads/*:refs/remotes/iwlwifi/*\n> [alias]\n>         new = gitk --all --not ORIG_HEAD\n>                                       \n\nActually I think you can only alias git commands. For example\n\"alias.last  =  cat-file  commit HEAD\" makes \"git last\" call\n\"git cat-file  commit HEAD\".\n\nSo \"alias.new  = gitk --all --not ORIG_HEAD\" would mean that\n\"git new\" invokes \"git gitk ...\" not \"gitk ...\". Do you see\nthe problem.\n\nBut error message is a bit strange...\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"34032","messageId":"200702090932.55255.litvinov2004@gmail.com","threadId":"6731","inReplyTo":"7vy7n8up6b.fsf@assigned-by-dhcp.cox.net","subject":"Re: Git rescue mission","fromName":"Alexander Litvinov","fromEmail":"litvinov2004@gmail.com","sentAt":"2007-02-09T03:32:54Z","receivedAt":"2007-02-09T03:32:54Z","isPatch":false,"sender":{"key":"litvinov2004@gmail.com","avatar":null},"body":"В сообщении от Friday 09 February 2007 06:53 Junio C Hamano написал(a):\n> Fair enough.  But I am known to be very bad at writing, so I\n> would ask the list to proofread this to see if it makes sense,\n> and prefereably rewrite it to make it easier to understand.\n\nIt is cleary enought for me to understand. Thanks a lot.\n"},{"id":"34035","messageId":"7vps8kueqt.fsf@assigned-by-dhcp.cox.net","threadId":"6731","inReplyTo":"Pine.LNX.4.64.0702081408140.8424@woody.linux-foundation.org","subject":"Re: Git rescue mission","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-09T04:38:50Z","receivedAt":"2007-02-09T04:38:50Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> Considering how stable the -rc kernels are (and actually, git \"master\" in \n> general), there's really very little reason to wait for the real release. \n> Junio has been very careful, and I think a lot of the delay in 1.5 has \n> been about trying to get all the new stuff that changes semantics subtly \n> in before the release, so that Junio will not have to do any real user- \n> visible changes later.\n\nHeh, I do not work on kernels ;-)\n\nSeriously, I think you are giving me a bit too much credit, but\nI do agree that the tip of \"master\" tends to be very stable most\nof the time.  This is especially true since some tagged releases\nwere followed up with immediate corrections for \"oops, brown\npaper bag\" bugs in the past X-<.\n\nBut the tip of \"master\" contains dubious change from time to\ntime (for example, I still haven't sorted out your \"log -z\"\nstuff, which is already in my tree).\n"},{"id":"34048","messageId":"20070209085834.GS6560@mellanox.co.il","threadId":"6731","inReplyTo":"17867.46325.433406.974582@lisa.zopyra.com","subject":"Re: Git rescue mission","fromName":"Michael S. Tsirkin","fromEmail":"mst@mellanox.co.il","sentAt":"2007-02-09T08:58:34Z","receivedAt":"2007-02-09T08:58:34Z","isPatch":false,"sender":{"key":"mst@kernel.org","avatar":null},"body":"> So, I assume I need to tell our developers that once we have installed\n> the new git, they will need to set aside their old repos and just\n> clone again from our company repo?\n\nHint:\nIf a developer has some relevant data in his old private repository, he can always\npull from old to new repository there after he clones from the public repository.\n\nThis way you won't lose any data in the conversion.\n\n-- \nMST\n"},{"id":"34071","messageId":"87tzxvf87d.fsf@host94.eke.fi","threadId":"6731","inReplyTo":"20070208221023.GB1091@spearce.org","subject":"Re: Git rescue mission","fromName":"Kalle Pokki","fromEmail":"kalle.pokki@iki.fi","sentAt":"2007-02-09T19:21:26Z","receivedAt":"2007-02-09T19:21:26Z","isPatch":false,"sender":{"key":"kalle.pokki@iki.fi","avatar":null},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> \tgit config alias.new \"gitk --all --not ORIG_HEAD\"\n> \n> Would give you a new git subcommand:\n> \n> \tgit new\n> \n> which shows all of the new stuff, on all branches, but doesn't show\n> your prior commit history.\n\nYes, but what I meant was that gitk wouldn't stop at ORIG_HEAD,\nbut just display it as another branch head with a nice green tag.\nNormally, displaying ORIG_HEAD would probably not be interesting,\nbut it might make sense with\n\n        gitk --all\n\nIt would give more context to the pull than just\n\n        gitk ORIG_HEAD..\n"},{"id":"34115","messageId":"1171123504783-git-send-email-tytso@mit.edu","threadId":"6731","inReplyTo":"20070209014852.GA13207@thunk.org","subject":"Re: Git rescue mission","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2007-02-10T16:05:02Z","receivedAt":"2007-02-10T16:05:02Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"Shawn O. Pearce <spearce@spearce.org> wrote:\n>Its not you.  The problem is 'gitk' is not an internal command,\n>nor is there a 'git-gitk'.  So we cannot execute it.  Instead we\n>are giving back a horrible error message.\n\nHere are some patches to fix the horrible error message and to allow\naliases to expand to external shell commands.\n\n                                        - Ted\n"},{"id":"34116","messageId":"11711235041527-git-send-email-tytso@mit.edu","threadId":"6731","inReplyTo":"1171123504783-git-send-email-tytso@mit.edu","subject":"[PATCH] Print a sane error message if an alias expands to an invalid git command","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2007-02-10T16:05:03Z","receivedAt":"2007-02-10T16:05:03Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"Signed-off-by: \"Theodore Ts'o\" <tytso@mit.edu>\n---\n git.c |    9 ++++++++-\n 1 files changed, 8 insertions(+), 1 deletions(-)\n\ndiff --git a/git.c b/git.c\nindex 82a8357..c43d4ff 100644\n--- a/git.c\n+++ b/git.c\n@@ -387,8 +387,15 @@ int main(int argc, const char **argv, char **envp)\n \t\tdone_alias = 1;\n \t}\n \n-\tif (errno == ENOENT)\n+\tif (errno == ENOENT) {\n+\t\tif (done_alias) {\n+\t\t\tfprintf(stderr, \"Expansion of alias '%s' failed; \"\n+\t\t\t\t\"'%s' is not a git-command\\n\",\n+\t\t\t\tcmd, argv[0]);\n+\t\t\texit(1);\n+\t\t}\n \t\thelp_unknown_cmd(cmd);\n+\t}\n \n \tfprintf(stderr, \"Failed to run command '%s': %s\\n\",\n \t\tcmd, strerror(errno));\n-- \n1.5.0.rc4\n"},{"id":"34114","messageId":"11711235042388-git-send-email-tytso@mit.edu","threadId":"6731","inReplyTo":"11711235041527-git-send-email-tytso@mit.edu","subject":"[PATCH] Allow aliases to expand to shell commands","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2007-02-10T16:05:04Z","receivedAt":"2007-02-10T16:05:04Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"If the alias expansion is prefixed with an exclamation point, treat\nit as a shell command which is run using system(3).\n\nSigned-off-by: \"Theodore Ts'o\" <tytso@mit.edu>\n---\n Documentation/config.txt |    6 ++++++\n git.c                    |   10 ++++++++++\n 2 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 4e650af..de185d8 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -222,6 +222,12 @@ alias.*::\n \tspaces, the usual shell quoting and escaping is supported.\n \tquote pair and a backslash can be used to quote them.\n \n+\tIf the alias expansion is prefixed with an exclamation point,\n+\tit will be treated as a shell command.  For example, defining\n+\t\"alias.new = !gitk --all --not ORIG_HEAD\", the invocation \n+\t\"git new\" is eqvuialent to running the shell command \n+\t\"gitk --all --not ORIG_HEAD\".\n+\n apply.whitespace::\n \tTells `git-apply` how to handle whitespaces, in the same way\n \tas the '--whitespace' option. See gitlink:git-apply[1].\ndiff --git a/git.c b/git.c\nindex c43d4ff..fc08396 100644\n--- a/git.c\n+++ b/git.c\n@@ -159,6 +159,16 @@ static int handle_alias(int *argcp, const char ***argv)\n \talias_command = (*argv)[0];\n \tgit_config(git_alias_config);\n \tif (alias_string) {\n+\t\tif (alias_string[0] == '!') {\n+\t\t\ttrace_printf(\"trace: alias to shell cmd: %s => %s\\n\",\n+\t\t\t\t     alias_command, alias_string+1);\n+\t\t\tret = system(alias_string+1);\n+\t\t\tif (ret >= 0 && WIFEXITED(ret) && \n+\t\t\t    WEXITSTATUS(ret) != 127)\n+\t\t\t\texit(WEXITSTATUS(ret));\n+\t\t\tdie(\"Failed to run '%s' when expanding alias '%s'\\n\", \n+\t\t\t    alias_string, alias_command);\n+\t\t}\n \t\tcount = split_cmdline(alias_string, &new_argv);\n \t\toption_count = handle_options(&new_argv, &count);\n \t\tmemmove(new_argv - option_count, new_argv,\n-- \n1.5.0.rc4\n"},{"id":"34123","messageId":"7vireaj6s2.fsf@assigned-by-dhcp.cox.net","threadId":"6731","inReplyTo":"11711235041527-git-send-email-tytso@mit.edu","subject":"Re: [PATCH] Print a sane error message if an alias expands to an invalid git command","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-10T16:50:53Z","receivedAt":"2007-02-10T16:50:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks for your alias and diff patches.\n\nI'll be away from the keyboard for most of today, so if the list\ncan do distributed QA (and debugging if necessary) before I\nreturn that would be very appreciated ;-).\n"},{"id":"34130","messageId":"Pine.LNX.4.64.0702101000100.8424@woody.linux-foundation.org","threadId":"6731","inReplyTo":"11711235042388-git-send-email-tytso@mit.edu","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-10T18:04:47Z","receivedAt":"2007-02-10T18:04:47Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 10 Feb 2007, Theodore Ts'o wrote:\n>\n> If the alias expansion is prefixed with an exclamation point, treat\n> it as a shell command which is run using system(3).\n\nACK. This should also make it possible to do pipelines etc as aliases, \nalthough to be *really* useful we would probably have to have some way to \nspecify where the arguments to the alias would go.\n\nThe more generic solution is obviously to just do it as external shell \nscripts (which can be named \"git-xyzzy\" so that you don't even need this \nkind of thing), but for the simple cases like gitk/qgit/xmerge/whatever, \nthis approach by Ted seems to be a good way to get easy access to stuff \nthat doesn't need anything fancier..\n\n\t\t\tLinus\n"},{"id":"34131","messageId":"20070210181357.GE25607@thunk.org","threadId":"6731","inReplyTo":"11711235042388-git-send-email-tytso@mit.edu","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-02-10T18:13:57Z","receivedAt":"2007-02-10T18:13:57Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"Here's a revised patch which fixes a stupid spelling typo in the\ndocumentation.  (\"eqvuialent\" --> \"equivalent\")\n\n>From c16544aa786b0fb244fd974a22831a1210286ec5 Mon Sep 17 00:00:00 2001\nFrom: Theodore Ts'o <tytso@mit.edu>\nDate: Sat, 10 Feb 2007 10:50:58 -0500\nSubject: [PATCH] Allow aliases to expand to shell commands\n\nIf the alias expansion is prefixed with an exclamation point, treat\nit as a shell command which is run using system(3).\n\nSigned-off-by: \"Theodore Ts'o\" <tytso@mit.edu>\n---\n Documentation/config.txt |    6 ++++++\n git.c                    |   10 ++++++++++\n 2 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 4e650af..e6e9409 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -222,6 +222,12 @@ alias.*::\n \tspaces, the usual shell quoting and escaping is supported.\n \tquote pair and a backslash can be used to quote them.\n \n+\tIf the alias expansion is prefixed with an exclamation point,\n+\tit will be treated as a shell command.  For example, defining\n+\t\"alias.new = !gitk --all --not ORIG_HEAD\", the invocation \n+\t\"git new\" is equivalent to running the shell command \n+\t\"gitk --all --not ORIG_HEAD\".\n+\n apply.whitespace::\n \tTells `git-apply` how to handle whitespaces, in the same way\n \tas the '--whitespace' option. See gitlink:git-apply[1].\ndiff --git a/git.c b/git.c\nindex c43d4ff..fc08396 100644\n--- a/git.c\n+++ b/git.c\n@@ -159,6 +159,16 @@ static int handle_alias(int *argcp, const char ***argv)\n \talias_command = (*argv)[0];\n \tgit_config(git_alias_config);\n \tif (alias_string) {\n+\t\tif (alias_string[0] == '!') {\n+\t\t\ttrace_printf(\"trace: alias to shell cmd: %s => %s\\n\",\n+\t\t\t\t     alias_command, alias_string+1);\n+\t\t\tret = system(alias_string+1);\n+\t\t\tif (ret >= 0 && WIFEXITED(ret) && \n+\t\t\t    WEXITSTATUS(ret) != 127)\n+\t\t\t\texit(WEXITSTATUS(ret));\n+\t\t\tdie(\"Failed to run '%s' when expanding alias '%s'\\n\", \n+\t\t\t    alias_string, alias_command);\n+\t\t}\n \t\tcount = split_cmdline(alias_string, &new_argv);\n \t\toption_count = handle_options(&new_argv, &count);\n \t\tmemmove(new_argv - option_count, new_argv,\n-- \n1.5.0.rc4.2.g4249\n"},{"id":"34138","messageId":"Pine.LNX.4.63.0702102129110.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6731","inReplyTo":"20070210181357.GE25607@thunk.org","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-10T20:34:38Z","receivedAt":"2007-02-10T20:34:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 10 Feb 2007, Theodore Tso wrote:\n\n> diff --git a/git.c b/git.c\n> index c43d4ff..fc08396 100644\n> --- a/git.c\n> +++ b/git.c\n> @@ -159,6 +159,16 @@ static int handle_alias(int *argcp, const char ***argv)\n>  \talias_command = (*argv)[0];\n>  \tgit_config(git_alias_config);\n>  \tif (alias_string) {\n> +\t\tif (alias_string[0] == '!') {\n> +\t\t\ttrace_printf(\"trace: alias to shell cmd: %s => %s\\n\",\n> +\t\t\t\t     alias_command, alias_string+1);\n\nHere, you add 1 to alias string (though I would put spaces around the \nplus, but that's really a nit).\n\n> +\t\t\tret = system(alias_string+1);\n> +\t\t\tif (ret >= 0 && WIFEXITED(ret) && \n> +\t\t\t    WEXITSTATUS(ret) != 127)\n> +\t\t\t\texit(WEXITSTATUS(ret));\n> +\t\t\tdie(\"Failed to run '%s' when expanding alias '%s'\\n\", \n> +\t\t\t    alias_string, alias_command);\n\nSo, shouldn't you here, too?\n\nIt made me feel a little uneasy that we can execute _any_ command now, but \nI can only find one way to exploit this, when an attacker does not have \nshell access anyway: git-shell.\n\nCiao,\nDscho\n"},{"id":"34146","messageId":"20070211001346.GA19656@thunk.org","threadId":"6731","inReplyTo":"Pine.LNX.4.63.0702102129110.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-02-11T00:13:46Z","receivedAt":"2007-02-11T00:13:46Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sat, Feb 10, 2007 at 09:34:38PM +0100, Johannes Schindelin wrote:\n> > +\t\tif (alias_string[0] == '!') {\n> > +\t\t\ttrace_printf(\"trace: alias to shell cmd: %s => %s\\n\",\n> > +\t\t\t\t     alias_command, alias_string+1);\n> \n> Here, you add 1 to alias string (though I would put spaces around the \n> plus, but that's really a nit).\n\nThat's not how I code but it does seem to be the prevailing git coding\nstyle, so I'll change it.\n\n> > +\t\t\tdie(\"Failed to run '%s' when expanding alias '%s'\\n\", \n> > +\t\t\t    alias_string, alias_command);\n> \n> So, shouldn't you here, too?\n\nYes, that makes the error message look a bit nicer.  I'll respin the\npatch.\n\n> It made me feel a little uneasy that we can execute _any_ command now, but \n> I can only find one way to exploit this, when an attacker does not have \n> shell access anyway: git-shell.\n\n... and git-shell only allows git-receive-pack and git-upload-pack to\nbe called, with a single argument, and aliases aren't allowed to\noverride commands.  So we're safe here, I think.\n\n\t\t\t\t\t\t- Ted\n"},{"id":"34167","messageId":"Pine.LNX.4.63.0702111701160.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6731","inReplyTo":"20070211001346.GA19656@thunk.org","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-11T16:03:29Z","receivedAt":"2007-02-11T16:03:29Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 10 Feb 2007, Theodore Tso wrote:\n\n> On Sat, Feb 10, 2007 at 09:34:38PM +0100, Johannes Schindelin wrote:\n> \n> > It made me feel a little uneasy that we can execute _any_ command now, \n> > but I can only find one way to exploit this, when an attacker does not \n> > have shell access anyway: git-shell.\n> \n> ... and git-shell only allows git-receive-pack and git-upload-pack to be \n> called, with a single argument, and aliases aren't allowed to override \n> commands.  So we're safe here, I think.\n\nYes, sorry. I have a modified git-shell, which allows the git wrapper, \ntoo, to allow setting the config. I'll just fix it here.\n\nCiao,\nDscho\n"},{"id":"34169","messageId":"20070211162136.GA26461@thunk.org","threadId":"6731","inReplyTo":"Pine.LNX.4.63.0702111701160.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-02-11T16:21:36Z","receivedAt":"2007-02-11T16:21:36Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sun, Feb 11, 2007 at 05:03:29PM +0100, Johannes Schindelin wrote:\n> > ... and git-shell only allows git-receive-pack and git-upload-pack to be \n> > called, with a single argument, and aliases aren't allowed to override \n> > commands.  So we're safe here, I think.\n> \n> Yes, sorry. I have a modified git-shell, which allows the git wrapper, \n> too, to allow setting the config. I'll just fix it here.\n\nIf all you've enabled is the ability to set the config, I think we're\nstill safe, since aliases can't override commands.  \n\nStill there are enough config options that might be scary, either now\n(the http.ssl* options) or in the future (someone might think that it\nmakes sense to set the post-commit, post-push, et. al hooks in the\nconfig), that I wouldn't be particularly comfortable letting git-shell\nhave unrestricted access to set the config without having some\nrestriction about which config parameters were allowed to be set from\nthe restricted shell.  Why did you add that ability, out of curiosity?\n\n\t\t\t\t\t\t- Ted\n"},{"id":"34172","messageId":"Pine.LNX.4.63.0702111735000.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6731","inReplyTo":"20070211162136.GA26461@thunk.org","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-11T16:36:51Z","receivedAt":"2007-02-11T16:36:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 11 Feb 2007, Theodore Tso wrote:\n\n> [I was talking about my local git-shell being allowed the git wrapper, \n>  to set config variables]\n>\n> Why did you add that ability, out of curiosity?\n\nIt seemed a good idea to make the description for gitweb a config \nvariable, and I wanted the users to change that themselves. It no longer \nseems a good idea, so I will probably just undo my changes.\n\nCiao,\nDscho\n"},{"id":"34188","messageId":"7vy7n4cqti.fsf@assigned-by-dhcp.cox.net","threadId":"6731","inReplyTo":"20070211162136.GA26461@thunk.org","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-11T21:44:25Z","receivedAt":"2007-02-11T21:44:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Theodore Tso <tytso@mit.edu> writes:\n\n> ..., I think we're\n> still safe, since aliases can't override commands.  \n\nI feel a bit uneasy to hear safety argument based on that\ncurrent restriction, since we might want to loosen it later.\n"},{"id":"34194","messageId":"Pine.LNX.4.63.0702112300500.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6731","inReplyTo":"7vy7n4cqti.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-11T22:03:03Z","receivedAt":"2007-02-11T22:03:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 11 Feb 2007, Junio C Hamano wrote:\n\n> Theodore Tso <tytso@mit.edu> writes:\n> \n> > ..., I think we're\n> > still safe, since aliases can't override commands.  \n> \n> I feel a bit uneasy to hear safety argument based on that current \n> restriction, since we might want to loosen it later.\n\nAfter seeing that it was a personal breakage only, I think we only have to \nkeep the safety in mind, _iff_ we are to loosen it later, not before that.\n\nFor the moment, there are no safety issues, but real advantages, IMHO.\n\nCiao,\nDscho\n"},{"id":"34259","messageId":"20070212035613.GA18010@thunk.org","threadId":"6731","inReplyTo":"7vy7n4cqti.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-02-12T03:56:24Z","receivedAt":"2007-02-12T03:56:24Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sun, Feb 11, 2007 at 01:44:25PM -0800, Junio C Hamano wrote:\n> Theodore Tso <tytso@mit.edu> writes:\n> \n> > ..., I think we're\n> > still safe, since aliases can't override commands.  \n> \n> I feel a bit uneasy to hear safety argument based on that\n> current restriction, since we might want to loosen it later.\n\nLoosen which restriction?\n\n1) The ability for aliases to shadow existing git commands?\n2) The ability for untrusted users to make arbitrary changes to the \n      config file?\n3) The ability for untrusted users to execute arbitrary git commands via \n      git-shell?\n\nYou hjave to loosen at least 2 of the 3 current restrictions before\nthe ability to execute shell commands out of aliases becomes a problem\n--- and I would argue that either (2) or (3) are things that we would\nbe insane to loosen at least to the point of allowing untrusted users\nto make arbitrary changes to the config or execute arbitrary git\ncommands, since even today, they could do a huge amount of damage\nalready.\n\n\t\t\t\t\t\t- Ted\n"},{"id":"34261","messageId":"20070212065319.GF699@spearce.org","threadId":"6731","inReplyTo":"20070212035613.GA18010@thunk.org","subject":"Re: [PATCH] Allow aliases to expand to shell commands","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-12T06:53:19Z","receivedAt":"2007-02-12T06:53:19Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Theodore Tso <tytso@mit.edu> wrote:\n> On Sun, Feb 11, 2007 at 01:44:25PM -0800, Junio C Hamano wrote:\n> > Theodore Tso <tytso@mit.edu> writes:\n> > \n> > > ..., I think we're\n> > > still safe, since aliases can't override commands.  \n> > \n> > I feel a bit uneasy to hear safety argument based on that\n> > current restriction, since we might want to loosen it later.\n> \n> Loosen which restriction?\n> \n> 1) The ability for aliases to shadow existing git commands?\n\nThis one.\n\n> 2) The ability for untrusted users to make arbitrary changes to the \n>       config file?\n> 3) The ability for untrusted users to execute arbitrary git commands via \n>       git-shell?\n> \n> You hjave to loosen at least 2 of the 3 current restrictions before\n> the ability to execute shell commands out of aliases becomes a problem\n> --- and I would argue that either (2) or (3) are things that we would\n> be insane to loosen at least to the point of allowing untrusted users\n> to make arbitrary changes to the config or execute arbitrary git\n> commands, since even today, they could do a huge amount of damage\n> already.\n\nI agree, 2 and 3 are the real issue here, not 1.  1 is only an\nissue for scripts which expect the plumbing to behave a certain\nway, but doesn't, as the user has aliased the plumbing command.\n\n-- \nShawn.\n"}]}