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

Re: [PATCH 3/3] grep: recurse in-process using 'struct repository'

From
BWBrandon Williams <bmwill@google.com>
Date
Jul 12, 2017, 18:49 UTC
Message-ID
<20170712184939.GF65927@google.com>
In-Reply-To
<20170712002533.GD93855@aiede.mtv.corp.google.com>
On 07/11, Jonathan Nieder wrote:
Show 63 quoted lines
> Hi,
> 
> Brandon Williams wrote:
> 
> > Convert grep to use 'struct repository' which enables recursing into
> > submodules to be handled in-process.
> 
> \o/
> 
> This will be even nicer with the changes described at
> https://public-inbox.org/git/20170706202739.6056-1-sbeller@google.com/.
> Until then, I fear it will cause a regression --- see (*) below.
> 
> [...]
> >  Documentation/git-grep.txt |   7 -
> >  builtin/grep.c             | 390 +++++++++------------------------------------
> >  cache.h                    |   1 -
> >  git.c                      |   2 +-
> >  grep.c                     |  13 --
> >  grep.h                     |   1 -
> >  setup.c                    |  12 +-
> >  7 files changed, 81 insertions(+), 345 deletions(-)
> 
> Yay, tests still pass.
> 
> [..]
> > --- a/Documentation/git-grep.txt
> > +++ b/Documentation/git-grep.txt
> > @@ -95,13 +95,6 @@ OPTIONS
> >  	<tree> option the prefix of all submodule output will be the name of
> >  	the parent project's <tree> object.
> >  
> > ---parent-basename <basename>::
> > -	For internal use only.  In order to produce uniform output with the
> > -	--recurse-submodules option, this option can be used to provide the
> > -	basename of a parent's <tree> object to a submodule so the submodule
> > -	can prefix its output with the parent's name rather than the SHA1 of
> > -	the submodule.
> 
> Being able to get rid of this is a very nice change.
> 
> [...]
> > +++ b/builtin/grep.c
> [...]
> > @@ -366,14 +349,10 @@ static int grep_file(struct grep_opt *opt, const char *filename)
> >  {
> >  	struct strbuf buf = STRBUF_INIT;
> >  
> > -	if (super_prefix)
> > -		strbuf_addstr(&buf, super_prefix);
> > -	strbuf_addstr(&buf, filename);
> > -
> >  	if (opt->relative && opt->prefix_length) {
> > -		char *name = strbuf_detach(&buf, NULL);
> > -		quote_path_relative(name, opt->prefix, &buf);
> > -		free(name);
> > +		quote_path_relative(filename, opt->prefix, &buf);
> > +	} else {
> > +		strbuf_addstr(&buf, filename);
> >  	}
> 
> style micronit: can avoid these braces since both branches are
> single-line.

Didn't realize that with all the deleted lines, I'll fix for the next version.

Show 50 quoted lines
> 
> [...]
> > @@ -421,284 +400,80 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
> >  		exit(status);
> >  }
> >  
> > -static void compile_submodule_options(const struct grep_opt *opt,
> > -				      const char **argv,
> > -				      int cached, int untracked,
> > -				      int opt_exclude, int use_index,
> > -				      int pattern_type_arg)
> > -{
> [...]
> > -	/*
> > -	 * Limit number of threads for child process to use.
> > -	 * This is to prevent potential fork-bomb behavior of git-grep as each
> > -	 * submodule process has its own thread pool.
> > -	 */
> > -	argv_array_pushf(&submodule_options, "--threads=%d",
> > -			 (num_threads + 1) / 2);
> 
> Being able to get rid of this is another very nice change.
> 
> [...]
> > +	/* add objects to alternates */
> > +	add_to_alternates_memory(submodule.objectdir);
> 
> (*) This sets up a single in-memory object store with all the
> processed submodules.  Processed objects are never freed.
> This means that if I run a command like
> 
> 	git grep --recurse-submodules -e neverfound HEAD
> 
> in a project with many submodules then memory consumption scales in
> the same way as if the project were all one repository.  By contrast,
> without this patch, git is able to take advantage of the implicit
> free() when each child exits to limit its memory usage.
> 
> Worse, this increases the number of pack files git has to pay
> attention to the sum of the numbers of pack files in all the
> repositories processed so far.  A single object lookup can take
> O(number of packs * log(number of objects in each pack)) time.  That
> means performance is likely to suffer as the number of submodules
> increases (n^2 performance) even on systems with a lot of memory.
> 
> Once the object store is part of the repository struct and freeable,
> those problems go away and this patch becomes a no-brainer.
> 
> What should happen until then?  Should this go in "next" so we can get
> experience with it but with care not to let it graduate to "master"?

I agree that this is an issue and that we need to address by having an object store per repository. While that is being worked on (by Stefan) I don't know how long it would take to have it be a reality. So the question ends up being do we care more about the state of the code and cleaning up a lot of 'hacks' that I introduced to get grep working with submodules, or do we care about the performance more. I don't know which is the right answer but I'd personally like to see the hacks I added to be removed sooner rather than later. That and I think that with the code in this sate it would make it easier to transition once we have per-repository object-stores.

Either way I should add a NEEDSWORK comment here to indicate that it should be removed once per-repo object-stores exist.

Show 7 quoted lines
> 
> Aside from those two concerns, this patch looks very good from a quick
> skim, though I haven't reviewed it closely line-by-line.  Once we know
> how to go forward, I'm happy to look at it again.
> 
> Thanks,
> Jonathan
-- 
Brandon Williams
Previous: Jonathan NiederNext: Jeff King
Message 23 of 68 in “Convert grep to recurse in-process”
  1. 0/3 Convert grep to recurse in-processBrandon Williams, Jul 11, 2017
  2. 1/3 repo_read_index: don't discard the indexBrandon Williams, Jul 11, 2017
  3. Jonathan NiederJul 11, 2017
  4. Brandon WilliamsJul 12, 2017
  5. Stefan BellerJul 11, 2017
  6. Brandon WilliamsJul 12, 2017
  7. 2/3 setup: have the_repository use the_indexBrandon Williams, Jul 11, 2017
  8. Jonathan NiederJul 12, 2017
  9. Stefan BellerJul 12, 2017
  10. Brandon WilliamsJul 12, 2017
  11. Junio C HamanoJul 12, 2017
  12. Brandon WilliamsJul 12, 2017
  13. Junio C HamanoJul 12, 2017
  14. Jonathan NiederJul 12, 2017
  15. Junio C HamanoJul 12, 2017
  16. Junio C HamanoJul 18, 2017
  17. 3/3 grep: recurse in-process using 'struct repository'Brandon Williams, Jul 11, 2017
  18. Jacob KellerJul 11, 2017
  19. Brandon WilliamsJul 12, 2017
  20. Stefan BellerJul 12, 2017
  21. Brandon WilliamsJul 12, 2017
  22. Jonathan NiederJul 12, 2017
  23. Brandon WilliamsJul 12, 2017
  24. Jeff KingJul 12, 2017
  25. Brandon WilliamsJul 12, 2017
  26. Jeff KingJul 12, 2017
  27. Jonathan NiederJul 12, 2017
  28. Jeff KingJul 12, 2017
  29. Jonathan NiederJul 12, 2017
  30. Stefan BellerJul 12, 2017
  31. Jeff KingJul 12, 2017
  32. 0/3 Convert grep to recurse in-processBrandon Williams, Jul 14, 2017
  33. 1/3 repo_read_index: don't discard the indexBrandon Williams, Jul 14, 2017
  34. 2/3 repository: have the_repository use the_indexBrandon Williams, Jul 14, 2017
  35. 3/3 grep: recurse in-process using 'struct repository'Brandon Williams, Jul 14, 2017
  36. 00/10 Convert grep to recurse in-processBrandon Williams, Jul 18, 2017
  37. 01/10 repo_read_index: don't discard the indexBrandon Williams, Jul 18, 2017
  38. 02/10 repository: have the_repository use the_indexBrandon Williams, Jul 18, 2017
  39. 04/10 config: add config_from_gitmodulesBrandon Williams, Jul 18, 2017
  40. 03/10 cache.h: add GITMODULES_FILE macroBrandon Williams, Jul 18, 2017
  41. convert any hard coded .gitmodules file string to the MACROStefan Beller, Jul 31, 2017
  42. Jeff HostetlerAug 1, 2017
  43. Stefan BellerAug 1, 2017
  44. Junio C HamanoAug 1, 2017
  45. Brandon WilliamsAug 2, 2017
  46. Brandon WilliamsAug 2, 2017
  47. 08/10 submodule: check for unmerged .gitmodules outside of config parsingBrandon Williams, Jul 18, 2017
  48. 09/10 submodule: merge repo_read_gitmodules and gitmodules_configBrandon Williams, Jul 18, 2017
  49. 10/10 grep: recurse in-process using 'struct repository'Brandon Williams, Jul 18, 2017
  50. 05/10 submodule: remove submodule.fetchjobs from submodule-config parsingBrandon Williams, Jul 18, 2017
  51. 06/10 submodule: remove fetch.recursesubmodules from submodule-config parsingBrandon Williams, Jul 18, 2017
  52. 07/10 submodule: check for unstaged .gitmodules outside of config parsingBrandon Williams, Jul 18, 2017
  53. Stefan BellerJul 31, 2017
  54. Brandon WilliamsAug 2, 2017
  55. Brandon WilliamsAug 2, 2017
  56. Junio C HamanoJul 18, 2017
  57. Brandon WilliamsJul 18, 2017
  58. 00/10 Convert grep to recurse in-processBrandon Williams, Aug 2, 2017
  59. 01/10 repo_read_index: don't discard the indexBrandon Williams, Aug 2, 2017
  60. 02/10 repository: have the_repository use the_indexBrandon Williams, Aug 2, 2017
  61. 04/10 config: add config_from_gitmodulesBrandon Williams, Aug 2, 2017
  62. 06/10 submodule: remove fetch.recursesubmodules from submodule-config parsingBrandon Williams, Aug 2, 2017
  63. 03/10 cache.h: add GITMODULES_FILE macroBrandon Williams, Aug 2, 2017
  64. 08/10 submodule: check for unmerged .gitmodules outside of config parsingBrandon Williams, Aug 2, 2017
  65. 09/10 submodule: merge repo_read_gitmodules and gitmodules_configBrandon Williams, Aug 2, 2017
  66. 10/10 grep: recurse in-process using 'struct repository'Brandon Williams, Aug 2, 2017
  67. 05/10 submodule: remove submodule.fetchjobs from submodule-config parsingBrandon Williams, Aug 2, 2017
  68. 07/10 submodule: check for unstaged .gitmodules outside of config parsingBrandon Williams, Aug 2, 2017

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.