# [RFC PATCH 0/2] submodule aware grep

6 messages from 2010-09-23 to 2010-09-24. Participants: Chris Packham, Heiko Voigt, Jens Lehmann.
Thread: https://gitlist.dev/t/25215

## Chris Packham, 2010-09-23 21:17

Subject: [RFC PATCH 0/2] submodule aware grep
Message-ID: <1285276627-7907-1-git-send-email-judge.packham@gmail.com>
URL: https://gitlist.dev/e/1285276627-7907-1-git-send-email-judge.packham%40gmail.com

```
This series contains 2 RFC patches that both implement a grep feature for
submodules.  The first patch is a self-contained script for contrib that should
work with most current git versions. The 2nd is basically the same
implementation but done as a proper git submodule command with some of the
helper code moved to git-sh-setup.sh

There are a couple of questions for this. Technically I'm making submodule 
grep-aware, should I be making grep submodule-aware instead? I haven't looked 
at the grep code yet but I imagine its harder.

Should I be putting the submodule_root* routines in git-sh-setup or should I be
looking at adding it to 'git rev parse' instead. I'm guessing eventually more 
commands might want to be able to get at the base superproject.

Chris Packham (2):
      contrib: add git-submodule-grep.sh
      submodule: add grep command

```

## Chris Packham, 2010-09-23 21:17

Subject: [RFC PATCH 1/2] contrib: add git-submodule-grep.sh
Message-ID: <1285276627-7907-2-git-send-email-judge.packham@gmail.com>
URL: https://gitlist.dev/e/1285276627-7907-2-git-send-email-judge.packham%40gmail.com
In-Reply-To: <1285276627-7907-1-git-send-email-judge.packham@gmail.com>

```
A simple wrapper around 'git grep' that is submodule aware.

The advantage of this over "git submodule foreach 'git grep <pattern>'" is
that the results are presented with a path relative to the current
directory. Also this script will work from any subdirectory of any submodule
in the current superproject.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
 contrib/git-submodule-grep.sh |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)
 create mode 100755 contrib/git-submodule-grep.sh

diff --git a/contrib/git-submodule-grep.sh b/contrib/git-submodule-grep.sh
new file mode 100755
index 0000000..407fdb0
--- /dev/null
+++ b/contrib/git-submodule-grep.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# Copyright (c) 2010, Chris Packham
+# Wrapper for git grep that is submodule aware
+
+SUBDIRECTORY_OK="yes"
+. git-sh-setup
+
+submodule_root_relative()
+{
+	ceiling="$HOME"
+	while test ! -e "$cdup.gitmodules"; do
+		cdup="$cdup../"
+		if test "$(cd $cdup && pwd)" == "$ceiling"; then
+			echo >&2 "fatal: failed to find superproject root,"
+			echo >&2 "       stopped searching at $ceiling."
+			exit 1
+		fi
+	done
+	echo "$cdup"
+}
+
+submodule_root()
+{
+	(cd "$(submodule_root_relative)" && pwd)
+}
+
+# we don't do anything with the arg but we should check that we
+# have something to pass to git grep
+test $# -lt 1 && die "fatal: no pattern given."
+
+prefix="$(submodule_root_relative)" || exit 1
+(cd "./$prefix"; \
+	git submodule --quiet foreach \
+		"git --no-pager grep $@ | sed s\"|.*|$prefix\$path/&|\" || true") \
+			| git_pager
-- 
1.7.3.dirty

```

## Chris Packham, 2010-09-23 21:17

Subject: [RFC PATCH 2/2] submodule: add grep command
Message-ID: <1285276627-7907-3-git-send-email-judge.packham@gmail.com>
URL: https://gitlist.dev/e/1285276627-7907-3-git-send-email-judge.packham%40gmail.com
In-Reply-To: <1285276627-7907-1-git-send-email-judge.packham@gmail.com>

```
This adds a 'grep' command to the 'git submodule' commands. Internally it is
basically a wrapper for "git submodule foreach 'git grep <pattern>'" but
does have the advantage of supplying results with a path relative to the
current directory.

Unlike contrib/git-submodule-grep.sh this can only be run from the root of a
submodule or the root of the superproject.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
 git-sh-setup.sh  |   19 +++++++++++++++++++
 git-submodule.sh |   41 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index 6131670..2a1d585 100644
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -145,6 +145,25 @@ require_work_tree () {
 	die "fatal: $0 cannot be used without a working tree."
 }
 
+submodule_root_relative()
+{
+	ceiling="$HOME"
+	while test ! -e "$cdup.gitmodules"; do
+		cdup="$cdup../"
+		if test "$(cd $cdup && pwd)" == "$ceiling"; then
+			echo >&2 "fatal: failed to find superproject root."
+			echo >&2 "       stopped searching at $ceiling".
+			exit 1
+		fi
+	done
+    echo "$cdup"
+}
+
+submodule_root()
+{
+    (cd "$(submodule_root_relative)" && pwd)
+}
+
 get_author_ident_from_commit () {
 	pick_author_script='
 	/^author /{
diff --git a/git-submodule.sh b/git-submodule.sh
index 9ebbab7..3edaa49 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -11,7 +11,8 @@ USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <r
    or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
-   or: $dashless [--quiet] sync [--] [<path>...]"
+   or: $dashless [--quiet] sync [--] [<path>...]
+   or: $dashless [--quiet] grep [--] [-n] [<pattern>]"
 OPTIONS_SPEC=
 . git-sh-setup
 . git-parse-remote
@@ -849,6 +850,42 @@ cmd_sync()
 		fi
 	done
 }
+#
+# Search for a pattern within all submodules
+# This is a fairly simple wrapper using foreach and git grep,
+# arguments could be passed to git grep but for now we only
+# understand -n
+#
+cmd_grep()
+{
+	grep_args=""
+	while test $# -ne 0
+	do
+		case "$1" in
+		-n)
+			grep_args="$1"
+			shift
+			;;
+		--)
+			shift
+			break
+			;;
+		-*)
+			usage
+			;;
+		*)
+			break
+			;;
+		esac
+	done
+	test $# -lt 1 && die "fatal: no pattern given"
+
+	prefix="$(submodule_root_relative)" || exit 1
+	(cd "./$prefix"; \
+		cmd_foreach "git --no-pager grep $grep_args -- $@ | \
+			sed s\"|.*|$prefix\$path/&|\" || true") \
+				| git_pager
+}
 
 # This loop parses the command line arguments to find the
 # subcommand name to dispatch.  Parsing of the subcommand specific
@@ -859,7 +896,7 @@ cmd_sync()
 while test $# != 0 && test -z "$command"
 do
 	case "$1" in
-	add | foreach | init | update | status | summary | sync)
+	add | foreach | init | update | status | summary | sync | grep)
 		command=$1
 		;;
 	-q|--quiet)
-- 
1.7.3.dirty

```

## Heiko Voigt, 2010-09-24 13:47

Subject: Re: [RFC PATCH 0/2] submodule aware grep
Message-ID: <20100924134748.GA576@book.hvoigt.net>
URL: https://gitlist.dev/e/20100924134748.GA576%40book.hvoigt.net
In-Reply-To: <1285276627-7907-1-git-send-email-judge.packham@gmail.com>

```
Hi,

On Thu, Sep 23, 2010 at 02:17:05PM -0700, Chris Packham wrote:
> This series contains 2 RFC patches that both implement a grep feature for
> submodules.  The first patch is a self-contained script for contrib that should
> work with most current git versions. The 2nd is basically the same
> implementation but done as a proper git submodule command with some of the
> helper code moved to git-sh-setup.sh
> 
> There are a couple of questions for this. Technically I'm making submodule 
> grep-aware, should I be making grep submodule-aware instead? I haven't looked 
> at the grep code yet but I imagine its harder.

Nice work! IMO it would be even nicer to have it as part of git grep.
Have a look at Jens branch about submodule checkout:

http://github.com/jlehmann/git-submod-enhancements (enhance_git_for_submodules)

particularly how checkout_submodule() is implemented. It forks a git
checkout inside the submodule. In a similar way you could fork a grep
there. Then you just have to teach the forked grep to prepend the
submodules path.

Cheers Heiko

```

## Chris Packham, 2010-09-24 16:07

Subject: Re: [RFC PATCH 0/2] submodule aware grep
Message-ID: <4C9CCCCC.4000909@gmail.com>
URL: https://gitlist.dev/e/4C9CCCCC.4000909%40gmail.com
In-Reply-To: <20100924134748.GA576@book.hvoigt.net>

```
On 24/09/10 06:47, Heiko Voigt wrote:
> Hi,
> 
> On Thu, Sep 23, 2010 at 02:17:05PM -0700, Chris Packham wrote:
>> This series contains 2 RFC patches that both implement a grep feature for
>> submodules.  The first patch is a self-contained script for contrib that should
>> work with most current git versions. The 2nd is basically the same
>> implementation but done as a proper git submodule command with some of the
>> helper code moved to git-sh-setup.sh
>>
>> There are a couple of questions for this. Technically I'm making submodule 
>> grep-aware, should I be making grep submodule-aware instead? I haven't looked 
>> at the grep code yet but I imagine its harder.
> 
> Nice work! IMO it would be even nicer to have it as part of git grep.
> Have a look at Jens branch about submodule checkout:
> 
> http://github.com/jlehmann/git-submod-enhancements (enhance_git_for_submodules)
> 
> particularly how checkout_submodule() is implemented. It forks a git
> checkout inside the submodule. In a similar way you could fork a grep
> there. Then you just have to teach the forked grep to prepend the
> submodules path.
> 

I'll look into it, from following Jens code it doesn't look too hard
(like you say just fork and pass a text prefix). I'm currently doing my
git hacking on my main development machine so I should probably setup
and environment where I can hack without affecting $dayjob work.

In the meantime I've got an updated patch for contrib if anyone is
interested (it just adds some grep options to be passed through).

Thanks,
Chris

```

## Jens Lehmann, 2010-09-24 17:10

Subject: Re: [RFC PATCH 0/2] submodule aware grep
Message-ID: <4C9CDB75.9070405@web.de>
URL: https://gitlist.dev/e/4C9CDB75.9070405%40web.de
In-Reply-To: <20100924134748.GA576@book.hvoigt.net>

```
Am 24.09.2010 15:47, schrieb Heiko Voigt:
>> There are a couple of questions for this. Technically I'm making submodule 
>> grep-aware, should I be making grep submodule-aware instead? I haven't looked 
>> at the grep code yet but I imagine its harder.
> 
> Nice work! IMO it would be even nicer to have it as part of git grep.

I like it too! And yes, me too thinks adding a "--recursive" option
to "git grep" would make more sense than adding a "grep" option to
the "git submodule" script.

```
