Git 命令行 - 知道是否在子模块中?
git 有什么方法可以知道你是否在子模块中吗?你可以在父目录中像 git submodule foreach 那样思考,但我似乎无法想出一种通用的方法来表明你在子模块中(如果你在一个子模块中),或者在子模块内的任何子目录。
我想你可以使用 git rev-parse --show-toplevel 找到存储库根目录,然后 cd-ing 上一个级别,再次找到该存储库的根目录,然后比较子模块列表到当前目录,但这看起来很粘......
Is there any way in git to know if you're in a submodule? You can do thinks like git submodule foreach
in the parent directory but I can't seem to come up with a generic way to show that you're in a submodule if you're in one, or in any of the child directories inside the submodule.
I guess you could find the repo root with git rev-parse --show-toplevel
, and then cd-ing up a level, and finding the root of that repo again and then comparing the list of submodules to the current directory, but that seems so sticky...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
(Git 2.13 于 2017 年 4 月更新,2017 年第 2 季度)
现在有一个官方命令可以确定某个存储库是否是父存储库的子模块:
请参阅 提交bf0231c(2017 年 3 月 8 日),作者:Stefan Beller (
stefanbeller
)。< br>(由 Junio C Hamano --
gitster
-- 合并于 提交3edcc04,2017 年 3 月 17 日)Jethro Yu 建议评论中:
(2014 年更新)正如 Quentin Pradet 所指出的,更新的 Git子模块存储库显示一个简单的
.git
文件,而不是.git
文件夹。该 .git 文件引用实际子模块 git 存储库的路径,存储在父存储库 .git/modules 子文件夹中。
jeffrson 添加了 评论(2023):
(原始答案:2011 年 9 月)
子模块的本质是作为子模块的 git 存储库不知道它被父存储库用作子模块。
一个肮脏的伎俩是:
git status --ignore-submodules=none
”如果您在
git status
结果中看到该文件,则您的存储库应该是一个子模块。如果它只是一个嵌套存储库,则 git status 应该完全忽略您的嵌套存储库。
(Update April 2017 for Git 2.13, Q2 2017)
There is now an official command to determine if a repo is a submodule of a parent repo:
See commit bf0231c (08 Mar 2017) by Stefan Beller (
stefanbeller
).(Merged by Junio C Hamano --
gitster
-- in commit 3edcc04, 17 Mar 2017)Jethro Yu suggests in the comments:
(Update 2014) As noted by Quentin Pradet, more recent Git submodule repos show a simple
.git
file instead of a.git
folder.That
.git
file reference the path of the actual submodule git repo, stored in the parent repo.git/modules
subfolder.jeffrson adds in the comments (2023):
(Original answer: Sept. 2011)
The very nature of a submodule is for the git repo acting as submodule has no idea it is used as a submodule by a parent repo.
One dirty trick would be to:
git status --ignore-submodules=none
"If you see the file in the result of the
git status
, your repo should be a submodule.If it is only a nested repo, the
git status
should ignore your nested repo entirely.下面是一个 shell 函数,您可以使用它来检测这一点:
编辑 响应您建议的脚本:
看起来不错。
中存在错误,因为它不会 cd 返回(所以只有在第一个子模块
是匹配的)。我的版本检查无需更改目录;这可以通过在子 shell 中执行 cd 来完成,但是返回退出代码会变得很复杂
我不知道你从哪里得到
$_git_dir< /code> 来自 - 我使用
basename
(1) 来得到它信息(见下文)。
名称中包含空格的子模块也存在问题。 在我的版本中,子模块名称中仍然存在换行符问题,但我不太关心解决这个问题。 (请注意避免在子 shell 中使用
while read
的“惯用”方法,而不需要像readarray
这样的新 bash-isms)最后声明所有vars local 修复了使用此功能时的潜在问题
在其他脚本内部(例如,当外部脚本使用
$path
变量时...)我将
_git_dir
重命名为top_level
(即不太容易混淆,因为 GIT_DIR 意味着其他东西)剩余问题:
我不知道git 是否支持它(我不这么认为),但如果子模块目录是符号链接,则此脚本可能会失败(因为“$top_level/..”可能会在包含的存储库之外解析)
子模块名称带有换行符的子模块名称将无法正确识别
我还建议您捕获错误(使用“set -e”,“trap“return 1”)
ERR' 或类似) - 不在我的脚本/读者练习中
Here is a shell function that you can use to detect this:
Edit In response to your proposed script:
Looking good.
There is a bug inbecause it won't cd back (so it would only work if the first submoduleMy version checks without changing directories; That could be done done byis a match).
cd
-ing in a subshell, but returning the exitcode is getting complicated that wayI don't know where you get
$_git_dir
from - I usedbasename
(1) to get thatinformation (see below).
There was also a problem with submodules containing a space in the name. In my version, there is still a problem with newlines in submodule names left, but I don't care enough to fix that. (Note the 'idiomatic' way to avoid having the
while read
in a subshell without needing new bash-isms likereadarray
)finally declaring all the vars local fixes potential problems when using this
inside other scripts (e.g. when the outer script uses the
$path
variable...)I renamed
_git_dir
totop_level
(which is less confusing, because GIT_DIR means something else)Remaining issues:
I don't know whether git supports it (I don't think so) but this script could fail if the submodule directory is a symlink (because "$top_level/.." might resolve outside the containing repository)
submodule names with newlines will not be recognized properly
I also suggest you trap errors (either with 'set -e', 'trap "return 1"
ERR' or similar) -- not in my script/exercise for reader
Usage
尝试 git rev-parse --git-dir ,当且仅当从项目根调用时,它才会返回“.git”:
除非您设置 $GIT_DIR< /code> 这将是这种情况下的返回值(请参阅 rev-parse ):
try
git rev-parse --git-dir
which will return".git"
if and only if called from the project root:unless you set
$GIT_DIR
which will be the returned value in that case (see rev-parse):我尝试了上面建议的脚本,但它对我不起作用。当然,我可能是世界上唯一一个拥有不是父模块的直接子模块的子模块的人。上面的代码假设确实如此。
然后显示父模块内的子模块路径也很好 - 我计划使用它来显示 bash shell 提示,告诉我是否在子模块中以及在哪里。
这是我的更新:
I tried the script suggested above and it didn't work for me. Of course, I may be the only person in the world who has a submodule that's not a direct child of the parent module. The code above assumes that it is.
It would also be nice to then show the submodule path inside the parent - I plan to use this to show a bash shell prompt telling me if I'm in a submodule, and where.
Here's my update:
所选答案不适用于不在顶层的子模块。这确实并且也更简单:
The selected answer doesn't work for submodules that aren't at the top level. This does and is also simpler: