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

[PATCH 00/11] writing out a huge blob to working tree

From
Junio C Hamano <gitster@pobox.com>
Date
May 16, 2011, 00:30 UTC
Message-ID
<1305505831-31587-1-git-send-email-gitster@pobox.com>

Traditionally, git always read the full contents of an object in memory before performing various operations on it, e.g. comparing for diff, writing it to the working tree, etc. A huge blob that you cannot fit in memory was very cumbersome to handle.

Recently "diff" learned to avoid reading the contents only to say "Binary files differ" when these large blobs are marked as binary. Also there is a topic cooking to teach "git add" to stream a large file directly to a packfile without keeping the whole thing in core.

The "checkout" codepath is to learn the trick next, and this is the series to attempt to do so. These would apply cleanly on top of three other topics still in 'next' or 'pu', namely:

 - jc/convert that cleans up the conversion;
 - jc/replacing that cleans up the object replacement;
 - jc/bigfile that teaches "git add" to handle large files.

Patch 1 and 5 are trivial clean-ups and refactoring. These could be separated out of the series and applied much earlier, but nothing other than this series directly benefit from these changes, so they are here in the series.

Patch 2, 3, and 4 enhances the sha1_file layer.

Patch 6 introduces a new API that takes an object name and gives back a "handle" you can read from (think: FILE *) the contents of the object. The implementation at this step is deliberately kept simple: it just calls read_sha1_file() to read everything in memory.

Patch 7 then uses the new API in the "git checkout" codepath, namely, in entry.c::write_entry() function. At this point, any blob that does not require smudge filters including crlf conversion would pass through this new codepath and used the 'incore' case of the streaming API, which means that (1) "hold everything in memory and process" limitation is not lifted yet, and that (2) breakage detected in here would have meant either the simple 'incore' implementation of the streaming API is broken (not likely), or its caller streaming_write_entry() is broken (more likely).

Patch 8 teaches the new write-out codepath to detect and make holes in the resulting file. This is primarily meant to help testing---when you add a large test file that weighs 1GB with "git add" (see how it is done in the test t/t1050-large.sh on jc/bigfile topic) and check it out, you do not want to end up with 1GB file fully populated with real blocks in your working tree.

Patch 9 teaches the streaming API how to read a non-delta object directly from packfile, without holding the entire result in the memory. This is the representation jc/bigfile topic creates for a huge file, and the primary interest of this topic.

Patch 10 and 11 teaches the streaming API how to read a loose object, without holding the entire result in the memory. This is not strictly necessary for the purpose of handling the output from jc/bigfile, but not having to hold everything in core by itself may be a plus.

Interested parties may want to measure the performance impact of the last three patches. The series deliberately ignores core.bigfileThreashold and let small and large blobs alike go through the streaming_write_entry() codepath, but it _might_ turn out that we would want to use the new code only for large-ish blobs.

Junio C Hamano (11):
  packed_object_info_detail(): do not return a string
  sha1_object_info_extended(): expose a bit more info
  sha1_object_info_extended(): hint about objects in delta-base cache
  unpack_object_header(): make it public
  write_entry(): separate two helper functions out
  streaming: a new API to read from the object store
  streaming_write_entry(): use streaming API in write_entry()
  streaming_write_entry(): support files with holes
  streaming: read non-delta incrementally from a pack
  sha1_file.c: expose helpers to read loose objects
  streaming: read loose objects incrementally
 Makefile              |    2 +
 builtin/verify-pack.c |    4 +-
 cache.h               |   36 +++++-
 convert.c             |   23 +++
 entry.c               |  111 ++++++++++++---
 sha1_file.c           |   71 ++++++++--
 streaming.c           |  376 +++++++++++++++++++++++++++++++++++++++++++++++++
 streaming.h           |   12 ++
 8 files changed, 600 insertions(+), 35 deletions(-)
 create mode 100644 streaming.c
 create mode 100644 streaming.h
-- 
1.7.5.1.365.g32b65
Next: Junio C Hamano
Message 1 of 49 in “writing out a huge blob to working tree”
  1. 00/11 writing out a huge blob to working treeJunio C Hamano, May 16, 2011
  2. 01/11 packed_object_info_detail(): do not return a stringJunio C Hamano, May 16, 2011
  3. Thiago FarinaMay 17, 2011
  4. Junio C HamanoMay 17, 2011
  5. 02/11 sha1_object_info_extended(): expose a bit more infoJunio C Hamano, May 16, 2011
  6. 03/11 sha1_object_info_extended(): hint about objects in delta-base cacheJunio C Hamano, May 16, 2011
  7. Shawn PearceMay 16, 2011
  8. 04/11 unpack_object_header(): make it publicJunio C Hamano, May 16, 2011
  9. 05/11 write_entry(): separate two helper functions outJunio C Hamano, May 16, 2011
  10. 06/11 streaming: a new API to read from the object storeJunio C Hamano, May 16, 2011
  11. Jeff KingMay 18, 2011
  12. Junio C HamanoMay 19, 2011
  13. 07/11 streaming_write_entry(): use streaming API in write_entry()Junio C Hamano, May 16, 2011
  14. 08/11 streaming_write_entry(): support files with holesJunio C Hamano, May 16, 2011
  15. Nguyen Thai Ngoc DuyMay 16, 2011
  16. Junio C HamanoMay 16, 2011
  17. Nguyen Thai Ngoc DuyMay 17, 2011
  18. Junio C HamanoMay 17, 2011
  19. Thiago FarinaMay 16, 2011
  20. 09/11 streaming: read non-delta incrementally from a packJunio C Hamano, May 16, 2011
  21. Shawn PearceMay 16, 2011
  22. Junio C HamanoMay 16, 2011
  23. 10/11 sha1_file.c: expose helpers to read loose objectsJunio C Hamano, May 16, 2011
  24. 11/11 streaming: read loose objects incrementallyJunio C Hamano, May 16, 2011
  25. Shawn PearceMay 16, 2011
  26. Jeff KingMay 18, 2011
  27. Jeff KingMay 18, 2011
  28. Jeff KingMay 18, 2011
  29. Junio C HamanoMay 18, 2011
  30. Jeff KingMay 18, 2011
  31. 00/11 writing out a huge blob to working treeJunio C Hamano, May 19, 2011
  32. 01/11 packed_object_info_detail(): do not return a stringJunio C Hamano, May 19, 2011
  33. 02/11 sha1_object_info_extended(): expose a bit more infoJunio C Hamano, May 19, 2011
  34. 03/11 sha1_object_info_extended(): hint about objects in delta-base cacheJunio C Hamano, May 19, 2011
  35. René ScharfeMay 20, 2011
  36. Junio C HamanoMay 21, 2011
  37. 04/11 unpack_object_header(): make it publicJunio C Hamano, May 19, 2011
  38. 05/11 write_entry(): separate two helper functions outJunio C Hamano, May 19, 2011
  39. 06/11 streaming: a new API to read from the object storeJunio C Hamano, May 19, 2011
  40. René ScharfeMay 20, 2011
  41. Junio C HamanoMay 21, 2011
  42. 07/11 streaming_write_entry(): use streaming API in write_entry()Junio C Hamano, May 19, 2011
  43. Junio C HamanoMay 20, 2011
  44. 08/11 streaming_write_entry(): support files with holesJunio C Hamano, May 19, 2011
  45. 09/11 streaming: read non-delta incrementally from a packJunio C Hamano, May 19, 2011
  46. 10/11 sha1_file.c: expose helpers to read loose objectsJunio C Hamano, May 19, 2011
  47. 11/11 streaming: read loose objects incrementallyJunio C Hamano, May 19, 2011
  48. 02/11 interdiffJunio C Hamano, May 19, 2011
  49. Jeff KingMay 19, 2011

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.