* 'upstream' branches.
@ 2007-05-05 12:29 David Woodhouse
2007-05-05 17:44 ` Alex Riesen
0 siblings, 1 reply; 13+ messages in thread
From: David Woodhouse @ 2007-05-05 12:29 UTC (permalink / raw)
To: git
When creating a repository which may pull from one or more 'upstream'
repositories, it's useful to keep 'branches' which keep track of the
last pull from those upstream repositories -- either directly or
indirectly.
At http://www.linux-mtd.infradead.org/doc/git.html I've described the
setup I'm currently using to achieve this, which looks something like
the following:
[remote "origin"]
url = ssh://git.infradead.org/~/public_git/foo-2.6.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/heads/mtd:refs/heads/mtd
fetch = +refs/heads/linus:refs/heads/linus
push = refs/heads/master:refs/heads/master
push = refs/heads/mtd:refs/heads/mtd
push = refs/heads/linus:refs/heads/linus
[branch "master"]
remote = origin
merge = refs/heads/master
[remote "mtd"]
url = git://git.infradead.org/mtd-2.6.git
fetch = refs/heads/master:refs/heads/mtd
fetch = +refs/heads/linus:refs/heads/linus
[remote "linus"]
url = git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.$
fetch = refs/heads/master:refs/heads/linus
Is there a better way to do this? Preferably which doesn't involve
directing the user to edit .git/config directly?
Basically, I want the local 'linus' branch to be updated whenever the
user pulls from _any_ other repository with a 'linus' branch, so that
the 'linus' branch always represents the latest commit pulled from
upstream. Likewise, the 'mtd' branch should be updated when pulling from
that tree (or any other dependent tree which will have an 'mtd' branch).
These branches should be pushed back to the origin each time.
What I have at the moment isn't ideal because I think pulling from the
'mtd' tree will fail if the 'linus' branch there is older than the local
clone's 'linus' branch. But it mostly works.
Is there a better way?
--
dwmw2
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: 'upstream' branches. 2007-05-05 12:29 'upstream' branches David Woodhouse @ 2007-05-05 17:44 ` Alex Riesen 2007-05-05 17:50 ` David Woodhouse 0 siblings, 1 reply; 13+ messages in thread From: Alex Riesen @ 2007-05-05 17:44 UTC (permalink / raw) To: David Woodhouse; +Cc: git David Woodhouse, Sat, May 05, 2007 14:29:26 +0200: > [remote "origin"] > url = ssh://git.infradead.org/~/public_git/foo-2.6.git > fetch = +refs/heads/*:refs/remotes/origin/* > fetch = +refs/heads/mtd:refs/heads/mtd > fetch = +refs/heads/linus:refs/heads/linus These pluses request overwriting of the local reference even if it has more commits than the remote ("is newer"). Are you sure you want that? > What I have at the moment isn't ideal because I think pulling from the > 'mtd' tree will fail if the 'linus' branch there is older than the local > clone's 'linus' branch. But it mostly works. > > Is there a better way? I would just remove the pluses. git-fetch will say that the branch is already up-to-date, if the local branch already has everything the remote has. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-05 17:44 ` Alex Riesen @ 2007-05-05 17:50 ` David Woodhouse 2007-05-05 22:52 ` Alex Riesen 0 siblings, 1 reply; 13+ messages in thread From: David Woodhouse @ 2007-05-05 17:50 UTC (permalink / raw) To: Alex Riesen; +Cc: git On Sat, 2007-05-05 at 19:44 +0200, Alex Riesen wrote: > David Woodhouse, Sat, May 05, 2007 14:29:26 +0200: > > [remote "origin"] > > url = ssh://git.infradead.org/~/public_git/foo-2.6.git > > fetch = +refs/heads/*:refs/remotes/origin/* > > fetch = +refs/heads/mtd:refs/heads/mtd > > fetch = +refs/heads/linus:refs/heads/linus > > These pluses request overwriting of the local reference even if it has > more commits than the remote ("is newer"). Are you sure you want that? > > > What I have at the moment isn't ideal because I think pulling from the > > 'mtd' tree will fail if the 'linus' branch there is older than the local > > clone's 'linus' branch. But it mostly works. > > > > Is there a better way? > > I would just remove the pluses. git-fetch will say that the branch is > already up-to-date, if the local branch already has everything the > remote has. Then after I pull from Linus' tree, I can't pull from the mtd tree -- it complains that the 'linus' branch there can't be fast-forwarded, and refuses to pull the 'master' branch. I think what I actually want is an 'only fast-forward, but don't error if you can't' option. -- dwmw2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-05 17:50 ` David Woodhouse @ 2007-05-05 22:52 ` Alex Riesen 2007-05-06 6:36 ` Junio C Hamano 0 siblings, 1 reply; 13+ messages in thread From: Alex Riesen @ 2007-05-05 22:52 UTC (permalink / raw) To: David Woodhouse; +Cc: git, Junio C Hamano David Woodhouse, Sat, May 05, 2007 19:50:28 +0200: > > > > > > Is there a better way? > > > > I would just remove the pluses. git-fetch will say that the branch is > > already up-to-date, if the local branch already has everything the > > remote has. > > Then after I pull from Linus' tree, I can't pull from the mtd tree -- it > complains that the 'linus' branch there can't be fast-forwarded, and > refuses to pull the 'master' branch. Which got me by surprise (just tried). I though it'd notice that all the commits are already present... Experts, is it really supposed to be that way? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-05 22:52 ` Alex Riesen @ 2007-05-06 6:36 ` Junio C Hamano 2007-05-06 7:35 ` David Woodhouse 0 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2007-05-06 6:36 UTC (permalink / raw) To: Alex Riesen; +Cc: David Woodhouse, git Alex Riesen <raa.lkml@gmail.com> writes: > David Woodhouse, Sat, May 05, 2007 19:50:28 +0200: >> > > >> > > Is there a better way? >> > >> > I would just remove the pluses. git-fetch will say that the branch is >> > already up-to-date, if the local branch already has everything the >> > remote has. >> >> Then after I pull from Linus' tree, I can't pull from the mtd tree -- it >> complains that the 'linus' branch there can't be fast-forwarded, and >> refuses to pull the 'master' branch. > > Which got me by surprise (just tried). I though it'd notice that all > the commits are already present... > > Experts, is it really supposed to be that way? I am not sure what the issue is here. If the copy of Linus's tip mtd tree has is behind the current Linus's tip, after you fetch from Linus's tree to obtain its tip, if you allowed the fetch from mtd tree to update the remote tracking ref that you use to keep track of where Linus is, it would _rewind_ it, so I think it is natural to warn/prevent that mistake. I think David's use of linus ref is bogus. What is he really trying to "track"? If he is trying to track where the tip of Linus's tree is, he should not let fetch from mtd to muck with that remote tracking ref that he uses to track Linus's tree. On the other hand, I think it is perfectly reasonable thing to want to track where the tip of Linus's tree is "from mtd tree's point of view". Then diff between "mtd's idea of Linus's tip" and "mtd's tip" would represent what mtd people did, regardless of what Linus did in his tree, before mtd people had a chance to sync again with Linus. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-06 6:36 ` Junio C Hamano @ 2007-05-06 7:35 ` David Woodhouse 2007-05-06 8:00 ` Junio C Hamano 0 siblings, 1 reply; 13+ messages in thread From: David Woodhouse @ 2007-05-06 7:35 UTC (permalink / raw) To: Junio C Hamano; +Cc: Alex Riesen, git On Sat, 2007-05-05 at 23:36 -0700, Junio C Hamano wrote: > I think David's use of linus ref is bogus. What is he really > trying to "track"? If he is trying to track where the tip of > Linus's tree is, he should not let fetch from mtd to muck with > that remote tracking ref that he uses to track Linus's tree. I'm trying to track "the latest commit in this tree which comes from Linus, either directly or indirectly". So that 'git-diff linus..' or 'git-log linus..' will show me what's outstanding against the master('s) tree. And scripts feeding the commits list can ignore those commits, etc. > On the other hand, I think it is perfectly reasonable thing to > want to track where the tip of Linus's tree is "from mtd tree's > point of view". Then diff between "mtd's idea of Linus's tip" > and "mtd's tip" would represent what mtd people did, regardless > of what Linus did in his tree, before mtd people had a chance to > sync again with Linus. Right. That's what I'm trying to track. And that 'idea of Linus' tip' needs to get updated whenever we pull from Linus' tree into our mtd-2.6.git tree on the server -- by whatever route, even if it's indirectly through another repo. Obviously we never actually _work_ on the tree on the server; we only ever push to it from a working repo somewhere. So those working repositories need to have this 'linus' branch which is updated when they pull directly from kernel.org, and which is pushed to the mtd tree when they push. Furthermore, when unprivileged users create their own clone with commits they want me to push, and if _they_ also pull from Linus' tree for some reason, that information should also make it into my working repo when I pull, and then into the mtd-2.6.git tree when I push. Those unprivileged users will probably want an 'mtd' branch too, to keep track of their _own_ outstanding changes. And when we do other things like the olpc-2.6.git tree ,which pulls from various other repositories (mtd, mmc, etc.), it should use the 'linus' branches of each of those repositories we pull from. Is that possible? I'm fairly sure it used to be. -- dwmw2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-06 7:35 ` David Woodhouse @ 2007-05-06 8:00 ` Junio C Hamano 2007-05-06 8:39 ` David Woodhouse 2007-05-06 9:21 ` Alex Riesen 0 siblings, 2 replies; 13+ messages in thread From: Junio C Hamano @ 2007-05-06 8:00 UTC (permalink / raw) To: David Woodhouse; +Cc: Alex Riesen, git David Woodhouse <dwmw2@infradead.org> writes: > So that 'git-diff linus..' or 'git-log linus..' will show me what's > outstanding against the master('s) tree. And scripts feeding the commits > list can ignore those commits, etc. > >> On the other hand, I think it is perfectly reasonable thing to >> want to track where the tip of Linus's tree is "from mtd tree's >> point of view". Then diff between "mtd's idea of Linus's tip" >> and "mtd's tip" would represent what mtd people did, regardless >> of what Linus did in his tree, before mtd people had a chance to >> sync again with Linus. > > Right. That's what I'm trying to track. And that 'idea of Linus' tip' > needs to get updated whenever we pull from Linus' tree into our > mtd-2.6.git tree on the server -- by whatever route, even if it's > indirectly through another repo. Ahh, I did not mean by "mtd's idea" _your_ repository, but I meant whichever one that was overwriting your 'linus' tracking branch you are using to track fetch from Linus's tree. The cleanest way to view "what do we really have since the latest of Linus, regardless of how and from whom we learned where the tip of Linus is", would be not to let other trees to disturb the tracking branch you use for Linus's tree with each other. [remote "a"] fetch = refs/heads/linus:refs/remotes/a/linus [remote "b"] fetch = refs/heads/linus:refs/remotes/b/linus [remote "c"] fetch = refs/heads/linus:refs/remotes/c/linus ... Then git log master --not remotes/a/linus remotes/b/linus remotes/c/linus > Is that possible? I'm fairly sure it used to be. I doubt we had that bug. If you allowed overwriting with +, it would not have prevented a rewind (i.e. pull from Linus and then pull from somebody who pulled from Linus earlier than you did). If you didn't, then it would have failed the fetch. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-06 8:00 ` Junio C Hamano @ 2007-05-06 8:39 ` David Woodhouse 2007-05-07 1:20 ` Junio C Hamano 2007-05-06 9:21 ` Alex Riesen 1 sibling, 1 reply; 13+ messages in thread From: David Woodhouse @ 2007-05-06 8:39 UTC (permalink / raw) To: Junio C Hamano; +Cc: Alex Riesen, git On Sun, 2007-05-06 at 01:00 -0700, Junio C Hamano wrote: > Ahh, I did not mean by "mtd's idea" _your_ repository, but I > meant whichever one that was overwriting your 'linus' tracking > branch you are using to track fetch from Linus's tree. Ah, right. > The cleanest way to view "what do we really have since the > latest of Linus, regardless of how and from whom we learned > where the tip of Linus is", would be not to let other trees to > disturb the tracking branch you use for Linus's tree with each > other. > > [remote "a"] fetch = refs/heads/linus:refs/remotes/a/linus > [remote "b"] fetch = refs/heads/linus:refs/remotes/b/linus > [remote "c"] fetch = refs/heads/linus:refs/remotes/c/linus > ... You're speaking from the point of view of the git implementation. >From the point of view of the _user_, I would violently disagree :) 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 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. -- dwmw2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-06 8:39 ` David Woodhouse @ 2007-05-07 1:20 ` Junio C Hamano 2007-05-07 8:51 ` David Woodhouse 0 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2007-05-07 1:20 UTC (permalink / raw) To: David Woodhouse; +Cc: Alex Riesen, git David Woodhouse <dwmw2@infradead.org> 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". ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-07 1:20 ` Junio C Hamano @ 2007-05-07 8:51 ` David Woodhouse 0 siblings, 0 replies; 13+ messages in thread From: David Woodhouse @ 2007-05-07 8:51 UTC (permalink / raw) To: Junio C Hamano; +Cc: Alex Riesen, git On Sun, 2007-05-06 at 18:20 -0700, Junio C Hamano wrote: > Of course not. Why are you even _PUBLISHING_ what your > upstreams' origins are to begin with? I have the master mtd-2.6.git tree on the server, of course. I have a bunch of clones of that, on various computers I might be sitting in front of. On each of those, I might pull from the upstream tree (directly or indirectly) and push to my server. On each of those, I might pull from my server and then set about pushing stuff to linus, which starts with 'git-diff linus..' to vet it for sanity and 'git-log linus..' to create a pull request. I don't _care_ how commits from Linus' tree get into my tree. I just want to know which is the latest commit in my tree that came from upstream. How it got there is an implementation detail. The other thing it's used for is excluding upstream commits from being sent to the MTD commits list. Anything in the 'linus' branch won't get sent. I _do_ have a fallback which also excludes any commits in the local mirror of upstream -- but that mirror is pulled by git:// and only daily, while my merges are usually from ssh://master.kernel.org/... so when I merge and push to the server, the 'linus' branch may be many commits ahead of the local mirror of upstream. > 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 don't. Except when I've pulled from them, and they've pulled from Linus since I did. When I prepare for a merge to Linus, I don't _care_ about the last time _I_ pulled from upstream. I just care about the latest commit which came from upstream, by whatever route. Likewise, when I'm working on the OLPC git tree and I want to see what we've got outstanding from Linus' tree. > ... 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". OK, that works for much of the local tracking stuff -- I wasn't previously aware of the 'linus...A' notation. So I can just 'git-fetch linus; git-log linus...' when preparing to merge upstream, instead of trying to keep track of the merge-base across many repositories. Thanks. It doesn't solve the problem of what to exclude from the commits list. But it does at least reduce the scope of the problem -- I only need to handle that on my own trees, and it _will_ only ever go forward (because I only ever do 'git-pull linus' in my clone of the mtd tree if it's going to be immediately followed by 'git-push origin'. -- dwmw2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-06 8:00 ` Junio C Hamano 2007-05-06 8:39 ` David Woodhouse @ 2007-05-06 9:21 ` Alex Riesen 2007-05-07 7:40 ` Junio C Hamano 1 sibling, 1 reply; 13+ messages in thread From: Alex Riesen @ 2007-05-06 9:21 UTC (permalink / raw) To: Junio C Hamano; +Cc: David Woodhouse, git, Linus Torvalds Junio C Hamano, Sun, May 06, 2007 10:00:25 +0200: > > > Is that possible? I'm fairly sure it used to be. > > I doubt we had that bug. If you allowed overwriting with +, it > would not have prevented a rewind (i.e. pull from Linus and then > pull from somebody who pulled from Linus earlier than you did). > If you didn't, then it would have failed the fetch. > Maybe we should not fail in the case the remote repo is older then local, but just to try to fast-forward local reference after a fetch and fail only if the fast-forward fails? Or introduce a new syntax for the strict reference succession and make fetch+fast-forward the default? Or the other way around, use something like "-from:to" to ignore fast-forwards failed because the "from" already has all the "to" has, which has precedents: make and its "-include", which ignores errors from non-existing files. Let us the local repo being in history younger then the remote: Whole history (anywhere) : A--B--C--D Local has (branch Tracking) : A--B Remote1 (where the Local is doing a fetch from): A--B--C Normal case, fetch will just update its reference in Local. It is now at C. Now suppose we have another remote Remote2, which is on B still. If Local does a fetch from that, usually the operation will fail. But if we do, for example, a fetch from Remote2 and store its reference locally somewhere and then try to merge Local with the stored reference, it shall result in nothing: everything's already merged: $ git branch * master Tracking $ git fetch Remote1 master:Tracking ...reference Tracking updated $ git fetch Remote2 master:tmp $ git checkout Tracking $ git merge tmp Already up-to-date. $ git branch -d tmp $ git checkout master ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-06 9:21 ` Alex Riesen @ 2007-05-07 7:40 ` Junio C Hamano 2007-05-07 8:39 ` Alex Riesen 0 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2007-05-07 7:40 UTC (permalink / raw) To: Alex Riesen; +Cc: David Woodhouse, git, Linus Torvalds Alex Riesen <raa.lkml@gmail.com> writes: > Junio C Hamano, Sun, May 06, 2007 10:00:25 +0200: >> >> > Is that possible? I'm fairly sure it used to be. >> >> I doubt we had that bug. If you allowed overwriting with +, it >> would not have prevented a rewind (i.e. pull from Linus and then >> pull from somebody who pulled from Linus earlier than you did). >> If you didn't, then it would have failed the fetch. >> > > Maybe we should not fail in the case the remote repo is older then > local, but just to try to fast-forward local reference after a fetch > and fail only if the fast-forward fails? > Or introduce a new syntax for the strict reference succession and make > fetch+fast-forward the default? > Or the other way around, use something like "-from:to" to ignore > fast-forwards failed because the "from" already has all the "to" has, > which has precedents: make and its "-include", which ignores errors > from non-existing files. I think the whole issue would disappear if David stops using the same 'linus' tracking branch to track origins from *different* repositories (see my other message on the thread), and I think it makes the above suggestions fall somewhat in "solutions looking for a problem" category. If this is a common enough misconfiguration, we might want to add a sanity check to catch Pull: lines in different remotes/ files and remote.*.fetch configurations for different remotes cause the same tracking branch to be updated, but I personally do not think it is even worth it. Having said that, I suspect that making the default <src>:<dst> (without 'force') to ignore pure rewind (not rewind+rebuild) might make sense without having much downside. If the remote repository owner rewinds its tip, current code catches it as a possible mistake of the remote side, but until it starts building a different history on top of that rewound head, there really is no harm done. One common case that can be helped with such a behaviour change is when your remote.*.url points at a single URL that actually is backed by more than one mirrors --- think of www.kernel.org which resolves to two actual hosts via DNS round robin. If you fetch from one server, and then fetch again from the other server that was behind (maybe rsync cron job got stuck for some unspecified reason), you would observe that the tip was rewound. Something like this untested patch should be sufficient if we want to go this route, but I am not convinced yet that this is the right thing to do. For one thing, it is not clear to me what should happen if --force is in effect. Should this honor the "wish" of the remote repository owner to rewind this ref, or should we assume that it was two servers with mirroring inconsistency fluke and ignore the rewind, hoping that the next round will straighten the situation out? What does --force instructs us to do in such a case? diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c index 2065466..29d7fe1 100644 --- a/builtin-fetch--tool.c +++ b/builtin-fetch--tool.c @@ -119,6 +119,12 @@ static int update_local_ref(const char *name, return update_ref("fast forward", name, sha1_new, sha1_old); } if (!force) { + if (in_merge_bases(updated, ¤t, 1)) { + fprintf(stderr, "* %s: ignoring straight rewind %s\n", + name, note); + fprintf(stderr, " old..new: %s..%s\n", oldh, newh); + return 0; + } fprintf(stderr, "* %s: not updating to non-fast forward %s\n", name, note); ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: 'upstream' branches. 2007-05-07 7:40 ` Junio C Hamano @ 2007-05-07 8:39 ` Alex Riesen 0 siblings, 0 replies; 13+ messages in thread From: Alex Riesen @ 2007-05-07 8:39 UTC (permalink / raw) To: Junio C Hamano; +Cc: David Woodhouse, git, Linus Torvalds On 5/7/07, Junio C Hamano <junkio@cox.net> wrote: > > > > Maybe we should not fail in the case the remote repo is older then > > local, but just to try to fast-forward local reference after a fetch > > and fail only if the fast-forward fails? ... > > Something like this untested patch should be sufficient if we > want to go this route, but I am not convinced yet that this is > the right thing to do. ... Now, after I thought about that a bit more (and after your explanation about David being silly), I think I was kind of silly as well. The idea looks a bit dangerous (because of the local and remote can divert from each other). If any, the reference mapping syntax should clearly reveal that, more like "TRY-FAST-FORWARD-MERGE ref1:ref2" instead of that hideous minus. And come to think about that, I'd still prefer to do that manually, as a real merge (I cannot know in advance _when_ the repos divert, and which one of source repos will divert, to entrust the operation an unattended process, and I have get-fetch in cron files sometimes), so count me out as a user of that feature. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-05-07 8:51 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-05-05 12:29 'upstream' branches David Woodhouse 2007-05-05 17:44 ` Alex Riesen 2007-05-05 17:50 ` David Woodhouse 2007-05-05 22:52 ` Alex Riesen 2007-05-06 6:36 ` Junio C Hamano 2007-05-06 7:35 ` David Woodhouse 2007-05-06 8:00 ` Junio C Hamano 2007-05-06 8:39 ` David Woodhouse 2007-05-07 1:20 ` Junio C Hamano 2007-05-07 8:51 ` David Woodhouse 2007-05-06 9:21 ` Alex Riesen 2007-05-07 7:40 ` Junio C Hamano 2007-05-07 8:39 ` Alex Riesen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).