git submodule foreach - Robust way to recursively commit a child module first?

和自甴很熟 提交于 2019-11-27 18:08:47

问题


Is there a robust way to do a recursive depth-first git submodule foreach command? I am using the foreach --recursive command which does the job, except it is breadth-first. This is a problem because if I have the following structure:

  • A
    • B
  • C

And I have commits in all three, a foreach --recursive add -A && git commit ... will hit A, B, C, which is problematic if I want the supermodule to capture the commits of B at that time.

I found this discussion from 2008, but it does not look like any of the suggested features are in the current version of Git that I have (1.7.9.5).

I wrote a small bash function to do this (excuse the shorthand naming):

function git-sfed() { git submodule foreach "git submodule foreach '$*' && $*"; }

And testing it with the following fanciful command seems to work:

git-sfed 'python -c "import sys; print sys.argv" $path'

Does this command seem robust, or are there other common existing methods?


回答1:


You can try this

git submodule  foreach --recursive  |  tail  -r | sed 's/Entering//' | xargs -I% cd % ; git add -A \& git commit

This list (recursively) all the submodules , then reverse the list, tail -r so you get the directories in the order you want (child first), enter the directory and do what ever you want in it.




回答2:


I didn't find any other way than your function to perform a depth-first foreach command.

The test would be to check if it does achieve recursive for a depth of more than one.

A
  B
    D
  C

I've been having trouble with by yours and my command when trying to put in single quotes (kinda sucks not being able to write them) - escaping with multiple levels of bash commands is a little confusing.

This (quotes issue) should be simplified in Git 1.9/2.0 (Q1 2014), with commit 1c4fb13 from Anders Kaseorg (andersk):

'eval "$@"' creates an extra layer of shell interpretation, which is probably not expected by a user who passes multiple arguments to git submodule foreach:

 $ git grep "'"
 [searches for single quotes]
 $ git submodule foreach git grep "'"
 Entering '[submodule]'
 /usr/lib/git-core/git-submodule: 1: eval: Syntax error: Unterminated quoted string
 Stopping at '[submodule]'; script returned non-zero status.

To fix this, if the user passes more than one argument, execute "$@" directly instead of passing it to eval.

Examples:

  • Typical usage when adding an extra level of quoting is to pass a single argument representing the entire command to be passed to the shell.
    This doesn't change that.
  • One can imagine someone feeding untrusted input as an argument:
    git submodule foreach git grep "$variable"

That currently results in a nonobvious shell code injection vulnerability.
Executing the command named by the arguments directly, as in this patch, fixes it.


Since Git 2.21 (Q2 2017), you have git grep -e "bar" --recurse-submodules



来源:https://stackoverflow.com/questions/14846967/git-submodule-foreach-robust-way-to-recursively-commit-a-child-module-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!