git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] Do not call git-rev-list from git-fetch-pack

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Oct 21, 2005, 09:35 UTC
Message-ID
<Pine.LNX.4.63.0510211111440.4950@wbgn013.biozentrum.uni-wuerzburg.de>
In-Reply-To
<7virvrw8w1.fsf@assigned-by-dhcp.cox.net>
Hi,
On Fri, 21 Oct 2005, Junio C Hamano wrote:
Show 16 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > +	   Branch1 has 40 commits since it last merged with branch2,
> > +	   and branch2 has 2 more commits since then.
> > +
> > +	   On the other end, branch1 is up-to-date, but branch2 is not.
> > +	   When fetching branch1, the 40 commits get sent, the first
> > +	   is acknowledged as common, and the local head of branch2
> > +	   never gets sent.
> > +
> > +	   As a consequence, the whole history of branch2
> > +	   (git-rev-list branch2 ^branch1) gets packed and transmitted.
> 
> Arrrgggggggh.  The description above captures the essense of the
> problem very well, but faking dates and still popping by recency
> looks like a really ugly hack to me.

It is ugly. But it is a good heuristic. And the code is simple, because I could use the existing functions for inserting into a commit_list.

Show 9 quoted lines
> Wouldn't it be cleaner if you traversed commits starting from
> local refs, and assign distance from the tip of the branch to
> each object (use generic object->util field for it), and
> maintain an object_list that is sorted by depth, similar to
> commit_list sorted by commit date?  Then you can pop from the
> list by depth, closer to tip first, and tell the other end that
> you have branch1, branch2, branch1^, branch2^, branch1~2,
> branch2~1,...  which is the order the above situation benefits
> from.

I have an example from the real world why this is bad as well: I have a repository imported from CVS, which has this silly CVS initial import marked as it's own branch. This was long, long, long ago, but git-cvsimport faithfully creates the branch "initial" for it anyway.

Imagine now the case that I added 40 revisions locally between the last fetch and now. What would happen is this:

In both cases, your git-fetch-pack and mine, the tips would get sent, the (very old one) "initial" acknowledged. A few of those 40 revisions would get sent, too, (and in your case, the root rev), but not at all the optimal merge base. In essence, almost all would get sent again.

How about this on top of your idea:

Send only those branch{i}^n where n is a power of 2. This is a tradeoff between the speed we find sensible common revs, and the accurateness of the best pick.

Note that the best thing would probably be to add a binary search to that, and *not* stop at the first ack'ed rev, but rather count them, and stop at MAX_HAS.

Ciao, Dscho

Previous: Junio C HamanoNext: Junio C Hamano
Message 3 of 9 in “Do not call git-rev-list from git-fetch-pack”
  1. Do not call git-rev-list from git-fetch-packJohannes Schindelin, Oct 21, 2005
  2. Junio C HamanoOct 21, 2005
  3. Johannes SchindelinOct 21, 2005
  4. Junio C HamanoOct 21, 2005
  5. Johannes SchindelinOct 21, 2005
  6. Junio C HamanoOct 21, 2005
  7. Johannes SchindelinOct 22, 2005
  8. Daniel BarkalowOct 21, 2005
  9. Johannes SchindelinOct 21, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.