Convert .gitmodules into a parsable format for iteration using Bash

Nic*_*mou 5 git bash git-submodules

Background

I would like to make a shell function that takes .gitmodules and iterates over each module executing certain commands based off of each submodules properties (e.g. <PATH> or <URL> or <BRANCH>).

?? The default format of .gitmodules:

[submodule "PATH"]
    path = <PATH>
    url = <URL>
[submodule "PATH"]
    path = <PATH>
    url = <URL>
    branch = <BRANCH>
Run Code Online (Sandbox Code Playgroud)

?? Pseudocode:

def install_modules() {
    modules = new list

    fill each index of the modules list with each submodule & its properties

    iteratate over modules
       if module @ 'path' contains a specified 'branch':
          git submodule add -b 'branch' 'url' 'path'
       else:
          git submodule add 'url' 'path'
}
Run Code Online (Sandbox Code Playgroud)

?? Current install_modules()

# currently works for grabbing the first line of the file
# doesn't work for each line after.
install_modules() {
    declare -A regex

    regex["module"]='\[submodule "(.*)"\]'
    regex["url"]='url = "(.*)"'
    regex["branch"]='branch = "(.*)"'

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    cat < ".gitmodules" | while read -r LINE; do
        if [[ $LINE =~ ${regex[module]} ]]; then
            PATH=${BASH_REMATCH[1]}

            echo "$PATH"
        fi
    done
}
Run Code Online (Sandbox Code Playgroud)

phd*_*phd 5

.gitmodules是一个类似.gitconfig文件,因此您可以使用git config它来读取它。例如,从 a 中读取所有值.gitmodules,按=(key=value)拆分值,按拆分键.

git config -f .gitmodules -l | awk '{split($0, a, /=/); split(a[1], b, /\./); print b[1], b[2], b[3], a[2]}'
Run Code Online (Sandbox Code Playgroud)

git config -f .gitmodules -l 打印出类似的东西

submodule.native/inotify_simple.path=native/inotify_simple
submodule.native/inotify_simple.url=https://github.com/chrisjbillington/inotify_simple
Run Code Online (Sandbox Code Playgroud)

awk输出将是

submodule native/inotify_simple path native/inotify_simple
submodule native/inotify_simple url https://github.com/chrisjbillington/inotify_simple
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,我认为没有理由避免使用“git config”。无论如何,你有“git”,你要运行“git submodule”,为什么不运行“git config”?您可能需要以不同的方式命名该文件,以便“git submodule add”不会破坏它。 (2认同)
  • 还值得一提的是:`git config` 可以通过其 blob 哈希 ID 或其他合适的修订字符串直接从 Git 存储库读取配置文件。Git 很早以前就培养了这种能力,*因为*Git 需要从不一定提取到文件系统的`.gitmodules` 文件中读取子模块信息。因此,您可以执行`GIT_DIR=$path_to_repo/.git git config --blob &lt;whatever&gt; --get ...`。文档建议使用,例如,`--blob master:.gitmodules`。 (2认同)

Nic*_*mou 4

在@phdRestore git submodules from .gitmodules@phd向我指出的方向)的帮助下,我能够构建我需要的函数。

\n\n

install_submodules()

\n\n

\xe2\x9a\xa0\xef\xb8\x8f注意假设$REPO_PATH已声明并初始化。

\n\n

\xe2\x9a\xa0\xef\xb8\x8f我的答案是改编自/sf/answers/3728874901/。

\n\n
install_submodules() {\n    git -C "${REPO_PATH}" config -f .gitmodules --get-regexp \'^submodule\\..*\\.path$\' |\n        while read -r KEY MODULE_PATH\n        do\n            # If the module\'s path exists, remove it.\n            # This is done b/c the module\'s path is currently \n            # not a valid git repo and adding the submodule will cause an error.\n            [ -d "${MODULE_PATH}" ] && sudo rm -rf "${MODULE_PATH}"\n\n            NAME="$(echo "${KEY}" | sed \'s/^submodule\\.\\(.*\\)\\.path$/\\1/\')"\n\n            url_key="$(echo "${KEY}" | sed \'s/\\.path$/.url/\')"\n            branch_key="$(echo "${KEY}" | sed \'s/\\.path$/.branch/\')"\n\n            URL="$(git config -f .gitmodules --get "${url_key}")"\n            BRANCH="$(git config -f .gitmodules --get "${branch_key}" || echo "master")"\n\n            git -C "${REPO_PATH}" submodule add --force -b "${BRANCH}" --name "${NAME}" "${URL}" "${MODULE_PATH}" || continue\n        done\n\n    git -C "${REPO_PATH}" submodule update --init --recursive\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 推荐的小调整:在 sed 表达式中,添加一个锚点(“path$”而不仅仅是“path”),这样路径为“x.path”的邪恶子模块不会被翻译为“NAME=x” ` 而是进入 `NAME=x.path`。 (2认同)