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

Re: [ANNOUNCE] Git v2.34.0-rc2

From
Jeff King <peff@peff.net>
Date
Nov 15, 2021, 16:52 UTC
Message-ID
<YZKQXYdemZCNS/Bz@coredump.intra.peff.net>
In-Reply-To
<YY17rBFIdDl+H47I@coredump.intra.peff.net>
On Thu, Nov 11, 2021 at 03:23:09PM -0500, Jeff King wrote:
Show 14 quoted lines
> Yes, I think that framing is right: it is making SLOP much worse. We
> could similarly have had bogus timestamps in those commits which would
> cause the same outcome. So in that sense it is nothing new. On the other
> hand, I wonder how often it will cause extra traversal work (keeping in
> mind that this commit traversal is just the first stage; after we find
> the commits, then we talk all of their trees, which is the more
> expensive part).
> 
> For the case of adding new commits directly on top of another branch, I
> think there would be no change. But any time you have to walk down to a
> common fork point (e.g., imagine I made a new branch forked from an old
> bit of history), we may fail to find that. I haven't quite constructed
> an example, but I have a feeling we could end up walking over
> arbitrarily long segments of history.

I was playing around with this a bit more, and there is one subtlety in the "day-10" snippet I showed that I hadn't noted before. It's important the day-1 does not have any parents. If we used day-2 instead, then limit_list() would insert its parent (day-1, in this case) into the queue, without an UNINTERESTING flag (because it's the parent of something interesting). And thus when we call still_interesting(), we would never decrement the slop counter, because we know we are still walking back to something potentially interesting.

This "works" because we put the new commit at the end of the list via commit_list_insert_by_date(). That can be fooled, of course, because it's assuming the list is already in sorted order (which it isn't). So there could be an "old" commit at the front, and we place the parent in front of that, even though it's UNINTERESTING descendants are further back in the list.

So I do think we could walk an arbitrary string of history in this way, all the way down to the root, or to something else pointed to by a ref tip. Here's the example I came up with:

-- >8 -- git init -q repo cd repo

commit_at() {
	echo $1 >$1
	git add .
	base=1234567890
	unit=86400
	timestamp="@$((base + $1 * unit)) +0000"
	GIT_COMMITTER_DATE=$timestamp \
	GIT_AUTHOR_DATE=$timestamp \
	git commit -qm "commit at day $1"
}
# imagine a bunch of base history
for i in $(seq 100); do
	commit_at $i
done
git tag base
# And then we have some older branches hanging around.
for i in $(seq 1 10); do
	git checkout -b branch-$i base~$((60+$i))
done

# But also a newer one; it's important that this refname # sort after the other ones, because that's what confuses # the sorting. git branch new-branch

# and then somebody pushes/fetches a branch based on an old part of history, # newer than our old branches, but older than our new one. # # We won't actually create the branch here, because we're simulating the state # before the ref is created, when we do the connectivity check. old_commit=$(git rev-parse base~50) new_commit=$(echo foo | git commit-tree -p $old_commit HEAD^{tree})

# and now here's the connectivity check we would do git rev-list $new_commit --not --all >expect git rev-list --unsorted-input $new_commit --not --all >actual diff -u expect actual -- >8 --

That will report all of base~60..base~50 in the output, when it should just report the single new commit.

I don't think any of this changes the plan for the 2.34 release (in fact, it makes me more confident that reverting this change was the right thing to do). I'm just recording my notes here for revisiting the topic later.

My suspicion is that there's no easy way to make this work. We're violating the assumption in still_interesting() that it can easily find the lowest-date commit. We could drop that assumption for the unsorted case, but then I think we'd be forced to walk all the way to the root commits, which is even worse than sorting the tips.

I suspect a better solution would be to make use of generation numbers from the commit graph if we have them. The --topo-order stuff already does this, and I kind of wonder if we could piggy-back on that.

-Peff
Previous: Jeff KingNext: Junio C Hamano
Message 22 of 23 in “[ANNOUNCE] Git v2.34.0-rc2”
  1. Junio C HamanoNov 10, 2021
  2. Jeff KingNov 10, 2021
  3. Jeff KingNov 10, 2021
  4. Carlo ArenasNov 10, 2021
  5. Jeff KingNov 10, 2021
  6. Carlo ArenasNov 10, 2021
  7. Jeff KingNov 10, 2021
  8. RelNotes: mention known crasher when ssh signing with OpenSSH 8.7Carlo Marcelo Arenas Belón, Nov 10, 2021
  9. Junio C HamanoNov 10, 2021
  10. Junio C HamanoNov 10, 2021
  11. Jeff KingNov 11, 2021
  12. Junio C HamanoNov 10, 2021
  13. Johannes AltmanningerNov 10, 2021
  14. Jeff KingNov 10, 2021
  15. Junio C HamanoNov 10, 2021
  16. Jeff KingNov 11, 2021
  17. Junio C HamanoNov 11, 2021
  18. Jeff KingNov 11, 2021
  19. Junio C HamanoNov 11, 2021
  20. Patrick SteinhardtNov 15, 2021
  21. Jeff KingNov 15, 2021
  22. Jeff KingNov 15, 2021
  23. Junio C HamanoNov 13, 2021

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.