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

Re: gitk-1.0 released

From
Linus Torvalds <torvalds@osdl.org>
Date
May 20, 2005, 19:07 UTC
Message-ID
<Pine.LNX.4.58.0505201150220.2206@ppc970.osdl.org>
In-Reply-To
<d6l9l1$ttd$1@sea.gmane.org>
On Fri, 20 May 2005, Kari Hameenaho wrote:
Show 12 quoted lines
> Paul Mackerras wrote:
> > 
> > Yes, indeed.  I'll have to think about how to do it in a responsive
> > fashion, since getting the necessary information involves reading all
> > the commits and all the tree objects back to the beginning of time,
> > AFAICS.  
> 
> Maybe its not necessary to go back all the way. It is possible to look only
> commits between 2.6.12-rc4 and 2.6.12-rc3, like follows (needs just a few
> fixes to gitk):
> 
> gitk -d $(commit-id v2.6.12-rc4) ^$(parent-id $(commit-id v2.6.12-rc3))
But that _does_ actually go back all the way in time.
It does so inside of "git-rev-tree", and that's why git-rev-tree is slow.

What you can do, is to special-case certain things that git-rev-tree does, and try to do them more efficiently.

For example, git-rev-list is much nicer to use, exactly because it does only one very particular special case of what git-rev-tree does, ie "list all revisions". Because it's a special case, you can do it incrementally.

Similarly, you _can_ actually do "git-rev-tree HEAD ^OLD_HEAD" as a special case too, and do it "as incrementally as possible". It's more complicated than the (trivial) git-rev-list, so I've not actually done it, but it's clearly important enough that I _should_ do it.

The way to do it "as incrementally as possible" is to start with the 
HEAD, and walk down and print out everything until you hit OLD_HEAD or a 
merge. Then:
 - If you hit OLD_HEAD, you're done.
 - If you hit a merge, you know the merge itself wasn't in OLD_HEAD, but 
   now one of the sides might contain OLD_HEAD which might have a merge
   pointing to the other side, so you don't know if you should show any of 
   the commits below it. What you do is:
    - walk down both paths in date order - like rev-list does - until you 
      _do_ hit OLD_HEAD. Here "date order" ends up being an approximation 
      for "how do I avoid going down a long chain that ends up already 
      being pointed to by OLD_HEAD"
    - mark everything reachable from OLD_HEAD as being uninteresting (aka 
      "seen"), and everything that reaches OLD_HEAD as being interesting
      and print it out.
    - as long as there are commits that aren't marked either uninteresting 
      _or_ interesting (they are unknown) continue to walk the commit 
      chain in date order, where the parent(s) of an uninteresting commit 
      is always uninteresting.
    - eventually, you'll have no unknowns left, and you can stop.

In the worst case, you'll end up walking back to the root (somebody did development against the root, and then merged that development up after OLD_HEAD), but that ends up being increasingly unlikely as the project grows, so in practice this kind of algorithm will always end up doign work that is comparable to the amount of development between OLD_HEAD and HEAD, and independent of the total history size.

I might have missed some detail in the above, but it should be _fairly_ straightforward to start with rev-list.c and make it generate the lists of "interesting", "uninteresting" and "unknown" commits and do the above.

Is anybody up for coding up this small exercise in graph traversal?
		Linus
Previous: Kari HameenahoNext: Jon Seymour
Message 8 of 14 in “gitk-1.0 released”
  1. Paul MackerrasMay 19, 2005
  2. Ingo MolnarMay 19, 2005
  3. Ingo MolnarMay 19, 2005
  4. Paul MackerrasMay 19, 2005
  5. Ingo MolnarMay 20, 2005
  6. Ingo MolnarMay 20, 2005
  7. Kari HameenahoMay 20, 2005
  8. Linus TorvaldsMay 20, 2005
  9. Jon SeymourMay 21, 2005
  10. Linus TorvaldsMay 21, 2005
  11. Benjamin HerrenschmidtMay 19, 2005
  12. Frank SorensonMay 20, 2005
  13. waltMay 20, 2005
  14. Ingo MolnarMay 28, 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.