{"thread":{"id":"7982","subject":"'upstream' branches.","startedAt":"2007-05-05T12:29:26Z","lastAt":"2007-05-07T08:51:01Z","messageCount":13,"participants":["David Woodhouse","Alex Riesen","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"41132","messageId":"1178368166.11851.60.camel@pmac.infradead.org","threadId":"7982","inReplyTo":null,"subject":"'upstream' branches.","fromName":"David Woodhouse","fromEmail":"dwmw2@infradead.org","sentAt":"2007-05-05T12:29:26Z","receivedAt":"2007-05-05T12:29:26Z","isPatch":false,"sender":{"key":"dwmw2@infradead.org","avatar":"https://gravatar.com/avatar/7afd4f07e0cf7d7e046ae2d23678296b37777c96488e6f3451e78a5514154ebd?d=mp&s=160"},"body":"When creating a repository which may pull from one or more 'upstream'\nrepositories, it's useful to keep 'branches' which keep track of the\nlast pull from those upstream repositories -- either directly or\nindirectly.\n\nAt http://www.linux-mtd.infradead.org/doc/git.html I've described the\nsetup I'm currently using to achieve this, which looks something like\nthe following:\n\n[remote \"origin\"]\n        url = ssh://git.infradead.org/~/public_git/foo-2.6.git\n        fetch = +refs/heads/*:refs/remotes/origin/*\n\tfetch = +refs/heads/mtd:refs/heads/mtd\n\tfetch = +refs/heads/linus:refs/heads/linus\n        push = refs/heads/master:refs/heads/master\n        push = refs/heads/mtd:refs/heads/mtd\n        push = refs/heads/linus:refs/heads/linus\n[branch \"master\"]\n        remote = origin\n        merge = refs/heads/master\n[remote \"mtd\"]\n        url = git://git.infradead.org/mtd-2.6.git\n        fetch = refs/heads/master:refs/heads/mtd\n        fetch = +refs/heads/linus:refs/heads/linus\n[remote \"linus\"]\n        url = git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.$\n        fetch = refs/heads/master:refs/heads/linus\n\nIs there a better way to do this? Preferably which doesn't involve\ndirecting the user to edit .git/config directly?\n\nBasically, I want the local 'linus' branch to be updated whenever the\nuser pulls from _any_ other repository with a 'linus' branch, so that\nthe 'linus' branch always represents the latest commit pulled from\nupstream. Likewise, the 'mtd' branch should be updated when pulling from\nthat tree (or any other dependent tree which will have an 'mtd' branch).\n\nThese branches should be pushed back to the origin each time.\n\nWhat I have at the moment isn't ideal because I think pulling from the\n'mtd' tree will fail if the 'linus' branch there is older than the local\nclone's 'linus' branch. But it mostly works.\n\nIs there a better way?\n\n-- \ndwmw2\n"},{"id":"41147","messageId":"20070505174416.GA2898@steel.home","threadId":"7982","inReplyTo":"1178368166.11851.60.camel@pmac.infradead.org","subject":"Re: 'upstream' branches.","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-05T17:44:16Z","receivedAt":"2007-05-05T17:44:16Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"David Woodhouse, Sat, May 05, 2007 14:29:26 +0200:\n> [remote \"origin\"]\n>         url = ssh://git.infradead.org/~/public_git/foo-2.6.git\n>         fetch = +refs/heads/*:refs/remotes/origin/*\n> \tfetch = +refs/heads/mtd:refs/heads/mtd\n> \tfetch = +refs/heads/linus:refs/heads/linus\n\nThese pluses request overwriting of the local reference even if it has\nmore commits than the remote (\"is newer\"). Are you sure you want that?\n\n> What I have at the moment isn't ideal because I think pulling from the\n> 'mtd' tree will fail if the 'linus' branch there is older than the local\n> clone's 'linus' branch. But it mostly works.\n> \n> Is there a better way?\n\nI would just remove the pluses. git-fetch will say that the branch is\nalready up-to-date, if the local branch already has everything the\nremote has.\n"},{"id":"41150","messageId":"1178387429.17680.35.camel@shinybook.infradead.org","threadId":"7982","inReplyTo":"20070505174416.GA2898@steel.home","subject":"Re: 'upstream' branches.","fromName":"David Woodhouse","fromEmail":"dwmw2@infradead.org","sentAt":"2007-05-05T17:50:28Z","receivedAt":"2007-05-05T17:50:28Z","isPatch":false,"sender":{"key":"dwmw2@infradead.org","avatar":"https://gravatar.com/avatar/7afd4f07e0cf7d7e046ae2d23678296b37777c96488e6f3451e78a5514154ebd?d=mp&s=160"},"body":"On Sat, 2007-05-05 at 19:44 +0200, Alex Riesen wrote:\n> David Woodhouse, Sat, May 05, 2007 14:29:26 +0200:\n> > [remote \"origin\"]\n> >         url = ssh://git.infradead.org/~/public_git/foo-2.6.git\n> >         fetch = +refs/heads/*:refs/remotes/origin/*\n> > \tfetch = +refs/heads/mtd:refs/heads/mtd\n> > \tfetch = +refs/heads/linus:refs/heads/linus\n> \n> These pluses request overwriting of the local reference even if it has\n> more commits than the remote (\"is newer\"). Are you sure you want that?\n> \n> > What I have at the moment isn't ideal because I think pulling from the\n> > 'mtd' tree will fail if the 'linus' branch there is older than the local\n> > clone's 'linus' branch. But it mostly works.\n> > \n> > Is there a better way?\n> \n> I would just remove the pluses. git-fetch will say that the branch is\n> already up-to-date, if the local branch already has everything the\n> remote has.\n\nThen after I pull from Linus' tree, I can't pull from the mtd tree -- it\ncomplains that the 'linus' branch there can't be fast-forwarded, and\nrefuses to pull the 'master' branch.\n\nI think what I actually want is an 'only fast-forward, but don't error\nif you can't' option.\n\n-- \ndwmw2\n"},{"id":"41166","messageId":"20070505225249.GE2898@steel.home","threadId":"7982","inReplyTo":"1178387429.17680.35.camel@shinybook.infradead.org","subject":"Re: 'upstream' branches.","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-05T22:52:49Z","receivedAt":"2007-05-05T22:52:49Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"David Woodhouse, Sat, May 05, 2007 19:50:28 +0200:\n> > > \n> > > Is there a better way?\n> > \n> > I would just remove the pluses. git-fetch will say that the branch is\n> > already up-to-date, if the local branch already has everything the\n> > remote has.\n> \n> Then after I pull from Linus' tree, I can't pull from the mtd tree -- it\n> complains that the 'linus' branch there can't be fast-forwarded, and\n> refuses to pull the 'master' branch.\n\nWhich got me by surprise (just tried). I though it'd notice that all\nthe commits are already present...\n\nExperts, is it really supposed to be that way?\n"},{"id":"41177","messageId":"7v3b2ah30f.fsf@assigned-by-dhcp.cox.net","threadId":"7982","inReplyTo":"20070505225249.GE2898@steel.home","subject":"Re: 'upstream' branches.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-06T06:36:48Z","receivedAt":"2007-05-06T06:36:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> David Woodhouse, Sat, May 05, 2007 19:50:28 +0200:\n>> > > \n>> > > Is there a better way?\n>> > \n>> > I would just remove the pluses. git-fetch will say that the branch is\n>> > already up-to-date, if the local branch already has everything the\n>> > remote has.\n>> \n>> Then after I pull from Linus' tree, I can't pull from the mtd tree -- it\n>> complains that the 'linus' branch there can't be fast-forwarded, and\n>> refuses to pull the 'master' branch.\n>\n> Which got me by surprise (just tried). I though it'd notice that all\n> the commits are already present...\n>\n> Experts, is it really supposed to be that way?\n\nI am not sure what the issue is here.  If the copy of Linus's\ntip mtd tree has is behind the current Linus's tip, after you\nfetch from Linus's tree to obtain its tip, if you allowed the\nfetch from mtd tree to update the remote tracking ref that you\nuse to keep track of where Linus is, it would _rewind_ it, so I\nthink it is natural to warn/prevent that mistake.\n\nI think David's use of linus ref is bogus.  What is he really\ntrying to \"track\"?  If he is trying to track where the tip of\nLinus's tree is, he should not let fetch from mtd to muck with\nthat remote tracking ref that he uses to track Linus's tree.\n\nOn the other hand, I think it is perfectly reasonable thing to\nwant to track where the tip of Linus's tree is \"from mtd tree's\npoint of view\".  Then diff between \"mtd's idea of Linus's tip\"\nand \"mtd's tip\" would represent what mtd people did, regardless\nof what Linus did in his tree, before mtd people had a chance to\nsync again with Linus.\n"},{"id":"41185","messageId":"1178436926.17680.74.camel@shinybook.infradead.org","threadId":"7982","inReplyTo":"7v3b2ah30f.fsf@assigned-by-dhcp.cox.net","subject":"Re: 'upstream' branches.","fromName":"David Woodhouse","fromEmail":"dwmw2@infradead.org","sentAt":"2007-05-06T07:35:26Z","receivedAt":"2007-05-06T07:35:26Z","isPatch":false,"sender":{"key":"dwmw2@infradead.org","avatar":"https://gravatar.com/avatar/7afd4f07e0cf7d7e046ae2d23678296b37777c96488e6f3451e78a5514154ebd?d=mp&s=160"},"body":"On Sat, 2007-05-05 at 23:36 -0700, Junio C Hamano wrote:\n> I think David's use of linus ref is bogus.  What is he really\n> trying to \"track\"?  If he is trying to track where the tip of\n> Linus's tree is, he should not let fetch from mtd to muck with\n> that remote tracking ref that he uses to track Linus's tree.\n\nI'm trying to track \"the latest commit in this tree which comes from\nLinus, either directly or indirectly\".\n\nSo that 'git-diff linus..' or 'git-log linus..' will show me what's\noutstanding against the master('s) tree. And scripts feeding the commits\nlist can ignore those commits, etc. \n\n> On the other hand, I think it is perfectly reasonable thing to\n> want to track where the tip of Linus's tree is \"from mtd tree's\n> point of view\".  Then diff between \"mtd's idea of Linus's tip\"\n> and \"mtd's tip\" would represent what mtd people did, regardless\n> of what Linus did in his tree, before mtd people had a chance to\n> sync again with Linus. \n\nRight. That's what I'm trying to track. And that 'idea of Linus' tip'\nneeds to get updated whenever we pull from Linus' tree into our\nmtd-2.6.git tree on the server -- by whatever route, even if it's\nindirectly through another repo.\n\nObviously we never actually _work_ on the tree on the server; we only\never push to it from a working repo somewhere.\n\nSo those working repositories need to have this 'linus' branch which is\nupdated when they pull directly from kernel.org, and which is pushed to\nthe mtd tree when they push.\n\nFurthermore, when unprivileged users create their own clone with commits\nthey want me to push, and if _they_ also pull from Linus' tree for some\nreason, that information should also make it into my working repo when I\npull, and then into the mtd-2.6.git tree when I push. Those unprivileged\nusers will probably want an 'mtd' branch too, to keep track of their\n_own_ outstanding changes.\n\nAnd when we do other things like the olpc-2.6.git tree ,which pulls from\nvarious other repositories (mtd, mmc, etc.), it should use the 'linus'\nbranches of each of those repositories we pull from.\n\nIs that possible? I'm fairly sure it used to be.\n\n-- \ndwmw2\n"},{"id":"41189","messageId":"7vy7k2e606.fsf@assigned-by-dhcp.cox.net","threadId":"7982","inReplyTo":"1178436926.17680.74.camel@shinybook.infradead.org","subject":"Re: 'upstream' branches.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-06T08:00:25Z","receivedAt":"2007-05-06T08:00:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Woodhouse <dwmw2@infradead.org> writes:\n\n> So that 'git-diff linus..' or 'git-log linus..' will show me what's\n> outstanding against the master('s) tree. And scripts feeding the commits\n> list can ignore those commits, etc. \n>\n>> On the other hand, I think it is perfectly reasonable thing to\n>> want to track where the tip of Linus's tree is \"from mtd tree's\n>> point of view\".  Then diff between \"mtd's idea of Linus's tip\"\n>> and \"mtd's tip\" would represent what mtd people did, regardless\n>> of what Linus did in his tree, before mtd people had a chance to\n>> sync again with Linus. \n>\n> Right. That's what I'm trying to track. And that 'idea of Linus' tip'\n> needs to get updated whenever we pull from Linus' tree into our\n> mtd-2.6.git tree on the server -- by whatever route, even if it's\n> indirectly through another repo.\n\nAhh, I did not mean by \"mtd's idea\" _your_ repository, but I\nmeant whichever one that was overwriting your 'linus' tracking\nbranch you are using to track fetch from Linus's tree.\n\nThe cleanest way to view \"what do we really have since the\nlatest of Linus, regardless of how and from whom we learned\nwhere the tip of Linus is\", would be not to let other trees to\ndisturb the tracking branch you use for Linus's tree with each\nother.\n\n\t[remote \"a\"] fetch = refs/heads/linus:refs/remotes/a/linus\n\t[remote \"b\"] fetch = refs/heads/linus:refs/remotes/b/linus\n\t[remote \"c\"] fetch = refs/heads/linus:refs/remotes/c/linus\n\t...\n\nThen\n\n\tgit log master --not remotes/a/linus remotes/b/linus remotes/c/linus\n\n\n> Is that possible? I'm fairly sure it used to be.\n\nI doubt we had that bug.  If you allowed overwriting with +, it\nwould not have prevented a rewind (i.e. pull from Linus and then\npull from somebody who pulled from Linus earlier than you did).\nIf you didn't, then it would have failed the fetch.\n"},{"id":"41191","messageId":"1178440759.17680.112.camel@shinybook.infradead.org","threadId":"7982","inReplyTo":"7vy7k2e606.fsf@assigned-by-dhcp.cox.net","subject":"Re: 'upstream' branches.","fromName":"David Woodhouse","fromEmail":"dwmw2@infradead.org","sentAt":"2007-05-06T08:39:19Z","receivedAt":"2007-05-06T08:39:19Z","isPatch":false,"sender":{"key":"dwmw2@infradead.org","avatar":"https://gravatar.com/avatar/7afd4f07e0cf7d7e046ae2d23678296b37777c96488e6f3451e78a5514154ebd?d=mp&s=160"},"body":"On Sun, 2007-05-06 at 01:00 -0700, Junio C Hamano wrote:\n> Ahh, I did not mean by \"mtd's idea\" _your_ repository, but I\n> meant whichever one that was overwriting your 'linus' tracking\n> branch you are using to track fetch from Linus's tree.\n\nAh, right.\n\n> The cleanest way to view \"what do we really have since the\n> latest of Linus, regardless of how and from whom we learned\n> where the tip of Linus is\", would be not to let other trees to\n> disturb the tracking branch you use for Linus's tree with each\n> other.\n> \n> \t[remote \"a\"] fetch = refs/heads/linus:refs/remotes/a/linus\n> \t[remote \"b\"] fetch = refs/heads/linus:refs/remotes/b/linus\n> \t[remote \"c\"] fetch = refs/heads/linus:refs/remotes/c/linus\n> \t...\n\nYou're speaking from the point of view of the git implementation.\n>From the point of view of the _user_, I would violently disagree :)\n\nHaving pulled that into my local repository, how do I then set it up to\npush the latest commit of refs/remotes/*/linus into the 'linus' branch\nof the origin, when I push back to my public tree on the server? Or do\nyou expect _everyone_ who pulls from that public tree to also do stuff\nlike:\n> \tgit log master --not remotes/a/linus remotes/b/linus remotes/c/linus\n\n\nCan't I instruct it to _merge_ the 'linus' branch of each remote into my\nown 'linus' branch? Of course that merge would only ever be a\nfast-forward or a no-op, in practice.\n\n-- \ndwmw2\n"},{"id":"41197","messageId":"20070506092129.GA2434@steel.home","threadId":"7982","inReplyTo":"7vy7k2e606.fsf@assigned-by-dhcp.cox.net","subject":"Re: 'upstream' branches.","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-06T09:21:29Z","receivedAt":"2007-05-06T09:21:29Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Sun, May 06, 2007 10:00:25 +0200:\n> \n> > Is that possible? I'm fairly sure it used to be.\n> \n> I doubt we had that bug.  If you allowed overwriting with +, it\n> would not have prevented a rewind (i.e. pull from Linus and then\n> pull from somebody who pulled from Linus earlier than you did).\n> If you didn't, then it would have failed the fetch.\n> \n\nMaybe we should not fail in the case the remote repo is older then\nlocal, but just to try to fast-forward local reference after a fetch\nand fail only if the fast-forward fails?\nOr introduce a new syntax for the strict reference succession and make\nfetch+fast-forward the default?\nOr the other way around, use something like \"-from:to\" to ignore\nfast-forwards failed because the \"from\" already has all the \"to\" has,\nwhich has precedents: make and its \"-include\", which ignores errors\nfrom non-existing files.\n\nLet us the local repo being in history younger then the remote:\n\nWhole history (anywhere)\t\t       : A--B--C--D\nLocal has (branch Tracking)\t\t       : A--B\nRemote1 (where the Local is doing a fetch from): A--B--C\n\nNormal case, fetch will just update its reference in Local. It is now\nat C.\n\nNow suppose we have another remote Remote2, which is on B still. If\nLocal does a fetch from that, usually the operation will fail. But if\nwe do, for example, a fetch from Remote2 and store its reference\nlocally somewhere and then try to merge Local with the stored\nreference, it shall result in nothing: everything's already merged:\n\n$ git branch\n* master\n  Tracking\n$ git fetch Remote1 master:Tracking\n...reference Tracking updated\n$ git fetch Remote2 master:tmp\n$ git checkout Tracking\n$ git merge tmp\nAlready up-to-date.\n$ git branch -d tmp\n$ git checkout master\n"},{"id":"41279","messageId":"7vabwh8m5e.fsf@assigned-by-dhcp.cox.net","threadId":"7982","inReplyTo":"1178440759.17680.112.camel@shinybook.infradead.org","subject":"Re: 'upstream' branches.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-07T01:20:29Z","receivedAt":"2007-05-07T01:20:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Woodhouse <dwmw2@infradead.org> writes:\n\n> You're speaking from the point of view of the git implementation.\n> From the point of view of the _user_, I would violently disagree :)\n\nI would not view this as an implementation issue.  If you or\nanybody disagrees, I think that is a disagreement at more\nconceptual level.\n\n> Having pulled that into my local repository, how do I then set it up to\n> push the latest commit of refs/remotes/*/linus into the 'linus' branch\n> of the origin, when I push back to my public tree on the server? Or do\n> you expect _everyone_ who pulls from that public tree to also do stuff\n> like:\n>> \tgit log master --not remotes/a/linus remotes/b/linus remotes/c/linus\n\nOf course not.  Why are you even _PUBLISHING_ what your\nupstreams' origins are to begin with?  I think you are simply\nbeing silly.\n\nSo let's step back a bit, so I can clarify why I said \"silly\" --\nI am not Linus and usually try not to say things like that ;-).\n\nFirst, I think everybody by now understands why rewinding a\nbranch in a published repository is a bad idea, and agrees that\n(at least) Linus's tip never rewinds but always goes forward.\nI see you also subscribe to the school of thought:\n\n> Can't I instruct it to _merge_ the 'linus' branch of each remote into my\n> own 'linus' branch? Of course that merge would only ever be a\n> fast-forward or a no-op, in practice.\n\nBy this, you are effectively getting the origin as seen by other\npeople, and taking the most advanced one as the union of the\norigins.\n\nBut step back and think about the reason why you would even want\nto know about the origin of each of your buddies (I earlier said\n\"upstream\" in this message, but because there is no inherent\nup/down in the distributed development model, I think it is more\ncorrect to call them your mtd buddies).\n\nEarlier I said that it would make sense for you to keep track of\nthe tip and \"the tip of Linus as seen by the buddy\" for _each_\nof your mtd buddies, by doing:\n\n\t[remote \"A\"]\n        \tfetch = refs/heads/master:refs/remotes/A/master\n                fetch = refs/heads/linus:refs/remotes/A/linus\n\nfor 'A', 'B', and 'C', your mtd buddies.  It would make sense\nbecause the log between A/linus and A/master represents what A\ndid, and what have not been incorporated in the Linus tree yet\nfrom A's point of view.  You can do\n\n\t$ git log remotes/A/linus..remotes/A/master\n\nfor that (same for B and C).  Also, diff between these would\nrepresent the change A made as a whole:\n\n\t$ git diff remotes/A/linus..remotes/A/master\n\nBut your arrangement is a bit different.  You allow the same\nbranch refs/heads/linus to be updated/overwritten by A, B and C.\nWe could teach special semantics of \"fast forward or nothing\",\nperhaps using '*' like this:\n\n\t[remote \"A\"]\n        \tfetch = refs/heads/master:refs/heads/A\n                fetch = *refs/heads/linus:refs/heads/linus\n\t[remote \"B\"]\n        \tfetch = refs/heads/master:refs/heads/B\n                fetch = *refs/heads/linus:refs/heads/linus\n\nas you suggest, but I do not think it buys you much.  The tip of\nLinus's repository B or C has may much more advanced than what A\nbased his work on, so your 'linus' may be soemthing A has not\nseen yet.  However, even then:\n\n\t$ git log linus..A\n\nwould continue to work.  On the other hand, the earlier \"diff\"\nnow needs to be written like this:\n\n\t$ git diff $(git merge-base linus A)..A\n\nBecause this is the right thing to do in regular cases anyway,\nwe even have a short-hand for that in the \"three dot\" form:\n\n\t$ git diff linus...A\n\nI think you already know these two things: \"git-log linus..A is\nthe right way to ask what A did relative to Linus, even when\n'linus' is ahead of what A based his work on\" and \"the three-dot\nnotation linus...A is the right thing to use when 'linus' could\nbe ahead of what A is based on\".  Otherwise you would not be\nasking for the \"fast forward or nothing\" fetch, as its result\nwould be hard to use without these characteristics.\n\nBut if you know them, and if you do not care exactly which\ncommit from Linus what each of your buddies thought was at\nLinus's tip (and you obviously don't, as \"fast forward or\nnothing\" would lose information for two people and keep only the\nmost advanced one), then you would also know that there is not\nmuch point fetching the origin from your buddies.  You can fetch\nand keep track of where Linus's tip is directly from Linus\nyourself, and the above \"git log linus..A\" and \"git diff\nlinus...A\" would work.  Then there is no risk of confusion.  If\none of A, B, or C had a wrong commit that claims to from Linus,\nhaving separate tracking branch on your end is necessary to\nfigure out which one has screwed up -- \"fast forward or nothing\"\nwould not help.\n\nHaving said that, I think \"fast-forward or nothing\" might make\nsense in one special case.  If the kernel project _were_ more\nregidly structured such that you were a third-stratum developer\nwho can only interact with second-stratum people and not allowed\nto fetch directly from first-stratum repository (i.e. Linus's).\nThen, the best guess you could make where the tip of Linus's\nrepository is by learning second-hand from the repositories of\nsecond-stratum you fetch, and keeping track of their origins,\nand picking the most advanced one among them.\n\nBut the kernel project is not structured that way.\n\nYou also _could_ argue that your fetching directly from Linus is\none extra fetch, and you do not _care_ where the real Linus's\ntip is.  Both of these are correct, if the only thing you care\nabout in this application is to inspect the progress your mtd\nbuddies A, B and C are making.  Even when all of them are way\nbehind from Linus's tree, \"log linus..A\"/\"diff linus...A\" would\nwork just fine.  I do not think it is unreasonable to want to\nmaintain a single 'linus' branch by picking the most advanced\namong the different 'linus' branches you get from different\nrepositories.\n\nBut at that point, I think it is such a specialized application\nthat you should be scripting that outside of git-core.\n\nOh, and to cut-down the message roundtrip (although I do not\nthink you would make such a silly argument, I do very much\nanticipate somebody else would).  I would not buy \"SCM tool\nshould do that work for me, not me doing that work for SCM\"\nargument on that last point.  It is like saying \"why doesn't\nyour editor fill a completed program when I open a new file\nwhose name is 'hello.c', and instead have me type it all?  It\nshould be clear that I want to write a \"hello world\" program,\nand the tool should be helping me\".\n"},{"id":"41298","messageId":"7vtzup6pzl.fsf@assigned-by-dhcp.cox.net","threadId":"7982","inReplyTo":"20070506092129.GA2434@steel.home","subject":"Re: 'upstream' branches.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-07T07:40:30Z","receivedAt":"2007-05-07T07:40:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> Junio C Hamano, Sun, May 06, 2007 10:00:25 +0200:\n>> \n>> > Is that possible? I'm fairly sure it used to be.\n>> \n>> I doubt we had that bug.  If you allowed overwriting with +, it\n>> would not have prevented a rewind (i.e. pull from Linus and then\n>> pull from somebody who pulled from Linus earlier than you did).\n>> If you didn't, then it would have failed the fetch.\n>> \n>\n> Maybe we should not fail in the case the remote repo is older then\n> local, but just to try to fast-forward local reference after a fetch\n> and fail only if the fast-forward fails?\n> Or introduce a new syntax for the strict reference succession and make\n> fetch+fast-forward the default?\n> Or the other way around, use something like \"-from:to\" to ignore\n> fast-forwards failed because the \"from\" already has all the \"to\" has,\n> which has precedents: make and its \"-include\", which ignores errors\n> from non-existing files.\n\nI think the whole issue would disappear if David stops using the\nsame 'linus' tracking branch to track origins from *different*\nrepositories (see my other message on the thread), and I think\nit makes the above suggestions fall somewhat in \"solutions\nlooking for a problem\" category.  If this is a common enough\nmisconfiguration, we might want to add a sanity check to catch\nPull: lines in different remotes/ files and remote.*.fetch\nconfigurations for different remotes cause the same tracking\nbranch to be updated, but I personally do not think it is even\nworth it.\n\nHaving said that, I suspect that making the default <src>:<dst>\n(without 'force') to ignore pure rewind (not rewind+rebuild)\nmight make sense without having much downside.  If the remote\nrepository owner rewinds its tip, current code catches it as a\npossible mistake of the remote side, but until it starts\nbuilding a different history on top of that rewound head, there\nreally is no harm done.\n\nOne common case that can be helped with such a behaviour change\nis when your remote.*.url points at a single URL that actually\nis backed by more than one mirrors --- think of www.kernel.org\nwhich resolves to two actual hosts via DNS round robin.  If you\nfetch from one server, and then fetch again from the other\nserver that was behind (maybe rsync cron job got stuck for some\nunspecified reason), you would observe that the tip was rewound.\n\nSomething like this untested patch should be sufficient if we\nwant to go this route, but I am not convinced yet that this is\nthe right thing to do.  For one thing, it is not clear to me\nwhat should happen if --force is in effect.  Should this honor\nthe \"wish\" of the remote repository owner to rewind this ref, or\nshould we assume that it was two servers with mirroring\ninconsistency fluke and ignore the rewind, hoping that the next\nround will straighten the situation out?  What does --force\ninstructs us to do in such a case?\n\ndiff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c\nindex 2065466..29d7fe1 100644\n--- a/builtin-fetch--tool.c\n+++ b/builtin-fetch--tool.c\n@@ -119,6 +119,12 @@ static int update_local_ref(const char *name,\n \t\treturn update_ref(\"fast forward\", name, sha1_new, sha1_old);\n \t}\n \tif (!force) {\n+\t\tif (in_merge_bases(updated, &current, 1)) {\n+\t\t\tfprintf(stderr, \"* %s: ignoring straight rewind %s\\n\",\n+\t\t\t\tname, note);\n+\t\t\tfprintf(stderr, \"  old..new: %s..%s\\n\", oldh, newh);\n+\t\t\treturn 0;\n+\t\t}\n \t\tfprintf(stderr,\n \t\t\t\"* %s: not updating to non-fast forward %s\\n\",\n \t\t\tname, note);\n"},{"id":"41308","messageId":"81b0412b0705070139v49f045d2j3929b38846e20120@mail.gmail.com","threadId":"7982","inReplyTo":"7vtzup6pzl.fsf@assigned-by-dhcp.cox.net","subject":"Re: 'upstream' branches.","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-07T08:39:56Z","receivedAt":"2007-05-07T08:39:56Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 5/7/07, Junio C Hamano <junkio@cox.net> wrote:\n> >\n> > Maybe we should not fail in the case the remote repo is older then\n> > local, but just to try to fast-forward local reference after a fetch\n> > and fail only if the fast-forward fails?\n...\n>\n> Something like this untested patch should be sufficient if we\n> want to go this route, but I am not convinced yet that this is\n> the right thing to do.  ...\n\nNow, after I thought about that a bit more (and after your explanation\nabout David being silly), I think I was kind of silly as well.\n\nThe idea looks a bit dangerous (because of the local and remote\ncan divert from each other). If any, the reference mapping\nsyntax should clearly reveal that, more like\n\n    \"TRY-FAST-FORWARD-MERGE ref1:ref2\"\n\ninstead of that hideous minus. And come to think about that, I'd still\nprefer to do that manually, as a real merge (I cannot know in advance\n_when_ the repos divert, and which one of source repos will divert,\nto entrust the operation an unattended process, and I have get-fetch\nin cron files sometimes), so count me out as a user of that feature.\n"},{"id":"41309","messageId":"1178527861.11851.110.camel@pmac.infradead.org","threadId":"7982","inReplyTo":"7vabwh8m5e.fsf@assigned-by-dhcp.cox.net","subject":"Re: 'upstream' branches.","fromName":"David Woodhouse","fromEmail":"dwmw2@infradead.org","sentAt":"2007-05-07T08:51:01Z","receivedAt":"2007-05-07T08:51:01Z","isPatch":false,"sender":{"key":"dwmw2@infradead.org","avatar":"https://gravatar.com/avatar/7afd4f07e0cf7d7e046ae2d23678296b37777c96488e6f3451e78a5514154ebd?d=mp&s=160"},"body":"On Sun, 2007-05-06 at 18:20 -0700, Junio C Hamano wrote:\n> Of course not.  Why are you even _PUBLISHING_ what your\n> upstreams' origins are to begin with? \n\nI have the master mtd-2.6.git tree on the server, of course. \nI have a bunch of clones of that, on various computers I might be\nsitting in front of. On each of those, I might pull from the upstream\ntree (directly or indirectly) and push to my server. On each of those, I\nmight pull from my server and then set about pushing stuff to linus,\nwhich starts with 'git-diff linus..' to vet it for sanity and 'git-log\nlinus..' to create a pull request.\n\nI don't _care_ how commits from Linus' tree get into my tree. I just\nwant to know which is the latest commit in my tree that came from\nupstream. How it got there is an implementation detail.\n\nThe other thing it's used for is excluding upstream commits from being\nsent to the MTD commits list. Anything in the 'linus' branch won't get\nsent. I _do_ have a fallback which also excludes any commits in the\nlocal mirror of upstream -- but that mirror is pulled by git:// and only\ndaily, while my merges are usually from ssh://master.kernel.org/... so\nwhen I merge and push to the server, the 'linus' branch may be many\ncommits ahead of the local mirror of upstream.\n\n> By this, you are effectively getting the origin as seen by other\n> people, and taking the most advanced one as the union of the\n> origins.\n> \n> But step back and think about the reason why you would even want\n> to know about the origin of each of your buddies \n\nI don't. Except when I've pulled from them, and they've pulled from\nLinus since I did. When I prepare for a merge to Linus, I don't _care_\nabout the last time _I_ pulled from upstream. I just care about the\nlatest commit which came from upstream, by whatever route.\n\nLikewise, when I'm working on the OLPC git tree and I want to see what\nwe've got outstanding from Linus' tree.\n\n> ... On the other hand, the earlier \"diff\" now needs to be written like\n> this:\n> \n> \t$ git diff $(git merge-base linus A)..A\n> \n> Because this is the right thing to do in regular cases anyway,\n> we even have a short-hand for that in the \"three dot\" form:\n> \n> \t$ git diff linus...A\n> \n> I think you already know these two things: \"git-log linus..A is\n> the right way to ask what A did relative to Linus, even when\n> 'linus' is ahead of what A based his work on\" and \"the three-dot\n> notation linus...A is the right thing to use when 'linus' could\n> be ahead of what A is based on\". \n\nOK, that works for much of the local tracking stuff -- I wasn't\npreviously aware of the 'linus...A' notation.\n\nSo I can just 'git-fetch linus; git-log linus...' when preparing to\nmerge upstream, instead of trying to keep track of the merge-base across\nmany repositories. Thanks.\n\nIt doesn't solve the problem of what to exclude from the commits list. \nBut it does at least reduce the scope of the problem -- I only need to\nhandle that on my own trees, and it _will_ only ever go forward (because\nI only ever do 'git-pull linus' in my clone of the mtd tree if it's\ngoing to be immediately followed by 'git-push origin'.\n\n-- \ndwmw2\n"}]}