David Woodhouse <dwmw2@xxxxxxxxxxxxx> writes: > You're speaking from the point of view of the git implementation. > From the point of view of the _user_, I would violently disagree :) I would not view this as an implementation issue. If you or anybody disagrees, I think that is a disagreement at more conceptual level. > Having pulled that into my local repository, how do I then set it up to > push the latest commit of refs/remotes/*/linus into the 'linus' branch > of the origin, when I push back to my public tree on the server? Or do > you expect _everyone_ who pulls from that public tree to also do stuff > like: >> git log master --not remotes/a/linus remotes/b/linus remotes/c/linus Of course not. Why are you even _PUBLISHING_ what your upstreams' origins are to begin with? I think you are simply being silly. So let's step back a bit, so I can clarify why I said "silly" -- I am not Linus and usually try not to say things like that ;-). First, I think everybody by now understands why rewinding a branch in a published repository is a bad idea, and agrees that (at least) Linus's tip never rewinds but always goes forward. I see you also subscribe to the school of thought: > Can't I instruct it to _merge_ the 'linus' branch of each remote into my > own 'linus' branch? Of course that merge would only ever be a > fast-forward or a no-op, in practice. By this, you are effectively getting the origin as seen by other people, and taking the most advanced one as the union of the origins. But step back and think about the reason why you would even want to know about the origin of each of your buddies (I earlier said "upstream" in this message, but because there is no inherent up/down in the distributed development model, I think it is more correct to call them your mtd buddies). Earlier I said that it would make sense for you to keep track of the tip and "the tip of Linus as seen by the buddy" for _each_ of your mtd buddies, by doing: [remote "A"] fetch = refs/heads/master:refs/remotes/A/master fetch = refs/heads/linus:refs/remotes/A/linus for 'A', 'B', and 'C', your mtd buddies. It would make sense because the log between A/linus and A/master represents what A did, and what have not been incorporated in the Linus tree yet from A's point of view. You can do $ git log remotes/A/linus..remotes/A/master for that (same for B and C). Also, diff between these would represent the change A made as a whole: $ git diff remotes/A/linus..remotes/A/master But your arrangement is a bit different. You allow the same branch refs/heads/linus to be updated/overwritten by A, B and C. We could teach special semantics of "fast forward or nothing", perhaps using '*' like this: [remote "A"] fetch = refs/heads/master:refs/heads/A fetch = *refs/heads/linus:refs/heads/linus [remote "B"] fetch = refs/heads/master:refs/heads/B fetch = *refs/heads/linus:refs/heads/linus as you suggest, but I do not think it buys you much. The tip of Linus's repository B or C has may much more advanced than what A based his work on, so your 'linus' may be soemthing A has not seen yet. However, even then: $ git log linus..A would continue to work. On the other hand, the earlier "diff" now needs to be written like this: $ git diff $(git merge-base linus A)..A Because this is the right thing to do in regular cases anyway, we even have a short-hand for that in the "three dot" form: $ git diff linus...A I think you already know these two things: "git-log linus..A is the right way to ask what A did relative to Linus, even when 'linus' is ahead of what A based his work on" and "the three-dot notation linus...A is the right thing to use when 'linus' could be ahead of what A is based on". Otherwise you would not be asking for the "fast forward or nothing" fetch, as its result would be hard to use without these characteristics. But if you know them, and if you do not care exactly which commit from Linus what each of your buddies thought was at Linus's tip (and you obviously don't, as "fast forward or nothing" would lose information for two people and keep only the most advanced one), then you would also know that there is not much point fetching the origin from your buddies. You can fetch and keep track of where Linus's tip is directly from Linus yourself, and the above "git log linus..A" and "git diff linus...A" would work. Then there is no risk of confusion. If one of A, B, or C had a wrong commit that claims to from Linus, having separate tracking branch on your end is necessary to figure out which one has screwed up -- "fast forward or nothing" would not help. Having said that, I think "fast-forward or nothing" might make sense in one special case. If the kernel project _were_ more regidly structured such that you were a third-stratum developer who can only interact with second-stratum people and not allowed to fetch directly from first-stratum repository (i.e. Linus's). Then, the best guess you could make where the tip of Linus's repository is by learning second-hand from the repositories of second-stratum you fetch, and keeping track of their origins, and picking the most advanced one among them. But the kernel project is not structured that way. You also _could_ argue that your fetching directly from Linus is one extra fetch, and you do not _care_ where the real Linus's tip is. Both of these are correct, if the only thing you care about in this application is to inspect the progress your mtd buddies A, B and C are making. Even when all of them are way behind from Linus's tree, "log linus..A"/"diff linus...A" would work just fine. I do not think it is unreasonable to want to maintain a single 'linus' branch by picking the most advanced among the different 'linus' branches you get from different repositories. But at that point, I think it is such a specialized application that you should be scripting that outside of git-core. Oh, and to cut-down the message roundtrip (although I do not think you would make such a silly argument, I do very much anticipate somebody else would). I would not buy "SCM tool should do that work for me, not me doing that work for SCM" argument on that last point. It is like saying "why doesn't your editor fill a completed program when I open a new file whose name is 'hello.c', and instead have me type it all? It should be clear that I want to write a "hello world" program, and the tool should be helping me". - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html