我正在尝试使用下面的 bash 方法将 AOSP 代码镜像到我们本地的 Gerrit 系统中。
#!/bin/bash
repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r9 --mirror
repo sync
repo_list=`repo list -p`
repo forall -c '
if [[ ${REPO_PATH} =~ $repo_list ]]; then
ssh -p 29418 gerritadmin@local-gerrit-host gerrit create-project aosp/${REPO_PATH} --parent All-Projects || echo "Failed to create project for ${REPO_PATH}"
fi
git push ssh://gerritadmin@local-gerrit-host:29418/aosp/${REPO_PATH} +refs/heads/* +refs/tags/* || echo "Failed to push ${REPO_PATH}"
'
但是,我在
repo forall
循环中遇到了问题。我有一个if condition
,但它似乎没有按预期工作。我不确定 repo forall
循环 bash IF
条件是否有效。
主要是,我的目标是尽量减少与本地 gerrit 服务器的多个 Gerrit SSH 连接,以减少负载。
您能帮我找到实现这一目标的正确方法吗?
剧本存在一些问题。
if [[ ${REPO_PATH} =~ $repo_list ]]; then
ssh -p 29418 gerritadmin@local-gerrit-host gerrit create-project aosp/${REPO_PATH} --parent All-Projects || echo "Failed to create project for ${REPO_PATH}"
fi
应该是
$repo_list =~ ${REPO_PATH}
。否则,除非只有一个项目,否则它总是错误的。即便如此,if
条款是不必要的并且是有缺陷的。 repo list -p
与 repo forall -c 'echo $REPO_PATH’
具有相同的效果。 $REPO_PATH
始终位于 repo list -p
的输出中。此外,如果 foo/bar_baz
中有路径 $repo_list
并且 $REPO_PATH
是 foo/bar
,则测试仍然通过,但可能不是预期的。
实际上,这里的
if
子句应该是在创建项目之前测试aosp/${REPO_PATH}
项目是否已经存在于您的Gerrit上。首先,列出包含子字符串 aosp/${REPO_PATH}
的所有项目。不幸的是,它不需要正则表达式。
ssh -p 29418 gerritadmin@local-gerrit-host gerrit ls-projects -m "aosp/${REPO_PATH}" < /dev/null
然后测试列出的项目之一是否正是“aosp/${REPO_PATH}”,而不是类似
aosp/${REPO_PATH}_foo
的内容。我认为省略测试也可以,因为如果项目已经存在,gerrit create-project
会引发错误。
根据我的经验,始终将
< /dev/null
附加到 Gerrit SSH CLI,尤其是在循环中使用它时。如果没有它,循环将在第一次运行后中断。
ssh -p 29418 gerritadmin@local-gerrit-host gerrit create-project aosp/${REPO_PATH} --parent All-Projects < /dev/null