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

Re: [BUG] git diff --no-index segfaults on large files (NULL object database)

From
Jeff King <peff@peff.net>
Date
Apr 5, 2026, 06:14 UTC
Message-ID
<20260405061430.GA1451922@coredump.intra.peff.net>
In-Reply-To
<7841c013-1f6e-49e3-9f47-f25044764a11@malon.dev>
On Sun, Apr 05, 2026 at 10:48:16AM +0800, Tian Yuchen wrote:
Show 14 quoted lines
> > Immediately after that commit, the switch from taking an odb to a source
> > is not helpful, though I think eventually it is used to set
> > transaction->base.source. But should the whole thing check for a NULL
> > source and return early? Or otherwise establish some kind of noop
> > transaction?
> > 
> 
> In a nutshell, are you suggesting that odb_transaction_begin() should return
> silently when source is NULL?
> 
> I understand and agree with your intention, but in practical terms, if the
> odb has not been initialised correctly, data will be lost silently here and
> the caller will not receive an error message. I’m concerned that doing this
> might lead to more bugs in certain situations

The source of data loss is not the transaction begin/end, though, but the actual write operation inside it. If I do this:

  t = odb_transaction_begin(the_repository->objects);
  if (startup_info->have_repository)
	odb_write_object(the_repository->objects, ...);
  odb_transaction_commit(t);

should it be an error? We chose not to write because we knew we did not have an odb, so there is no data to be lost. Starting or ending a transaction without an odb _is_ a noop, because there is nothing that can or will be written. It is asking to write that is the error.

In the example above you could obviously push the transaction begin/end into the conditional. But that's harder when the "if" part is happening inside a helper function, which is exactly what's going on in index_fd() here. It passes the flags (which would omit INDEX_WRITE_OBJECT) down to index_blob_packfile_transaction(), which then goes through all its regular motions without touching the odb.

This used to work because begin_odb_transaction() did quietly return NULL, and index_fd() did not have to care about the flag at all.

> Would it make more sense to treat this as a bug instead, e.g. by
> triggering a BUG() when source is NULL?

I don't think so, if the point is to be kind to callers. We should still BUG() on an actual write when there is no odb or repo, of course.

I looked over the other callers of odb_transaction_begin() and I think this is probably the only affected caller. But I don't think it's purely academic. If you teach index_fd() to use index_core() when the INDEX_WRITE_OBJECT is not set (as proposed earlier in this thread), I think you'll fall afoul of the comment at the top of the function:

          /*
           * Call xsize_t() only when needed to avoid potentially unnecessary
           * die() for large files.
           */

E.g., on a 32-bit system we'd die() on a 4GB file now (because we can't fit its size in a size_t anymore), and probably even smaller (because we'd try to mmap() it and there wouldn't be a large enough contiguous chunk of the address space).

So we really do want to follow the streaming path, even if we're not writing out the object.

-Peff
Previous: Tian YuchenNext: Justin Tobler
Message 7 of 9 in “[BUG] git diff --no-index segfaults on large files (NULL object database)”
  1. Luca StefaniApr 4, 2026
  2. Tian YuchenApr 4, 2026
  3. Luca StefaniApr 4, 2026
  4. Tian YuchenApr 4, 2026
  5. Jeff KingApr 4, 2026
  6. Tian YuchenApr 5, 2026
  7. Jeff KingApr 5, 2026
  8. Justin ToblerApr 6, 2026
  9. Junio C HamanoApr 6, 2026

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.