* '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: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  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-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
* 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
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).