我是一位以前有svn经验的git新手。我的许多项目都使用自己库中的代码,因此自然而然地,我希望从git中获得一些“类似于外部”的功能。我目前正在尝试使用子模块。
但是,如果您以错误的方式使用子模块(据我所知),会给您带来很多麻烦(例如,更改子模块中的文件而忘记推送它们或忘记提交它们)。
如果我将子模块中的所有文件设为只读怎么办?这足以防止意外更改。而且,如果我真的想更改某些内容,则应该在原始存储库中进行更改。
所以,我的问题是:
编辑:我希望可以通过git hooks来实现,但是我不确定到底是怎么做到的。第一次克隆存储库时,我无法使用客户端挂钩,可以吗?
EDIT2:在SRobertz的帮助下,我可以提出一个结帐后的钩子:
echo "you just checked out: $*"
echo "submodules:"
for p in `grep path .gitmodules | sed 's/.*= //'`; do # get submodules list
echo "making submodule directory $p read-only"
chmod -R a-w $p;
SAVEIFS=$IFS
IFS=$(echo -en "\n\b") #set delimeter to \n\b to handle whitespaces in filenames
for f in `ls $p`; do #get files in submodule dir
echo "making file $f in directory $p read-only"
chmod -R a-w $p\\$f;
done
IFS=$SAVEIFS #restore delimeter to default value
done
现在的问题是,克隆新存储库时,如果已经创建了子模块目录,但尚未提取其中的文件,则此钩子触发得太早。
如果您想要类似svn的外部组件,则可能要看一下Giternal,https://github.com/patmaddox/giternal,可以按原样使用或作为起点。它是用ruby编写的,如果freeze
命令不是您想要的(可能不是),则应该很容易适应您的需求。
简短介绍:http : //www.rubyinside.com/giternal-easy-git-external-dependency-management-1322.html
较长的文章结尾处有一些替代方法:https : //codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/
编辑:在客户端挂钩及其部署上:如果您知道git子模块的怪癖并且想要使用它(也许是为了从引用特定提交而不是以获得稳定性HEAD
),那么这是一种使其读取的方式-仅在克隆或签出时使用。
要使用的客户端挂钩是post-checkout
,并按照(受git储存库中的List子模块以及git-clone和post-checkout挂钩启发)对子模块进行迭代。我在.gitmodules上使用grep,因为它在子模块已初始化。)
#!/bin/sh
# An example post-checkout hook to make submodules read-only
echo "you just checked out: $*"
git submodule init
git submodule update --recursive
echo "submodules:"
for p in `grep path .gitmodules | sed 's/.*= //'`; do
echo "making submodule directory $p read-only"
chmod -R a-w $p;
done
然后,要部署该钩子,一种选择是为开发人员设置一个模板目录,然后让他们做git clone --template=</your/template/dir> url-to-clone...
(即,将该--template=...
选项添加到中git clone
,也许通过使其成为别名并以某种方式将其放置在每个人的全局配置中。
EDIT2:经过评论讨论:
如果子模块已设为只读,则在更新之前需要使它们可写(根据注释,Windows上的git自动完成此操作,但linux / macos上要求这样做)。为此,可以使用类似以下草图git pull
的post-merge
钩子。
#!/bin/sh
# An example post-merge hook to
# 1. make submodules writable,
# 2. init and update submodules, and
# 3. make them read-only
# make all (existing) submodule directories writable
for p in `git submodule status | sed -e "s/^[+\ ][^\ ]*\ //" -e s/\ .*$//`; do
echo "making submodule directory $p writable"
chmod -R u+w $p;
done
echo "updating submodules:"
git submodule init
git submodule update --recursive
# make all submodules read-only
for p in `grep path .gitmodules | sed 's/.*= //'`; do
echo "making submodule directory $p read-only"
chmod -R a-w $p;
done
可以完善此方法以检查合并中是否有任何子模块被更新,并且仅处理该子模块,而不是始终遍历所有子模块。
警告:git pull --recurse-submodules
如果打算使用它,则需要检查它如何相互作用。
请注意,这会初始化并更新所有子模块,并在每次合并(拉动)后将它们设为只读。
但是,它没有解决git pull
子模块内部的问题。为此,需要将相应的钩子添加到.git/modules/*/hooks
(对于git版本> = 1.7.8)或<submodule>/.git/hooks
(对于较旧的git版本)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句