* [RFC PATCH 0/3] grep: submodule support @ 2010-09-29 20:28 Chris Packham 2010-09-29 20:28 ` [RFC PATCH 1/3] add test for git grep --recursive Chris Packham ` (2 more replies) 0 siblings, 3 replies; 22+ messages in thread From: Chris Packham @ 2010-09-29 20:28 UTC (permalink / raw) To: Jens.Lehmann; +Cc: git This patch series is my initial attempt to add submodule awareness to git grep. It's also the first time I've played with the git C code so expect bugs. The patches are based off apply on Jens Lehmann's 'enhance_git_for_submodules' branch in git://github.com/jlehmann/git-submod-enhancements.git The first patch adds some basic tests for grep with submodules. There is probably some overlap with other grep tests so I'll have a more in-depth look at what is needed later. I have a problem with the tests that when I invoke 'git grep' using run_command I actually end up using the installed git which doesn't understand my new --submodule-prefix option. The 2nd patch just adds a --submodule-prefix option so that I can prepend some text to the output from the sub processes. The 3rd patch is the main implementation. Currently I rebuild a command line for the subprocess based on the opts structure and I make use of the modified argv[0] from the command. Neither of these are really optimal, it'd be much easier if I could just start my subprocess from cmd_grep (or even grep_cache). Any pointers to get me moving in this direction are welcome. Even if I retain the rebuilding of the command line I'd like to rebuild the pattern(s) instead of relying on the saved_argv[0]. Chris Packham (3): add test for git grep --recursive grep: prepare grep for submodules grep: add support for grepping in submodules ^ permalink raw reply [flat|nested] 22+ messages in thread
* [RFC PATCH 1/3] add test for git grep --recursive 2010-09-29 20:28 [RFC PATCH 0/3] grep: submodule support Chris Packham @ 2010-09-29 20:28 ` Chris Packham 2010-09-29 20:35 ` Ævar Arnfjörð Bjarmason 2010-09-29 20:28 ` [RFC PATCH 2/3] grep: prepare grep for submodules Chris Packham 2010-09-29 20:28 ` [RFC PATCH 3/3] grep: add support for grepping in submodules Chris Packham 2 siblings, 1 reply; 22+ messages in thread From: Chris Packham @ 2010-09-29 20:28 UTC (permalink / raw) To: Jens.Lehmann; +Cc: git, Chris Packham Signed-off-by: Chris Packham <judge.packham@gmail.com> --- t/t7820-grep-recursive.sh | 101 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) create mode 100644 t/t7820-grep-recursive.sh diff --git a/t/t7820-grep-recursive.sh b/t/t7820-grep-recursive.sh new file mode 100644 index 0000000..4bbd109 --- /dev/null +++ b/t/t7820-grep-recursive.sh @@ -0,0 +1,101 @@ +#!/bin/sh +# +# Copyright (c) 2010 Chris Packham +# + +test_description='git grep --recursive test + +This test checks the ability of git grep to search within submodules when told +to do so with the --recursive option' + +. ./test-lib.sh + +test_expect_success 'setup - initial commit' ' + printf "one two three\nfour five six\n" >t && + git add t && + git commit -m "initial commit" +' +submodurl=$TRASH_DIRECTORY + +test_expect_success 'setup submodules for test' ' + for mod in $(seq 1 5 | sed "s/.*/submodule&/"); do + git submodule add "$submodurl" $mod && + git submodule init $mod + done +' + +test_expect_success 'update data in each submodule' ' + for n in $(seq 1 5); do + (cd submodule$n && + sed -i "s/^four.*/& #$n/" t && + git commit -a -m"update") + done +' + +cat >expected <<EOF +t:four five six +EOF +test_expect_success 'non-recursive grep in base' ' + git grep "five" >actual && + test_cmp expected actual +' + +cat >expected <<EOF +foo/t:four five six +EOF +test_expect_success 'submodule-prefix option' ' + git grep --submodule-prefix=foo/ "five" >actual && + test_cmp expected actual +' + +cat >submodule1/expected <<EOF +t:four five six #1 +EOF +test_expect_success 'non-recursive grep in submodule' ' + ( + cd submodule1 && + git grep "five" >actual && + test_cmp expected actual + ) +' + +cat >expected <<EOF +t:four five six #1 +t:four five six #2 +t:four five six #3 +t:four five six #4 +t:four five six #5 +t:four five six +EOF +test_expect_success 'recursive grep' ' + git grep --recurse-submodules "five" >actual && + test_cmp expected actual +' + +cat >expected <<EOF +t:2:four five six #1 +t:2:four five six #2 +t:2:four five six #3 +t:2:four five six #4 +t:2:four five six #5 +t:2:four five six +EOF +test_expect_success 'recursive grep (with -n)' ' + git grep --recurse-submodules -n "five" >actual && + test_cmp expected actual +' + +cat >expected <<EOF +t +t +t +t +t +t +EOF +test_expect_success 'recursive grep (with -l)' ' + git grep --recurse-submodules -l "five" >actual && + test_cmp expected actual +' + +test_done -- 1.7.3.dirty ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 1/3] add test for git grep --recursive 2010-09-29 20:28 ` [RFC PATCH 1/3] add test for git grep --recursive Chris Packham @ 2010-09-29 20:35 ` Ævar Arnfjörð Bjarmason 2010-09-29 20:48 ` Chris Packham 2010-09-29 21:34 ` Kevin Ballard 0 siblings, 2 replies; 22+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2010-09-29 20:35 UTC (permalink / raw) To: Chris Packham; +Cc: Jens.Lehmann, git On Wed, Sep 29, 2010 at 20:28, Chris Packham <judge.packham@gmail.com> wrote: > Signed-off-by: Chris Packham <judge.packham@gmail.com> > --- > t/t7820-grep-recursive.sh | 101 +++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 101 insertions(+), 0 deletions(-) > create mode 100644 t/t7820-grep-recursive.sh > > diff --git a/t/t7820-grep-recursive.sh b/t/t7820-grep-recursive.sh > new file mode 100644 > index 0000000..4bbd109 > --- /dev/null > +++ b/t/t7820-grep-recursive.sh > @@ -0,0 +1,101 @@ > +#!/bin/sh > +# > +# Copyright (c) 2010 Chris Packham > +# > + > +test_description='git grep --recursive test > + > +This test checks the ability of git grep to search within submodules when told > +to do so with the --recursive option' > + > +. ./test-lib.sh > + > +test_expect_success 'setup - initial commit' ' > + printf "one two three\nfour five six\n" >t && > + git add t && > + git commit -m "initial commit" > +' > +submodurl=$TRASH_DIRECTORY > + > +test_expect_success 'setup submodules for test' ' > + for mod in $(seq 1 5 | sed "s/.*/submodule&/"); do > + git submodule add "$submodurl" $mod && > + git submodule init $mod > + done > +' > + > +test_expect_success 'update data in each submodule' ' > + for n in $(seq 1 5); do seq isn't portable to windows, so we usually write out "1 2 3 4 5" directly. > + (cd submodule$n && > + sed -i "s/^four.*/& #$n/" t && > + git commit -a -m"update") > + done > +' > + > +cat >expected <<EOF > +t:four five six > +EOF > +test_expect_success 'non-recursive grep in base' ' > + git grep "five" >actual && > + test_cmp expected actual > +' Put the "cat >expected <<EOF" inside the test: test_expect_success 'non-recursive grep in base' ' cat >expected <<\EOF && t:four five six EOF git grep "five" >actual && test_cmp expected actual ' ditto for the rest. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 1/3] add test for git grep --recursive 2010-09-29 20:35 ` Ævar Arnfjörð Bjarmason @ 2010-09-29 20:48 ` Chris Packham 2010-09-29 21:34 ` Kevin Ballard 1 sibling, 0 replies; 22+ messages in thread From: Chris Packham @ 2010-09-29 20:48 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason; +Cc: Jens.Lehmann, git On 29/09/10 13:35, Ævar Arnfjörð Bjarmason wrote: > On Wed, Sep 29, 2010 at 20:28, Chris Packham <judge.packham@gmail.com> wrote: >> Signed-off-by: Chris Packham <judge.packham@gmail.com> >> --- >> t/t7820-grep-recursive.sh | 101 +++++++++++++++++++++++++++++++++++++++++++++ >> 1 files changed, 101 insertions(+), 0 deletions(-) >> create mode 100644 t/t7820-grep-recursive.sh >> >> diff --git a/t/t7820-grep-recursive.sh b/t/t7820-grep-recursive.sh >> new file mode 100644 >> index 0000000..4bbd109 >> --- /dev/null >> +++ b/t/t7820-grep-recursive.sh >> @@ -0,0 +1,101 @@ >> +#!/bin/sh >> +# >> +# Copyright (c) 2010 Chris Packham >> +# >> + >> +test_description='git grep --recursive test >> + >> +This test checks the ability of git grep to search within submodules when told >> +to do so with the --recursive option' >> + >> +. ./test-lib.sh >> + >> +test_expect_success 'setup - initial commit' ' >> + printf "one two three\nfour five six\n" >t && >> + git add t && >> + git commit -m "initial commit" >> +' >> +submodurl=$TRASH_DIRECTORY >> + >> +test_expect_success 'setup submodules for test' ' >> + for mod in $(seq 1 5 | sed "s/.*/submodule&/"); do >> + git submodule add "$submodurl" $mod && >> + git submodule init $mod >> + done >> +' >> + >> +test_expect_success 'update data in each submodule' ' >> + for n in $(seq 1 5); do > > seq isn't portable to windows, so we usually write out "1 2 3 4 5" > directly. > >> + (cd submodule$n && >> + sed -i "s/^four.*/& #$n/" t && >> + git commit -a -m"update") >> + done >> +' >> + >> +cat >expected <<EOF >> +t:four five six >> +EOF >> +test_expect_success 'non-recursive grep in base' ' >> + git grep "five" >actual && >> + test_cmp expected actual >> +' > > Put the "cat >expected <<EOF" inside the test: > > test_expect_success 'non-recursive grep in base' ' > cat >expected <<\EOF && > t:four five six > EOF > git grep "five" >actual && > test_cmp expected actual > ' > > ditto for the rest. Thanks for the review, will be in next re-roll. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 1/3] add test for git grep --recursive 2010-09-29 20:35 ` Ævar Arnfjörð Bjarmason 2010-09-29 20:48 ` Chris Packham @ 2010-09-29 21:34 ` Kevin Ballard 1 sibling, 0 replies; 22+ messages in thread From: Kevin Ballard @ 2010-09-29 21:34 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason; +Cc: Chris Packham, Jens.Lehmann, git On Sep 29, 2010, at 1:35 PM, Ævar Arnfjörð Bjarmason wrote: >> +test_expect_success 'update data in each submodule' ' >> + for n in $(seq 1 5); do > > seq isn't portable to windows, so we usually write out "1 2 3 4 5" > directly. FWIW, seq isn't even provided by default on OS X. -Kevin Ballard ^ permalink raw reply [flat|nested] 22+ messages in thread
* [RFC PATCH 2/3] grep: prepare grep for submodules 2010-09-29 20:28 [RFC PATCH 0/3] grep: submodule support Chris Packham 2010-09-29 20:28 ` [RFC PATCH 1/3] add test for git grep --recursive Chris Packham @ 2010-09-29 20:28 ` Chris Packham 2010-09-30 1:10 ` Nguyen Thai Ngoc Duy 2010-09-29 20:28 ` [RFC PATCH 3/3] grep: add support for grepping in submodules Chris Packham 2 siblings, 1 reply; 22+ messages in thread From: Chris Packham @ 2010-09-29 20:28 UTC (permalink / raw) To: Jens.Lehmann; +Cc: git, Chris Packham Add --submodule-prefix option to pass to subprocess grep invocations. The prefix is then used when outputting the results. Signed-off-by: Chris Packham <judge.packham@gmail.com> --- builtin/grep.c | 2 ++ grep.c | 8 ++++++++ grep.h | 1 + 3 files changed, 11 insertions(+), 0 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index da32f3d..8315ff0 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -927,6 +927,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) "allow calling of grep(1) (ignored by this build)"), { OPTION_CALLBACK, 0, "help-all", &options, NULL, "show usage", PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback }, + OPT_STRING(0, "submodule-prefix", &opt.submodule_prefix, "DIR", + "prepend this to submodule path output"), OPT_END() }; diff --git a/grep.c b/grep.c index 63c4280..36bec98 100644 --- a/grep.c +++ b/grep.c @@ -370,6 +370,10 @@ static void output_sep(struct grep_opt *opt, char sign) static void show_name(struct grep_opt *opt, const char *name) { + if (opt->submodule_prefix) { + output_color(opt, opt->submodule_prefix, + strlen(opt->submodule_prefix), opt->color_filename); + } output_color(opt, name, strlen(name), opt->color_filename); opt->output(opt, opt->null_following_name ? "\0" : "\n", 1); } @@ -644,6 +648,10 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol, } opt->last_shown = lno; + if (opt->submodule_prefix) { + output_color(opt, opt->submodule_prefix, + strlen(opt->submodule_prefix), opt->color_filename); + } if (opt->pathname) { output_color(opt, name, strlen(name), opt->color_filename); output_sep(opt, sign); diff --git a/grep.h b/grep.h index 06621fe..d918da4 100644 --- a/grep.h +++ b/grep.h @@ -67,6 +67,7 @@ struct grep_opt { struct grep_expr *pattern_expression; const char *prefix; int prefix_length; + const char *submodule_prefix; regex_t regexp; int linenum; int invert; -- 1.7.3.dirty ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 2/3] grep: prepare grep for submodules 2010-09-29 20:28 ` [RFC PATCH 2/3] grep: prepare grep for submodules Chris Packham @ 2010-09-30 1:10 ` Nguyen Thai Ngoc Duy 2010-09-30 18:34 ` Chris Packham 0 siblings, 1 reply; 22+ messages in thread From: Nguyen Thai Ngoc Duy @ 2010-09-30 1:10 UTC (permalink / raw) To: Chris Packham; +Cc: Jens.Lehmann, git On Thu, Sep 30, 2010 at 6:28 AM, Chris Packham <judge.packham@gmail.com> wrote: > Add --submodule-prefix option to pass to subprocess grep invocations. The > prefix is then used when outputting the results. I haven't followed the recursive submodule support in Git lately. But I think --submodule-prefix is unnecessary. I would imagine you need to add --submodule-prefix to a lot more commands as they support recusive submodule search. There is a corner case in Git's prefix setup that we can utilize to avoid the new option. If you do this at the superproject repo: $ GIT_DIR=path/to/submodule/.git GIT_WORK_TREE=path/to/submodule git grep blah I would expect that it shows the result correctly (i.e. all files prefixed by "path/to/submodule"), but it does not right now. If you make that setup work, then you don't need --submodule-prefix, just set GIT_DIR/GIT_WORK_TREE properly and run "git grep". You can make setup_explicit_git_dir() realize that situation (current working directory outside $GIT_WORK_TREE), then calculate and save the submodule prefix in startup_info struct. Then "git grep" or any commands can just read startup_info to find out the submodule prefix. -- Duy ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 2/3] grep: prepare grep for submodules 2010-09-30 1:10 ` Nguyen Thai Ngoc Duy @ 2010-09-30 18:34 ` Chris Packham 2010-10-01 14:37 ` Nguyen Thai Ngoc Duy 0 siblings, 1 reply; 22+ messages in thread From: Chris Packham @ 2010-09-30 18:34 UTC (permalink / raw) To: Nguyen Thai Ngoc Duy; +Cc: Jens.Lehmann, git On 29/09/10 18:10, Nguyen Thai Ngoc Duy wrote: > On Thu, Sep 30, 2010 at 6:28 AM, Chris Packham <judge.packham@gmail.com> wrote: >> Add --submodule-prefix option to pass to subprocess grep invocations. The >> prefix is then used when outputting the results. > > I haven't followed the recursive submodule support in Git lately. But > I think --submodule-prefix is unnecessary. I would imagine you need to > add --submodule-prefix to a lot more commands as they support recusive > submodule search. There is a corner case in Git's prefix setup that we > can utilize to avoid the new option. > > If you do this at the superproject repo: > > $ GIT_DIR=path/to/submodule/.git GIT_WORK_TREE=path/to/submodule git grep blah > > I would expect that it shows the result correctly (i.e. all files > prefixed by "path/to/submodule"), but it does not right now. If you > make that setup work, then you don't need --submodule-prefix, just set > GIT_DIR/GIT_WORK_TREE properly and run "git grep". > > You can make setup_explicit_git_dir() realize that situation (current > working directory outside $GIT_WORK_TREE), then calculate and save the > submodule prefix in startup_info struct. Then "git grep" or any > commands can just read startup_info to find out the submodule prefix. Here's my first naive attempt at implementing what you describe. Needs tests, more comments, sign-off etc. One situation that could be handled better is when the cwd is a subdirectory of the specified worktree. At the moment this ends up giving the full path to the worktree, the output would look much nicer if it gave the relative path (e.g. ../../). ---8<--- From: Chris Packham <judge.packham@gmail.com> Date: Thu, 30 Sep 2010 11:19:29 -0700 Subject: [RFC PATCH] save the work tree prefix in startup_info This is the relative path between the cwd and the worktree or the absolute path of the worktree if the worktree is not a subdirectory of the worktree. --- cache.h | 1 + dir.c | 26 ++++++++++++++++++++++++++ dir.h | 1 + setup.c | 4 ++++ 4 files changed, 32 insertions(+), 0 deletions(-) diff --git a/cache.h b/cache.h index e1d3ffd..f320e78 100644 --- a/cache.h +++ b/cache.h @@ -1111,6 +1111,7 @@ const char *split_cmdline_strerror(int cmdline_errno); /* git.c */ struct startup_info { int have_repository; + const char *prefix; }; extern struct startup_info *startup_info; diff --git a/dir.c b/dir.c index 58ec1a1..2148730 100644 --- a/dir.c +++ b/dir.c @@ -1036,6 +1036,32 @@ char *get_relative_cwd(char *buffer, int size, const char *dir) } } +char *get_relative_wt(char *buffer, int size, const char *dir) +{ + char *cwd = buffer; + + if (!dir) + return NULL; + if (!getcwd(buffer, size)) + die_errno("can't find the current directory"); + if (!is_absolute_path(dir)) + dir = make_absolute_path(dir); + if (strstr(dir, cwd)) { + dir += strlen(cwd); + switch(*dir){ + case '\0': + return NULL; + case '/': + dir++; + break; + default: + break; + } + } + strncpy(buffer, dir, size); + return buffer; +} + int is_inside_dir(const char *dir) { char buffer[PATH_MAX]; diff --git a/dir.h b/dir.h index b3e2104..d3c161f 100644 --- a/dir.h +++ b/dir.h @@ -81,6 +81,7 @@ extern void add_exclude(const char *string, const char *base, extern int file_exists(const char *); extern char *get_relative_cwd(char *buffer, int size, const char *dir); +extern char *get_relative_wt(char *buffer, int size, const char *dir); extern int is_inside_dir(const char *dir); static inline int is_dot_or_dotdot(const char *name) diff --git a/setup.c b/setup.c index a3b76de..bd9d9fd 100644 --- a/setup.c +++ b/setup.c @@ -317,6 +317,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, const char *work_tree_env, int *nongit_ok) { static char buffer[1024 + 1]; + static char wtbuf[1024 + 1]; const char *retval; if (PATH_MAX - 40 < strlen(gitdirenv)) @@ -337,6 +338,9 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, } if (check_repository_format_gently(nongit_ok)) return NULL; + + startup_info->prefix=get_relative_wt(wtbuf, sizeof(wtbuf) - 1, + get_git_work_tree()); retval = get_relative_cwd(buffer, sizeof(buffer) - 1, get_git_work_tree()); if (!retval || !*retval) -- 1.7.3.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 2/3] grep: prepare grep for submodules 2010-09-30 18:34 ` Chris Packham @ 2010-10-01 14:37 ` Nguyen Thai Ngoc Duy 2010-10-01 16:26 ` Chris Packham 0 siblings, 1 reply; 22+ messages in thread From: Nguyen Thai Ngoc Duy @ 2010-10-01 14:37 UTC (permalink / raw) To: Chris Packham; +Cc: Jens.Lehmann, git On 10/1/10, Chris Packham <judge.packham@gmail.com> wrote: > > You can make setup_explicit_git_dir() realize that situation (current > > working directory outside $GIT_WORK_TREE), then calculate and save the > > submodule prefix in startup_info struct. Then "git grep" or any > > commands can just read startup_info to find out the submodule prefix. > > > Here's my first naive attempt at implementing what you describe. Needs > tests, more comments, sign-off etc. Thanks. > One situation that could be handled better is when the cwd is a > subdirectory of the specified worktree. At the moment this ends up > giving the full path to the worktree, the output would look much nicer > if it gave the relative path (e.g. ../../). Hmm.. if cwd is inside a worktree, prefix (the 3rd parameter in cmd_grep) should be correctly set and "git grep" should also show relative path. Or are you talking about another command? > > ---8<--- > From: Chris Packham <judge.packham@gmail.com> > Date: Thu, 30 Sep 2010 11:19:29 -0700 > Subject: [RFC PATCH] save the work tree prefix in startup_info > > This is the relative path between the cwd and the worktree or the > absolute path of the worktree if the worktree is not a subdirectory > of the worktree. > --- > cache.h | 1 + > dir.c | 26 ++++++++++++++++++++++++++ > dir.h | 1 + > setup.c | 4 ++++ > 4 files changed, 32 insertions(+), 0 deletions(-) > > diff --git a/cache.h b/cache.h > index e1d3ffd..f320e78 100644 > --- a/cache.h > +++ b/cache.h > @@ -1111,6 +1111,7 @@ const char *split_cmdline_strerror(int cmdline_errno); > /* git.c */ > struct startup_info { > int have_repository; > + const char *prefix; You should use another name here to avoid confusion with the current prefix, relative to worktree toplevel directory. I'm thinking of outer_prefix or cwd_prefix, but I'm usually bad at naming. > }; > extern struct startup_info *startup_info; > > diff --git a/dir.c b/dir.c > index 58ec1a1..2148730 100644 > --- a/dir.c > +++ b/dir.c > @@ -1036,6 +1036,32 @@ char *get_relative_cwd(char *buffer, int size, > const char *dir) > } > } > > +char *get_relative_wt(char *buffer, int size, const char *dir) > +{ > + char *cwd = buffer; > + > + if (!dir) > + return NULL; > + if (!getcwd(buffer, size)) > + die_errno("can't find the current directory"); > + if (!is_absolute_path(dir)) > + dir = make_absolute_path(dir); > + if (strstr(dir, cwd)) { Why not strncmp? > + dir += strlen(cwd); > + switch(*dir){ > + case '\0': > + return NULL; > + case '/': > + dir++; > + break; Yeah. > + default: > + break; Should we properly handle relative path that includes ".." here too? > + } > + } > + strncpy(buffer, dir, size); So if "cwd" is inside "dir", an absolute "dir" is returned? That does not look like a prefix to me. > + return buffer; > +} > + > int is_inside_dir(const char *dir) > { > char buffer[PATH_MAX]; > diff --git a/dir.h b/dir.h > index b3e2104..d3c161f 100644 > --- a/dir.h > +++ b/dir.h > @@ -81,6 +81,7 @@ extern void add_exclude(const char *string, const char > *base, > extern int file_exists(const char *); > > extern char *get_relative_cwd(char *buffer, int size, const char *dir); > +extern char *get_relative_wt(char *buffer, int size, const char *dir); > extern int is_inside_dir(const char *dir); > > static inline int is_dot_or_dotdot(const char *name) > diff --git a/setup.c b/setup.c > index a3b76de..bd9d9fd 100644 > --- a/setup.c > +++ b/setup.c > @@ -317,6 +317,7 @@ static const char *setup_explicit_git_dir(const char > *gitdirenv, > const char *work_tree_env, int *nongit_ok) > { > static char buffer[1024 + 1]; > + static char wtbuf[1024 + 1]; > const char *retval; > > if (PATH_MAX - 40 < strlen(gitdirenv)) > @@ -337,6 +338,9 @@ static const char *setup_explicit_git_dir(const char > *gitdirenv, > } > if (check_repository_format_gently(nongit_ok)) > return NULL; > + > + startup_info->prefix=get_relative_wt(wtbuf, sizeof(wtbuf) - 1, > + get_git_work_tree()); > retval = get_relative_cwd(buffer, sizeof(buffer) - 1, > get_git_work_tree()); > if (!retval || !*retval) > > -- > 1.7.3.1 > > -- Duy ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 2/3] grep: prepare grep for submodules 2010-10-01 14:37 ` Nguyen Thai Ngoc Duy @ 2010-10-01 16:26 ` Chris Packham 0 siblings, 0 replies; 22+ messages in thread From: Chris Packham @ 2010-10-01 16:26 UTC (permalink / raw) To: Nguyen Thai Ngoc Duy; +Cc: Jens.Lehmann, git On 01/10/10 07:37, Nguyen Thai Ngoc Duy wrote: > On 10/1/10, Chris Packham <judge.packham@gmail.com> wrote: >> > You can make setup_explicit_git_dir() realize that situation (current >> > working directory outside $GIT_WORK_TREE), then calculate and save the >> > submodule prefix in startup_info struct. Then "git grep" or any >> > commands can just read startup_info to find out the submodule prefix. >> >> >> Here's my first naive attempt at implementing what you describe. Needs >> tests, more comments, sign-off etc. > > Thanks. > >> One situation that could be handled better is when the cwd is a >> subdirectory of the specified worktree. At the moment this ends up >> giving the full path to the worktree, the output would look much nicer >> if it gave the relative path (e.g. ../../). > > Hmm.. if cwd is inside a worktree, prefix (the 3rd parameter in > cmd_grep) should be correctly set and "git grep" should also show > relative path. Or are you talking about another command? I was testing this with grep but also with my submodule changes. I should probably move this to its own topic branch and get it working then rebase my grep changes on top of it. >> >> ---8<--- >> From: Chris Packham <judge.packham@gmail.com> >> Date: Thu, 30 Sep 2010 11:19:29 -0700 >> Subject: [RFC PATCH] save the work tree prefix in startup_info >> >> This is the relative path between the cwd and the worktree or the >> absolute path of the worktree if the worktree is not a subdirectory >> of the worktree. >> --- >> cache.h | 1 + >> dir.c | 26 ++++++++++++++++++++++++++ >> dir.h | 1 + >> setup.c | 4 ++++ >> 4 files changed, 32 insertions(+), 0 deletions(-) >> >> diff --git a/cache.h b/cache.h >> index e1d3ffd..f320e78 100644 >> --- a/cache.h >> +++ b/cache.h >> @@ -1111,6 +1111,7 @@ const char *split_cmdline_strerror(int cmdline_errno); >> /* git.c */ >> struct startup_info { >> int have_repository; >> + const char *prefix; > > You should use another name here to avoid confusion with the current > prefix, relative to worktree toplevel directory. I'm thinking of > outer_prefix or cwd_prefix, but I'm usually bad at naming. I couldn't come up with a better name either, that’s why I used "prefix". "cwd_prefix" seems sensible enough to me. >> }; >> extern struct startup_info *startup_info; >> >> diff --git a/dir.c b/dir.c >> index 58ec1a1..2148730 100644 >> --- a/dir.c >> +++ b/dir.c >> @@ -1036,6 +1036,32 @@ char *get_relative_cwd(char *buffer, int size, >> const char *dir) >> } >> } >> >> +char *get_relative_wt(char *buffer, int size, const char *dir) >> +{ >> + char *cwd = buffer; >> + >> + if (!dir) >> + return NULL; >> + if (!getcwd(buffer, size)) >> + die_errno("can't find the current directory"); >> + if (!is_absolute_path(dir)) >> + dir = make_absolute_path(dir); >> + if (strstr(dir, cwd)) { > > Why not strncmp? I actually tried strcmp first, expecting to get a number that I can increment dir by. What I actually got was -1, maybe I just screwed up the order of dir and cwd. I'll look into it. > >> + dir += strlen(cwd); >> + switch(*dir){ >> + case '\0': >> + return NULL; >> + case '/': >> + dir++; >> + break; > > Yeah. > >> + default: >> + break; > > Should we properly handle relative path that includes ".." here too? By now dir and cwd are both absolute paths. So I dn't think there is anything to handle >> + } >> + } >> + strncpy(buffer, dir, size); > > So if "cwd" is inside "dir", an absolute "dir" is returned? That does > not look like a prefix to me. That is a problem. Maybe I should be returning NULL in that case and let the existing code handle the cwd inside dir case. I think if I wrote some tests first I could see the various permutations better. >> + return buffer; >> +} >> + >> int is_inside_dir(const char *dir) >> { >> char buffer[PATH_MAX]; >> diff --git a/dir.h b/dir.h >> index b3e2104..d3c161f 100644 >> --- a/dir.h >> +++ b/dir.h >> @@ -81,6 +81,7 @@ extern void add_exclude(const char *string, const char >> *base, >> extern int file_exists(const char *); >> >> extern char *get_relative_cwd(char *buffer, int size, const char *dir); >> +extern char *get_relative_wt(char *buffer, int size, const char *dir); >> extern int is_inside_dir(const char *dir); >> >> static inline int is_dot_or_dotdot(const char *name) >> diff --git a/setup.c b/setup.c >> index a3b76de..bd9d9fd 100644 >> --- a/setup.c >> +++ b/setup.c >> @@ -317,6 +317,7 @@ static const char *setup_explicit_git_dir(const char >> *gitdirenv, >> const char *work_tree_env, int *nongit_ok) >> { >> static char buffer[1024 + 1]; >> + static char wtbuf[1024 + 1]; >> const char *retval; >> >> if (PATH_MAX - 40 < strlen(gitdirenv)) >> @@ -337,6 +338,9 @@ static const char *setup_explicit_git_dir(const char >> *gitdirenv, >> } >> if (check_repository_format_gently(nongit_ok)) >> return NULL; >> + >> + startup_info->prefix=get_relative_wt(wtbuf, sizeof(wtbuf) - 1, >> + get_git_work_tree()); >> retval = get_relative_cwd(buffer, sizeof(buffer) - 1, >> get_git_work_tree()); >> if (!retval || !*retval) >> >> -- >> 1.7.3.1 >> >> > > ^ permalink raw reply [flat|nested] 22+ messages in thread
* [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 20:28 [RFC PATCH 0/3] grep: submodule support Chris Packham 2010-09-29 20:28 ` [RFC PATCH 1/3] add test for git grep --recursive Chris Packham 2010-09-29 20:28 ` [RFC PATCH 2/3] grep: prepare grep for submodules Chris Packham @ 2010-09-29 20:28 ` Chris Packham 2010-09-29 22:21 ` Jens Lehmann 2 siblings, 1 reply; 22+ messages in thread From: Chris Packham @ 2010-09-29 20:28 UTC (permalink / raw) To: Jens.Lehmann; +Cc: git, Chris Packham When the --recurse-submodules option is given git grep will search in submodules as they are encountered. Signed-off-by: Chris Packham <judge.packham@gmail.com> --- builtin/grep.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ grep.h | 1 + 2 files changed, 73 insertions(+), 0 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index 8315ff0..c9befdc 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -30,6 +30,9 @@ static char const * const grep_usage[] = { static int use_threads = 1; +static int saved_argc; +static const char **saved_argv; + #ifndef NO_PTHREADS #define THREADS 8 static pthread_t threads[THREADS]; @@ -585,6 +588,67 @@ static void run_pager(struct grep_opt *opt, const char *prefix) free(argv); } +static const char **create_sub_grep_argv(struct grep_opt *opt, const char *path) +{ + #define NUM_ARGS 10 + struct strbuf buf = STRBUF_INIT; + const char **argv; + int i = 0; + + argv = xcalloc(NUM_ARGS, sizeof(const char *)); + argv[i++] = "grep"; + strbuf_addf(&buf, "--submodule-prefix=\\\"%s\\\"", path); + //argv[i++] = buf.buf; + + if (opt->linenum) + argv[i++] = "-n"; + if (opt->invert) + argv[i++] = "-v"; + if (opt->ignore_case) + argv[i++] = "-i"; + if (opt->count) + argv[i++] = "-c"; + if (opt->name_only) + argv[i++] = "-l"; + + argv[i++] = saved_argv[0]; + argv[i++] = NULL; + + strbuf_release(&buf); + return argv; +} + +static int grep_submodule(struct grep_opt *opt, const char *path) +{ + struct strbuf buf = STRBUF_INIT; + struct child_process cp; + const char **argv = create_sub_grep_argv(opt, path); + const char *git_dir; + int hit = 0; + + strbuf_addf(&buf, "%s/.git", path); + git_dir = read_gitfile_gently(buf.buf); + if (!git_dir) + git_dir = buf.buf; + if (!is_directory(git_dir)) { + warning("submodule %s has not been initialized\n", path); + goto out_free; + } + + memset(&cp, 0, sizeof(cp)); + cp.argv = argv; + cp.env = local_repo_env; + cp.git_cmd = 1; + cp.no_stdin = 1; + cp.dir = path; + if (run_command(&cp) == 0) + hit = 1; +out_free: + free(argv); + strbuf_release(&buf); + return hit; +} + static int grep_cache(struct grep_opt *opt, const char **paths, int cached) { int hit = 0; @@ -593,6 +657,10 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached) for (nr = 0; nr < active_nr; nr++) { struct cache_entry *ce = active_cache[nr]; + if (S_ISGITLINK(ce->ce_mode) && opt->recurse_submodules) { + hit |= grep_submodule(opt, ce->name); + continue; + } if (!S_ISREG(ce->ce_mode)) continue; if (!pathspec_matches(paths, ce->name, opt->max_depth)) @@ -929,9 +997,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix) PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback }, OPT_STRING(0, "submodule-prefix", &opt.submodule_prefix, "DIR", "prepend this to submodule path output"), + OPT_BOOLEAN(0, "recurse-submodules", &opt.recurse_submodules, + "recurse into submodules"), OPT_END() }; + saved_argc = argc; + saved_argv = argv; /* * 'git grep -h', unlike 'git grep -h <pattern>', is a request * to show usage information and exit. diff --git a/grep.h b/grep.h index d918da4..e3199c9 100644 --- a/grep.h +++ b/grep.h @@ -102,6 +102,7 @@ struct grep_opt { unsigned post_context; unsigned last_shown; int show_hunk_mark; + int recurse_submodules; void *priv; void (*output)(struct grep_opt *opt, const void *data, size_t size); -- 1.7.3.dirty ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 20:28 ` [RFC PATCH 3/3] grep: add support for grepping in submodules Chris Packham @ 2010-09-29 22:21 ` Jens Lehmann 2010-09-29 22:59 ` Junio C Hamano 2010-09-29 23:02 ` Chris Packham 0 siblings, 2 replies; 22+ messages in thread From: Jens Lehmann @ 2010-09-29 22:21 UTC (permalink / raw) To: Chris Packham; +Cc: git Nice start! Am 29.09.2010 22:28, schrieb Chris Packham: > When the --recurse-submodules option is given git grep will search in > submodules as they are encountered. As "git clone" already introduced a "--recursive" option for submodule recursion IMO "--recursive" should be used here too for consistency. (Maybe you took the idea to use "--recurse-submodules" from my "git-checkout-recurse-submodules" branch on github? But that is only used there because I didn't get around to change it yet like I did in the "fetch-submodules-too" branch). > Signed-off-by: Chris Packham <judge.packham@gmail.com> > --- > builtin/grep.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > grep.h | 1 + > 2 files changed, 73 insertions(+), 0 deletions(-) > > diff --git a/builtin/grep.c b/builtin/grep.c > index 8315ff0..c9befdc 100644 > --- a/builtin/grep.c > +++ b/builtin/grep.c > @@ -30,6 +30,9 @@ static char const * const grep_usage[] = { > > static int use_threads = 1; > > +static int saved_argc; > +static const char **saved_argv; > + > #ifndef NO_PTHREADS > #define THREADS 8 > static pthread_t threads[THREADS]; > @@ -585,6 +588,67 @@ static void run_pager(struct grep_opt *opt, const char *prefix) > free(argv); > } > > +static const char **create_sub_grep_argv(struct grep_opt *opt, const char *path) > +{ > + #define NUM_ARGS 10 > + struct strbuf buf = STRBUF_INIT; > + const char **argv; > + int i = 0; > + > + argv = xcalloc(NUM_ARGS, sizeof(const char *)); > + argv[i++] = "grep"; > + strbuf_addf(&buf, "--submodule-prefix=\\\"%s\\\"", path); > + //argv[i++] = buf.buf; As C++ comments are not portable they have to be avoided, but I assume this one here (and the unused "saved_argc" variable too) is a hint that this code is not working as intended yet? ;-) It seems you want to use strbuf_detach() here so that this argv[] stays valid after the strbuf_release() at the end of this function. And if I'm not missing something this would not work correctly in the second recursion depth, as the new submodule prefix should be the one given to this grep command concatenated with the current submodule path. > + if (opt->linenum) > + argv[i++] = "-n"; > + if (opt->invert) > + argv[i++] = "-v"; > + if (opt->ignore_case) > + argv[i++] = "-i"; > + if (opt->count) > + argv[i++] = "-c"; > + if (opt->name_only) > + argv[i++] = "-l"; > + > + argv[i++] = saved_argv[0]; > + argv[i++] = NULL; Hm, at a quick glance it might be much easier to copy argc & argv in cmd_grep() before parse_options() starts manipulating it. Then you would only have to change/add the "--submodule-prefix" option as needed and would not have to deal with all possible grep option combinations (and for example you don't pass the recurse option yet, which would stop the recursion pretty soon). > + > + strbuf_release(&buf); > + return argv; > +} > + > +static int grep_submodule(struct grep_opt *opt, const char *path) > +{ > + struct strbuf buf = STRBUF_INIT; > + struct child_process cp; > + const char **argv = create_sub_grep_argv(opt, path); > + const char *git_dir; > + int hit = 0; > + > + strbuf_addf(&buf, "%s/.git", path); > + git_dir = read_gitfile_gently(buf.buf); > + if (!git_dir) > + git_dir = buf.buf; > + if (!is_directory(git_dir)) { > + warning("submodule %s has not been initialized\n", path); Having a submodule which is not checked out is perfectly fine, so I don't think we want to issue a warning here. > + goto out_free; > + } > + > + memset(&cp, 0, sizeof(cp)); > + cp.argv = argv; > + cp.env = local_repo_env; > + cp.git_cmd = 1; > + cp.no_stdin = 1; > + cp.dir = path; > + if (run_command(&cp) == 0) > + hit = 1; > +out_free: > + free(argv); > + strbuf_release(&buf); > + return hit; > +} > + > static int grep_cache(struct grep_opt *opt, const char **paths, int cached) > { > int hit = 0; > @@ -593,6 +657,10 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached) > > for (nr = 0; nr < active_nr; nr++) { > struct cache_entry *ce = active_cache[nr]; > + if (S_ISGITLINK(ce->ce_mode) && opt->recurse_submodules) { > + hit |= grep_submodule(opt, ce->name); > + continue; > + } > if (!S_ISREG(ce->ce_mode)) > continue; > if (!pathspec_matches(paths, ce->name, opt->max_depth)) > @@ -929,9 +997,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix) > PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback }, > OPT_STRING(0, "submodule-prefix", &opt.submodule_prefix, "DIR", > "prepend this to submodule path output"), > + OPT_BOOLEAN(0, "recurse-submodules", &opt.recurse_submodules, > + "recurse into submodules"), > OPT_END() > }; > > + saved_argc = argc; > + saved_argv = argv; > /* > * 'git grep -h', unlike 'git grep -h <pattern>', is a request > * to show usage information and exit. > diff --git a/grep.h b/grep.h > index d918da4..e3199c9 100644 > --- a/grep.h > +++ b/grep.h > @@ -102,6 +102,7 @@ struct grep_opt { > unsigned post_context; > unsigned last_shown; > int show_hunk_mark; > + int recurse_submodules; > void *priv; > > void (*output)(struct grep_opt *opt, const void *data, size_t size); ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 22:21 ` Jens Lehmann @ 2010-09-29 22:59 ` Junio C Hamano 2010-09-29 23:47 ` Chris Packham 2010-09-30 11:28 ` Johannes Sixt 2010-09-29 23:02 ` Chris Packham 1 sibling, 2 replies; 22+ messages in thread From: Junio C Hamano @ 2010-09-29 22:59 UTC (permalink / raw) To: Jens Lehmann; +Cc: Chris Packham, git Jens Lehmann <Jens.Lehmann@web.de> writes: > Hm, at a quick glance it might be much easier to copy argc & argv > in cmd_grep() before parse_options() starts manipulating it. Yes, I think that is a much saner direction to go. Otherwise, you would need to unparse grep boolean expressions as well. A few more things to think about. 1. What does this mean: $ git grep --recursive -e frotz master next It recurses into the submodule commits recorded in 'master' and 'next' commits in the superproject, right? How do the lines output from the above look like? From the superproject, we will get lines like these: master:t/README: test_description='xxx test (option --frotz) master:t/README: and tries to run git-ls-files with option --frotz.' What if we have a submodule at git-gui in the superproject, and its README has string frotz in it? Should we label the submodule commit we find in 'master' of superproject as 'master' as well, even if it is not at the tip of 'master' branch of the submodule? Or do we get abbreviated hexadecimal SHA-1 name? IOW, would we see: master:git-gui/README: git-gui also knows frotz or deadbeef:git-gui/README: git-gui also knows frotz where "deadbeaf...." is what "git rev-parse master:git-gui" would give us in the superproject? I tend to think the former is preferable, but then most likely you would need to pass not just submodule-prefix but the original ref name (i.e. 'master') you started from down to the recursive one. 2. Now how would this work with pathspecs? $ git grep --recursive -e frotz -- dir/ This should look for the string in the named directory in the superproject and if there are submodules in that directory, recurse into them as well, right? What pathspec, if any, will be in effect when we recurse into the submodule at dir/sub? Limiting to dir/ feels wrong, no? 3. Corollary. Is it reasonable to expect that we will look into all shell scripts, both in the superproject and in submodules, with this: $ git grep --recursive -e frotz -- '*.sh' Oops? What happened to the "we restrict the recursion using pathspec, and we do not pass down the pathspec" that was suggested in 2.? ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 22:59 ` Junio C Hamano @ 2010-09-29 23:47 ` Chris Packham 2010-09-30 11:09 ` Jens Lehmann 2010-09-30 11:28 ` Johannes Sixt 1 sibling, 1 reply; 22+ messages in thread From: Chris Packham @ 2010-09-29 23:47 UTC (permalink / raw) To: Junio C Hamano; +Cc: Jens Lehmann, git On 29/09/10 15:59, Junio C Hamano wrote: > Jens Lehmann <Jens.Lehmann@web.de> writes: > >> Hm, at a quick glance it might be much easier to copy argc & argv >> in cmd_grep() before parse_options() starts manipulating it. > > Yes, I think that is a much saner direction to go. Otherwise, you would > need to unparse grep boolean expressions as well. I've got some of that working in my quest to not use saved_argv[0]. If we follow some of your points below about handling ref names then rebuilding the args actually starts to make life easier. I guess the same is true for just making these manipulations on the grep_opts. The only thing that is really clear is that saving the original argv is not going to help us. > A few more things to think about. > > 1. What does this mean: > > $ git grep --recursive -e frotz master next > > It recurses into the submodule commits recorded in 'master' and 'next' > commits in the superproject, right? > > How do the lines output from the above look like? From the superproject, > we will get lines like these: > > master:t/README: test_description='xxx test (option --frotz) > master:t/README: and tries to run git-ls-files with option --frotz.' > > What if we have a submodule at git-gui in the superproject, and its README > has string frotz in it? Should we label the submodule commit we find in > 'master' of superproject as 'master' as well, even if it is not at the tip > of 'master' branch of the submodule? Or do we get abbreviated hexadecimal > SHA-1 name? IOW, would we see: > > master:git-gui/README: git-gui also knows frotz > > or > > deadbeef:git-gui/README: git-gui also knows frotz > > where "deadbeaf...." is what "git rev-parse master:git-gui" would give us > in the superproject? > > I tend to think the former is preferable, but then most likely you would > need to pass not just submodule-prefix but the original ref name > (i.e. 'master') you started from down to the recursive one. Passing the ref name is doable. There is a little potential for confusion between who's "master" that actually is (the same confusion is in theory possible with an abbreviated SHA-1). Maybe we should color the submodule ref's differently > 2. Now how would this work with pathspecs? > > $ git grep --recursive -e frotz -- dir/ > > This should look for the string in the named directory in the superproject > and if there are submodules in that directory, recurse into them as well, > right? > > What pathspec, if any, will be in effect when we recurse into the > submodule at dir/sub? Limiting to dir/ feels wrong, no? > > 3. Corollary. > > Is it reasonable to expect that we will look into all shell scripts, both > in the superproject and in submodules, with this: > > $ git grep --recursive -e frotz -- '*.sh' > > Oops? What happened to the "we restrict the recursion using pathspec, and > we do not pass down the pathspec" that was suggested in 2.? > This is a bit of a grey area, I'm not sure what is the sensible thing to do. Maybe we could pop a directory level per recursion e.g. user enters 'dir/sub/subsub/*.sh' first level recursion is passed 'sub/subsub/*.sh' second level recursion is passed 'subsub/*.sh' subsequent levels of recursion are passed '*.sh' But that's not quite what the user thought they asked for (i.e. they will end up with dir/sub/subsub/subsubsub/file.sh). Or we could alter the behaviour based on whether their original pathspec had an explicit trailing /. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 23:47 ` Chris Packham @ 2010-09-30 11:09 ` Jens Lehmann 0 siblings, 0 replies; 22+ messages in thread From: Jens Lehmann @ 2010-09-30 11:09 UTC (permalink / raw) To: Chris Packham; +Cc: Junio C Hamano, git Am 30.09.2010 01:47, schrieb Chris Packham: > On 29/09/10 15:59, Junio C Hamano wrote: >> A few more things to think about. >> >> 1. What does this mean: >> >> $ git grep --recursive -e frotz master next >> >> It recurses into the submodule commits recorded in 'master' and 'next' >> commits in the superproject, right? >> >> How do the lines output from the above look like? From the superproject, >> we will get lines like these: >> >> master:t/README: test_description='xxx test (option --frotz) >> master:t/README: and tries to run git-ls-files with option --frotz.' >> >> What if we have a submodule at git-gui in the superproject, and its README >> has string frotz in it? Should we label the submodule commit we find in >> 'master' of superproject as 'master' as well, even if it is not at the tip >> of 'master' branch of the submodule? Or do we get abbreviated hexadecimal >> SHA-1 name? IOW, would we see: >> >> master:git-gui/README: git-gui also knows frotz >> >> or >> >> deadbeef:git-gui/README: git-gui also knows frotz >> >> where "deadbeaf...." is what "git rev-parse master:git-gui" would give us >> in the superproject? >> >> I tend to think the former is preferable, but then most likely you would >> need to pass not just submodule-prefix but the original ref name >> (i.e. 'master') you started from down to the recursive one. Me too thinks that as you grep from inside the superproject it makes more sense to use the ref name used there and not the SHA-1 from the submodule. > Passing the ref name is doable. There is a little potential for > confusion between who's "master" that actually is (the same confusion is > in theory possible with an abbreviated SHA-1). Maybe we should color the > submodule ref's differently Hmm, showing somehow that the grep result is from inside a submodule could be helpful. But using something like the following line seems a bit like overkill, so coloring might be a good alternative: master/deadbeef:git-gui/README: git-gui also knows frotz But I don't have a strong opinion here. >> 2. Now how would this work with pathspecs? >> >> $ git grep --recursive -e frotz -- dir/ >> >> This should look for the string in the named directory in the superproject >> and if there are submodules in that directory, recurse into them as well, >> right? >> >> What pathspec, if any, will be in effect when we recurse into the >> submodule at dir/sub? Limiting to dir/ feels wrong, no? >> >> 3. Corollary. >> >> Is it reasonable to expect that we will look into all shell scripts, both >> in the superproject and in submodules, with this: >> >> $ git grep --recursive -e frotz -- '*.sh' >> >> Oops? What happened to the "we restrict the recursion using pathspec, and >> we do not pass down the pathspec" that was suggested in 2.? >> > > This is a bit of a grey area, I'm not sure what is the sensible thing to do. > > Maybe we could pop a directory level per recursion e.g. > user enters 'dir/sub/subsub/*.sh' > first level recursion is passed 'sub/subsub/*.sh' > second level recursion is passed 'subsub/*.sh' > subsequent levels of recursion are passed '*.sh' > > But that's not quite what the user thought they asked for (i.e. they > will end up with dir/sub/subsub/subsubsub/file.sh). > > Or we could alter the behaviour based on whether their original pathspec > had an explicit trailing /. I think we'll have to manipulate the pathspecs so we properly translate their meaning into the context of the submodule. What about this: If they point outside the submodule, they must be dropped. If they contain directories, the prefix part has to be stripped from the beginning. Examples for submodule 'dir/sub': * 'dir/' and 'dir/sub2/' get dropped as they point outside * '*.sh' should just be passed on * 'dir/sub/foo/*.sh' would become 'foo/*.sh' * 'dir/sub/' gets dropped too (as the result of stripping the prefix is '') That should lead to the expected behavior. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 22:59 ` Junio C Hamano 2010-09-29 23:47 ` Chris Packham @ 2010-09-30 11:28 ` Johannes Sixt 2010-09-30 15:07 ` Jens Lehmann 1 sibling, 1 reply; 22+ messages in thread From: Johannes Sixt @ 2010-09-30 11:28 UTC (permalink / raw) To: Junio C Hamano; +Cc: Jens Lehmann, Chris Packham, git Am 9/30/2010 0:59, schrieb Junio C Hamano: > A few more things to think about. > > 1. What does this mean: > > $ git grep --recursive -e frotz master next > > It recurses into the submodule commits recorded in 'master' and 'next' > commits in the superproject, right? And what does it mean if you add --cached? Does it grep in the index of the submodules, or does it grep in the rev of the submodule that is recorded in the index of the supermodule? -- Hannes ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-30 11:28 ` Johannes Sixt @ 2010-09-30 15:07 ` Jens Lehmann 0 siblings, 0 replies; 22+ messages in thread From: Jens Lehmann @ 2010-09-30 15:07 UTC (permalink / raw) To: Johannes Sixt; +Cc: Junio C Hamano, Chris Packham, git Am 30.09.2010 13:28, schrieb Johannes Sixt: > Am 9/30/2010 0:59, schrieb Junio C Hamano: >> A few more things to think about. >> >> 1. What does this mean: >> >> $ git grep --recursive -e frotz master next >> >> It recurses into the submodule commits recorded in 'master' and 'next' >> commits in the superproject, right? > > And what does it mean if you add --cached? Does it grep in the index of > the submodules, or does it grep in the rev of the submodule that is > recorded in the index of the supermodule? Hmm, as you told grep to use the index of the superproject it should use the rev of the submodule that is recorded in the index of the superproject. Thus the "--cached" should be removed from and the appropriate rev must be added to the arguments of the grep forked in the submodule. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 22:21 ` Jens Lehmann 2010-09-29 22:59 ` Junio C Hamano @ 2010-09-29 23:02 ` Chris Packham 2010-09-30 11:24 ` Jens Lehmann 2010-09-30 18:59 ` Heiko Voigt 1 sibling, 2 replies; 22+ messages in thread From: Chris Packham @ 2010-09-29 23:02 UTC (permalink / raw) To: Jens Lehmann; +Cc: git On 29/09/10 15:21, Jens Lehmann wrote: > Nice start! > > > Am 29.09.2010 22:28, schrieb Chris Packham: >> When the --recurse-submodules option is given git grep will search in >> submodules as they are encountered. > > As "git clone" already introduced a "--recursive" option for > submodule recursion IMO "--recursive" should be used here too for > consistency. (Maybe you took the idea to use "--recurse-submodules" > from my "git-checkout-recurse-submodules" branch on github? But that > is only used there because I didn't get around to change it yet like > I did in the "fetch-submodules-too" branch). I actually started with --recursive and switched to --recurse-submodules. One thing with this is the standard grep --recursive option which may cause some confusion if people expect git grep to behave like normal grep. I'll switch to using --recursive for now until someone objects to the potential confusion. One more thought on this that has been hanging around in my mind. I sometimes want to do something on all but one submodule, in this case with grep I'm fairly likely to want to skip a linux repository because I already know the thing I'm looking for is in userland. Maybe in the future we can make --recursive take an argument that allows us to specify/restrict which submodules get included in the command invocation. > >> Signed-off-by: Chris Packham <judge.packham@gmail.com> >> --- >> builtin/grep.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> grep.h | 1 + >> 2 files changed, 73 insertions(+), 0 deletions(-) >> >> diff --git a/builtin/grep.c b/builtin/grep.c >> index 8315ff0..c9befdc 100644 >> --- a/builtin/grep.c >> +++ b/builtin/grep.c >> @@ -30,6 +30,9 @@ static char const * const grep_usage[] = { >> >> static int use_threads = 1; >> >> +static int saved_argc; >> +static const char **saved_argv; >> + >> #ifndef NO_PTHREADS >> #define THREADS 8 >> static pthread_t threads[THREADS]; >> @@ -585,6 +588,67 @@ static void run_pager(struct grep_opt *opt, const char *prefix) >> free(argv); >> } >> >> +static const char **create_sub_grep_argv(struct grep_opt *opt, const char *path) >> +{ >> + #define NUM_ARGS 10 >> + struct strbuf buf = STRBUF_INIT; >> + const char **argv; >> + int i = 0; >> + >> + argv = xcalloc(NUM_ARGS, sizeof(const char *)); >> + argv[i++] = "grep"; >> + strbuf_addf(&buf, "--submodule-prefix=\\\"%s\\\"", path); >> + //argv[i++] = buf.buf; > > As C++ comments are not portable they have to be avoided, but I > assume this one here (and the unused "saved_argc" variable too) is > a hint that this code is not working as intended yet? ;-) Yeah this is due to my test problem I mentioned in the cover email. When run_command gets called it ends up invoking the installed git executable which doesn't understand my new option. > It seems you want to use strbuf_detach() here so that this argv[] > stays valid after the strbuf_release() at the end of this function. > And if I'm not missing something this would not work correctly in > the second recursion depth, as the new submodule prefix should > be the one given to this grep command concatenated with the current > submodule path. I'll look into strbuf_detatch. The tricky thing will be keeping track of what to free at the end of grep_submodule. I guess I can assume that it will argv[1] is always going to be the dynamically allocated string. > >> + if (opt->linenum) >> + argv[i++] = "-n"; >> + if (opt->invert) >> + argv[i++] = "-v"; >> + if (opt->ignore_case) >> + argv[i++] = "-i"; >> + if (opt->count) >> + argv[i++] = "-c"; >> + if (opt->name_only) >> + argv[i++] = "-l"; >> + >> + argv[i++] = saved_argv[0]; >> + argv[i++] = NULL; > > Hm, at a quick glance it might be much easier to copy argc & argv > in cmd_grep() before parse_options() starts manipulating it. Then > you would only have to change/add the "--submodule-prefix" option > as needed and would not have to deal with all possible grep option > combinations (and for example you don't pass the recurse option > yet, which would stop the recursion pretty soon). Yeah this is the part I was struggling with a little. It would be easy to save argv before any option processing but I wondered if that would be frowned upon as an overhead for non-submodule usages. I was thinking about doing something tricky with max-depth and recursion. But maybe its better to keep it simple. >> + >> + strbuf_release(&buf); >> + return argv; >> +} >> + >> +static int grep_submodule(struct grep_opt *opt, const char *path) >> +{ >> + struct strbuf buf = STRBUF_INIT; >> + struct child_process cp; >> + const char **argv = create_sub_grep_argv(opt, path); >> + const char *git_dir; >> + int hit = 0; >> + >> + strbuf_addf(&buf, "%s/.git", path); >> + git_dir = read_gitfile_gently(buf.buf); >> + if (!git_dir) >> + git_dir = buf.buf; >> + if (!is_directory(git_dir)) { >> + warning("submodule %s has not been initialized\n", path); > > Having a submodule which is not checked out is perfectly fine, so > I don't think we want to issue a warning here. > OK I'll remove it. >> + goto out_free; >> + } >> + >> + memset(&cp, 0, sizeof(cp)); >> + cp.argv = argv; >> + cp.env = local_repo_env; >> + cp.git_cmd = 1; >> + cp.no_stdin = 1; >> + cp.dir = path; >> + if (run_command(&cp) == 0) >> + hit = 1; >> +out_free: >> + free(argv); >> + strbuf_release(&buf); >> + return hit; >> +} >> + >> static int grep_cache(struct grep_opt *opt, const char **paths, int cached) >> { >> int hit = 0; >> @@ -593,6 +657,10 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached) >> >> for (nr = 0; nr < active_nr; nr++) { >> struct cache_entry *ce = active_cache[nr]; >> + if (S_ISGITLINK(ce->ce_mode) && opt->recurse_submodules) { >> + hit |= grep_submodule(opt, ce->name); >> + continue; >> + } >> if (!S_ISREG(ce->ce_mode)) >> continue; >> if (!pathspec_matches(paths, ce->name, opt->max_depth)) >> @@ -929,9 +997,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix) >> PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback }, >> OPT_STRING(0, "submodule-prefix", &opt.submodule_prefix, "DIR", >> "prepend this to submodule path output"), >> + OPT_BOOLEAN(0, "recurse-submodules", &opt.recurse_submodules, >> + "recurse into submodules"), >> OPT_END() >> }; >> >> + saved_argc = argc; >> + saved_argv = argv; >> /* >> * 'git grep -h', unlike 'git grep -h <pattern>', is a request >> * to show usage information and exit. >> diff --git a/grep.h b/grep.h >> index d918da4..e3199c9 100644 >> --- a/grep.h >> +++ b/grep.h >> @@ -102,6 +102,7 @@ struct grep_opt { >> unsigned post_context; >> unsigned last_shown; >> int show_hunk_mark; >> + int recurse_submodules; >> void *priv; >> >> void (*output)(struct grep_opt *opt, const void *data, size_t size); > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 23:02 ` Chris Packham @ 2010-09-30 11:24 ` Jens Lehmann 2010-09-30 16:48 ` Chris Packham 2010-09-30 18:59 ` Heiko Voigt 1 sibling, 1 reply; 22+ messages in thread From: Jens Lehmann @ 2010-09-30 11:24 UTC (permalink / raw) To: Chris Packham; +Cc: git Am 30.09.2010 01:02, schrieb Chris Packham: > I actually started with --recursive and switched to > --recurse-submodules. One thing with this is the standard grep > --recursive option which may cause some confusion if people expect git > grep to behave like normal grep. Guess how I came to use "--recurse-submodules" for recursive checkout in the first place ;-) But the fact that clone already uses it weighs stronger here I suppose ... > One more thought on this that has been hanging around in my mind. I > sometimes want to do something on all but one submodule, in this case > with grep I'm fairly likely to want to skip a linux repository because I > already know the thing I'm looking for is in userland. Maybe in the > future we can make --recursive take an argument that allows us to > specify/restrict which submodules get included in the command invocation. Hmm, maybe adding an option to "git grep" to exclude a pathspec would make more sense? >> It seems you want to use strbuf_detach() here so that this argv[] >> stays valid after the strbuf_release() at the end of this function. > I'll look into strbuf_detatch. The tricky thing will be keeping track of > what to free at the end of grep_submodule. Right, but if you push the strbuf operations into one of the calling functions you can achieve that more easily. > Yeah this is the part I was struggling with a little. It would be easy > to save argv before any option processing but I wondered if that would > be frowned upon as an overhead for non-submodule usages. Yup, but as you are only copying a pointer array the overhead is very small. And if the code gets much easier that way (as I would expect) that price is well paid. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-30 11:24 ` Jens Lehmann @ 2010-09-30 16:48 ` Chris Packham 0 siblings, 0 replies; 22+ messages in thread From: Chris Packham @ 2010-09-30 16:48 UTC (permalink / raw) To: Jens Lehmann; +Cc: git On 30/09/10 04:24, Jens Lehmann wrote: > Am 30.09.2010 01:02, schrieb Chris Packham: >> Yeah this is the part I was struggling with a little. It would be easy >> to save argv before any option processing but I wondered if that would >> be frowned upon as an overhead for non-submodule usages. > > Yup, but as you are only copying a pointer array the overhead is very > small. And if the code gets much easier that way (as I would expect) > that price is well paid. With the talk of translating superproject --index into submodule SHA-1, re-formatting pathspecs and passing the superproject ref-name. It sounds like making a copy of argv is not going to be that useful. If we did copy it we'd have to scan it for the things we don't want passed to the submodule grep. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-29 23:02 ` Chris Packham 2010-09-30 11:24 ` Jens Lehmann @ 2010-09-30 18:59 ` Heiko Voigt 2010-09-30 19:48 ` Jens Lehmann 1 sibling, 1 reply; 22+ messages in thread From: Heiko Voigt @ 2010-09-30 18:59 UTC (permalink / raw) To: Chris Packham; +Cc: Jens Lehmann, git Hi, On Wed, Sep 29, 2010 at 04:02:01PM -0700, Chris Packham wrote: > On 29/09/10 15:21, Jens Lehmann wrote: > > Am 29.09.2010 22:28, schrieb Chris Packham: > >> When the --recurse-submodules option is given git grep will search in > >> submodules as they are encountered. > > > > As "git clone" already introduced a "--recursive" option for > > submodule recursion IMO "--recursive" should be used here too for > > consistency. (Maybe you took the idea to use "--recurse-submodules" > > from my "git-checkout-recurse-submodules" branch on github? But that > > is only used there because I didn't get around to change it yet like > > I did in the "fetch-submodules-too" branch). > > I actually started with --recursive and switched to > --recurse-submodules. One thing with this is the standard grep > --recursive option which may cause some confusion if people expect git > grep to behave like normal grep. I'll switch to using --recursive for > now until someone objects to the potential confusion. How about dropping the option all together and making grep search all populated submodules by default and maybe have an option to turn it off. Since git grep is searching recursive by default this would be what I would expect as a user. Are there other reasons to turn off the search in submodules than the potential runtime penalty because of forks? > One more thought on this that has been hanging around in my mind. I > sometimes want to do something on all but one submodule, in this case > with grep I'm fairly likely to want to skip a linux repository because I > already know the thing I'm looking for is in userland. Maybe in the > future we can make --recursive take an argument that allows us to > specify/restrict which submodules get included in the command invocation. Thinking about this how about not providing a disable submodule recursion option at all? Just provide an --exclude option and let it be used transparently for both normal subfolders and submodules? Cheers Heiko ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 3/3] grep: add support for grepping in submodules 2010-09-30 18:59 ` Heiko Voigt @ 2010-09-30 19:48 ` Jens Lehmann 0 siblings, 0 replies; 22+ messages in thread From: Jens Lehmann @ 2010-09-30 19:48 UTC (permalink / raw) To: Heiko Voigt; +Cc: Chris Packham, git Am 30.09.2010 20:59, schrieb Heiko Voigt: > How about dropping the option all together and making grep search all > populated submodules by default and maybe have an option to turn it off. And that option might be called "--no-recursive"? :-) But when we add an config setting to control the default behavior later (which we had to do for all submodule recursion features so far where we changed the default to recursion) we'll need the "--recursive" option again anyway to be able to override the config setting. So I vote for just leaving the option as it is for now, and we can discuss the proper default as we go along (And in case of grep I have not made up my mind as to what a sane default would be, personally I'm fine with having to use the "--recursive" option when I want recursion, but I won't object to making it the default either). > Since git grep is searching recursive by default this would be what I > would expect as a user. Are there other reasons to turn off the search > in submodules than the potential runtime penalty because of forks? The runtime penalty is a *very* important aspect, as we have some submodule users who have put huge trees into submodules especially to avoid the performance penalties (see the discussions for recursive diff and status). So if we change the default, we will have to provide an config option for that. ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2010-10-01 16:26 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-09-29 20:28 [RFC PATCH 0/3] grep: submodule support Chris Packham 2010-09-29 20:28 ` [RFC PATCH 1/3] add test for git grep --recursive Chris Packham 2010-09-29 20:35 ` Ævar Arnfjörð Bjarmason 2010-09-29 20:48 ` Chris Packham 2010-09-29 21:34 ` Kevin Ballard 2010-09-29 20:28 ` [RFC PATCH 2/3] grep: prepare grep for submodules Chris Packham 2010-09-30 1:10 ` Nguyen Thai Ngoc Duy 2010-09-30 18:34 ` Chris Packham 2010-10-01 14:37 ` Nguyen Thai Ngoc Duy 2010-10-01 16:26 ` Chris Packham 2010-09-29 20:28 ` [RFC PATCH 3/3] grep: add support for grepping in submodules Chris Packham 2010-09-29 22:21 ` Jens Lehmann 2010-09-29 22:59 ` Junio C Hamano 2010-09-29 23:47 ` Chris Packham 2010-09-30 11:09 ` Jens Lehmann 2010-09-30 11:28 ` Johannes Sixt 2010-09-30 15:07 ` Jens Lehmann 2010-09-29 23:02 ` Chris Packham 2010-09-30 11:24 ` Jens Lehmann 2010-09-30 16:48 ` Chris Packham 2010-09-30 18:59 ` Heiko Voigt 2010-09-30 19:48 ` Jens Lehmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).