Re: [PATCH/RFC] Changing submodule foreach --recursive to be depth-first, --parent option to execute command in supermodule as well
- From
- Eric Cousineau <eacousineau@gmail.com>
- Date
- Mar 26, 2013, 04:36 UTC
- Message-ID
- <515125CE.3020101@gmail.com>
- In-Reply-To
- <51511C62.3080704@gmail.com>
On 03/25/2013 10:56 PM, Eric Cousineau wrote:
> On 03/18/2013 04:10 PM, Jens Lehmann wrote: >> Am 12.03.2013 17:01, schrieb Phil Hord: >>> On Sat, Mar 9, 2013 at 1:18 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote: >>>> Am 05.03.2013 22:17, schrieb Phil Hord:
...
Show 114 quoted lines
>>
>> I agree on the possible problems a configuration option introduces.
>>
>>>> I'm still not convinced we should add a new switch, as it can easily
>>>> be achieved by adding "${cmd} &&" to your scripts. And on the command
>>>> line you could use an alias like this one to achieve that:
>>>>
>>>> [alias]
>>>> recurse = !sh -c \"$@ && git submodule foreach --recursive $@\"
>>>
>
> I tried this and the 'recurse-post' alias, but could not get it to function as
> it does inside of 'git submodule foreach'. I also tried out some different escaping
> methods, but nothing seemed to work. I've added the examples below.
>
>>> Yes, making the feature itself a 2nd-class citizen. :-)
>>>
>>> But this alias also denies me the benefit of the --post-order option.
>>> For 'git recurse git push', for example, I wouldn't want the
>>> superproject push to occur first; I would want it to occur last after
>>> the submodules have been successfully pushed.
>>
>> [alias]
>> recurse-post = !sh -c \"git submodule foreach --recursive --post-order $@ && $@\"
>> ;-)
>>
>>> I agree this should go in some other commit, but I do not think it is
>>> so trivial it should never be considered as a feature for git. That's
>>> all I'm trying to say.
>>
>> I am not against adding such a functionality to Git, I'm just not
>> convinced "git submodule foreach" is the right command for that. I
>> suspect the "git for-each-repo" Lars proposed earlier this year might
>> be a better choice, as that could also recurse into other repos which
>> aren't registered as submodules. And a "for-each-repo" to me looks
>> like a command which could include the superproject too (at least when
>> told to do so with an option).
>>
>
> Here are the aliases I am using:
>
> [alias]
> recurse = !sh -c \"$@ && git submodule foreach --recursive $@\"
> recurse-post = !sh -c \"git submodule foreach --recursive --post-order $@ && $@\"
> fer = !sh -c \"eval \\\"$@\\\" && git submodule foreach --recursive \\\"$@\\\"\"
> ferpo = !sh -c \"git submodule foreach --recursive --post-order \\\"$@\\\" && eval \\\"$@\\\"\"
> fers = !sh -c \"eval '$@' && git submodule foreach --recursive '$@'\"
> ferpos = !sh -c \"git submodule foreach --recursive --post-order '$@' && eval '$@'\"
>
> And these are the results I get with the following example:
>
> $ cmd="echo \"'ello world: \$PWD\""
> $ eval "$cmd"
> 'ello world: /tmp/a
> $ git submodule foreach --recursive "$cmd"
> Entering 'b'
> 'ello world: /tmp/a/b
> Entering 'b/d'
> 'ello world: /tmp/a/b/d
> Entering 'c'
> 'ello world: /tmp/a/c
> $ git submodule foreach --recursive --post-order "$cmd" "$cmd"
> Entering 'b'
> 'ello world: /tmp/a/b
> Entering 'b/d'
> 'ello world: /tmp/a/b/d
> Exiting 'b/d'
> 'ello world: /tmp/a/b/d
> Exiting 'b'
> 'ello world: /tmp/a/b
> Entering 'c'
> 'ello world: /tmp/a/c
> Exiting 'c'
> 'ello world: /tmp/a/c
> $ git recurse "$cmd"
> 'ello world: /tmp/a
> Entering 'b'
> /home/eacousineau/local/lib/git/libexec/git-core/git-submodule: 1: eval: Syntax error: Unterminated quoted string
> Stopping at 'b'; script returned non-zero status.
> $ git recurse-post "$cmd"
> Entering 'b'
> /home/eacousineau/local/lib/git/libexec/git-core/git-submodule: 1: eval: Syntax error: Unterminated quoted string
> Stopping at 'b'; script returned non-zero status.
> $ git fer "$cmd"
> ello world: /tmp/a
> Entering 'b'
> ello world: /tmp/a
> Entering 'b/d'
> ello world: /tmp/a
> Entering 'c'
> ello world: /tmp/a
> $ git ferpo "$cmd"
> Entering 'b'
> /home/eacousineau/local/lib/git/libexec/git-core/git-submodule: 1: eval: world:: not found
> Stopping at 'b'; script returned non-zero status.
> Stopping at 'b'; script returned non-zero status.
> $ git fers "$cmd"
> ello world: /tmp/a' && git submodule foreach --recursive 'echo ello world: /tmp/a
> $ git ferpos "$cmd"
> Entering 'b'
> /home/eacousineau/local/lib/git/libexec/git-core/git-submodule: 1: eval: Syntax error: Unterminated quoted string
> Stopping at 'b'; script returned non-zero status.
>
> The problem is trying to escape with double-quotes, where the single-quotes are evaluated
> as a shell token thing and not as a string argument, versus single-quotes, where you cannot (easily) escape single
> quotes inside of it (though please correct me if I'm wrong!).
> It seems the best solution would be to have it as a script to allow recursion to occur in the scope of one script,
> like submodule foreach.
>
> I understand now why it does not fit in the scope of 'git submodule', though, so I could implement it as a *very*
> lightweight stand-in for Lars's "git for-each-repo" via some copy-and-paste :P
>
> - Eric
>Put together a script with the --include-super functionality, named it 'git-fer.sh' to start. Posted as a Gist: https://gist.github.com/eacousineau/5243161
That test case:
$ git-fer --include-super --recursive --post-order "$cmd" "$cmd" Entering supermodule 'a' 'ello world: /tmp/a Entering 'b' 'ello world: /tmp/a/b Entering 'b/d' 'ello world: /tmp/a/b/d Exiting 'b/d' 'ello world: /tmp/a/b/d Exiting 'b' 'ello world: /tmp/a/b Entering 'c' 'ello world: /tmp/a/c Exiting 'c' 'ello world: /tmp/a/c Exiting supermodule 'a' 'ello world: /tmp/a