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

Re: performance problem: "git commit filename"

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Jan 13, 2008, 01:46 UTC
Message-ID
<alpine.LFD.1.00.0801121735020.2806@woody.linux-foundation.org>
In-Reply-To
<alpine.LFD.1.00.0801121426510.2806@woody.linux-foundation.org>
On Sat, 12 Jan 2008, Linus Torvalds wrote:
> 
> I thought we had fixed this long long ago, but if we did, it has 
> re-surfaced.
It's new, and yes, it seems to be due to the new builtin-commit.c.
I think I know what is going on.
In the old git-commit.sh, this case used to be handled with
	TMP_INDEX="$GIT_DIR/tmp-index$$"
	GIT_INDEX_FILE="$THIS_INDEX" \
	git read-tree --index-output="$TMP_INDEX" -i -m HEAD

which is a one-way merge of the *old* index and HEAD, taking the index information from the old index, but the actual file information from HEAD (to then later be updated by the named files).

This logic is implemented by builtin-read-tree.c with
	struct unpack_trees_options opts;
	..
	opts.fn = oneway_merge;
	..
	unpack_trees(nr_trees, t, &opts);

where all the magic is done by that "oneway_merge()" function being called for each entry by unpack_trees(). This does everything right, and the result is that any index entry that was up-to-date in the old index and unchanged in the base tree will be up-to-date in the new index too

HOWEVER. When that logic was converted from that shell-script into a builtin-commit.c, that conversion was not done correctly. The old "git read-tree -i -m" was not translated as a "unpack_trees()" call, but as this in prepare_index():

	discard_cache()
	..
	tree = parse_tree_indirect(head_sha1);
	..
	read_tree(tree, 0, NULL)

which is very wrong, because it replaces the old index entirely, and doesn't do that stat information merging.

As a result, the index that is created by read-tree is totally bogus in the stat cache, and yes, everything will have to be re-computed.

Kristian?
			Linus
Previous: Linus TorvaldsNext: Linus Torvalds
Message 2 of 33 in “performance problem: "git commit filename"”
  1. Linus TorvaldsJan 12, 2008
  2. Linus TorvaldsJan 13, 2008
  3. Linus TorvaldsJan 13, 2008
  4. Daniel BarkalowJan 13, 2008
  5. Junio C HamanoJan 13, 2008
  6. Linus TorvaldsJan 13, 2008
  7. Daniel BarkalowJan 13, 2008
  8. Junio C HamanoJan 13, 2008
  9. Junio C HamanoJan 13, 2008
  10. builtin-commit.c: do not lstat(2) partially committed paths twice.Junio C Hamano, Jan 13, 2008
  11. Junio C HamanoJan 13, 2008
  12. Linus TorvaldsJan 13, 2008
  13. Junio C HamanoJan 13, 2008
  14. index: be careful when handling long namesJunio C Hamano, Jan 13, 2008
  15. Alex RiesenJan 13, 2008
  16. Junio C HamanoJan 13, 2008
  17. Alex RiesenJan 13, 2008
  18. Junio C HamanoJan 14, 2008
  19. Junio C HamanoJan 14, 2008
  20. Linus TorvaldsJan 14, 2008
  21. Junio C HamanoJan 14, 2008
  22. Linus TorvaldsJan 14, 2008
  23. Junio C HamanoJan 14, 2008
  24. Linus TorvaldsJan 14, 2008
  25. Linus TorvaldsJan 15, 2008
  26. Junio C HamanoJan 15, 2008
  27. builtin-commit.c: remove useless check added by faulty cut and pasteJunio C Hamano, Jan 13, 2008
  28. しらいしななこJan 14, 2008
  29. Junio C HamanoJan 14, 2008
  30. Kristian HøgsbergJan 14, 2008
  31. Kristian HøgsbergJan 14, 2008
  32. Junio C HamanoJan 14, 2008
  33. Linus TorvaldsJan 14, 2008

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.