Re: 'upstream' branches.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]