我正在测试新的git submodule add -b
功能(在git 1.8.2之后),它会创建据称跟踪分支而不是提交的子模块。我正在使用git version 1.8.4.msysgit.0
。子模块的分支跟踪功能似乎在原始超级项目中正常工作,但只要克隆超级项目就会失败。更具体一点:
我所做的是典型的,大致如下,
1. create a git repo (called common): ...
2. create a main project (called main), which uses common as a library/submodule.
mkdir main && cd main
git init
git submodule add -b master url_to_common.git
git commit -m "initial commit"
cd common
git status
正如所宣传的那样,添加的子模块跟踪子模块仓库的主分支。我得到了:
# On branch master
nothing to commit, working directory clean
此外,如果我git pull
或git push
,我会
Already up-to-date.
Everything up-to-date
,分别。
但是,如果我以任何方式克隆main
项目,克隆项目中的common
子模块将失去“On branch”状态。我在git pull
文件夹中的git push
或common
不能像原型main
项目那样。当然,我可以添加origin master
来为克隆项目中的common
拉动和推送工作,但这似乎打败了跟踪子模块(子模块添加-b)的目的。
我用来克隆和检查子模块的命令是:
cd main
git clone . ../main2 --recursive
cd ../main2/common
git status
我得到了:
# HEAD detached at 0259d75
nothing to commit, working directory clean
我也尝试了git clone . ../main3 --recurse-submodules
,以及
git clone . ../main4.git --bare
git clone url_to_main4.git --recursive
同样的事情发生在main3
和main4
上。
总而言之,我创建了一个超级项目,其子模块跟踪其主分支。一旦我尝试克隆它并在其他地方处理它,分支跟踪功能就会丢失。在我看来,保持分支跟踪子模块的唯一方法是压缩原始的main
项目并将其复制。我是否在这种情况下遗漏了一些东西,或者是否正在以最好的方式复制原始项目?
我的问题是,如何在克隆超级项目后保持分支跟踪功能。我对使main4.git
工作特别感兴趣,因为它涉及远程服务器上的裸克隆。
注意:在分支丢失后指定分支(例如Git submodules: Specify a branch/tag)不是我想要的,因为git submodule add -b
中给出的信息仍然丢失,我们又回到原点。我们不妨删除子模块并重新添加。
答案 0 :(得分:1)
对于遇到此问题的其他人:
正如答案所述,您的子模块会跟踪提交。这实际上不是问题,子模块表示单个时间点(即提交)的外部依赖,而不是活动的开发流(分支)。您可以根据自己的选择手动更新此依赖项(理论上,只在Master分支上)
在提交时,您只关心您的分支。在不在分支机构的情况下进行承诺会让人失去理智,并且您的团队很容易失去工作。
我在我们的工作室通过添加预提交钩子来解决这个问题,如果不在分支上则拒绝提交:
#!/bin/sh
function parse_git_branch_check {
if [[ ${branch_name} == "* (detached from "* ]]; then
echo "********************************************"
echo "You need to be on a branch before committing"
echo "********************************************"
exit 1
else
echo "-- You are on branch $branch_name --"
exit 0
fi
}
function parse_git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d'
}
branch_name=$(parse_git_branch)
parse_git_branch_check;
这个钩子致力于超级回购,以及这个BAT(是的,我知道,对不起)脚本来安装钩子
REM - Create links for all submodules to our pre-commit hooks for preventing submissions without a branch
if EXIST .git\hooks\pre-commit (
del .git\hooks\pre-commit
)
mklink /h .git\hooks\pre-commit pre-commit
FOR /F "tokens=*" %%i IN ('DIR .git\modules /A:D /b') do (
if EXIST .git\modules\%%i\hooks\pre-commit (
del .git\modules\%%i\hooks\pre-commit
)
mklink /h .git\modules\%%i\hooks\pre-commit pre-commit
)
新克隆需要运行脚本,这不是完美的,但最接近我能想到的自动解决方案。
答案 1 :(得分:0)
通过特定的提交引用跟踪Git子模块。不通过分支机构。因此,即使您位于HEAD
的{{1}},您的master
项目也会跟踪main
的特定提交。这就是为什么子模块在引用中非常静态的原因,这有时会引起混淆和问题:)
This blog相当好地描述了这个概念。
答案 2 :(得分:0)
git有不同的用例。但对于我的情况,以下适用于git 1.8.5.2(可能稍后)。基本上,首先完成子模块,然后再将其添加回来。当然,子模块是最新的和正常的。
cd main
git rm common
rm -rf .git/modules/common
git submodule add -b master url_to_common.git
cd common
git status
注意,第三行rm ...
是必要的,因为git(从1.8.5.2开始)会在超级项目中留下.git/modules/common
,这会阻止子模块被重新添加。