强制 Git 子模块始终保持最新

我喜欢 git 子模块。而且,我讨厌 git 子模块。我喜欢它们的地方在于它使你能够清楚地划分依赖关系等等。我明白让他们指出回购的具体承诺是什么意思,真的。但是在我的例子中,我正在构建一个库,它将用于另一个项目,所以我想将它保存在那个单独的回购中。

然而,当我每天都在使用这个库,并且不断地切换到使用我的库来提交指针更新的应用程序时,烦恼就来了。

那么,有没有可能在我不断更新和添加这个库时,git 子模块总是位于它所指向的回购的头部呢?

45638 次浏览

UPDATE: As of git 1.8.2, there seems to be a solution. Please see VonC's answer down below. The original answer is left here for the users of git < 1.8.2.


No, and this is by design. If there were a way to point a submodule to the "current head" of some other repository, then it would be impossible to retrieve a historical version (such as a tagged version) from the main repository. It wouldn't know which version of the submodule to check out.

Having said that, you may be interested in the git subtree script. This offers a different way of working with submodules that may be more compatible with your workflow. I was just reminded of this by the recent post on HN.

Why don't you make changes inside the submodule directory, which itself is a git repo? This way, your app will always have updated library.

Caveats:

  1. You still need to commit the submodule change inside your app repo to put the change in version control (for the app).

  2. If there are more apps than one that are using this library, than this is not going to work, since only one app will be up-to-date at any given time.

As I mention in "git submodule tracking latest", you can since git 1.8.2 (March 2013) make a submodule track the HEAD of branch:

git submodule add -b <branch> <repository> [<path>]

A submodule SHA1 is still recorded in the parent repo as a gitlink (special entry in the index)

But a git submodule update --remote will update that entry to the SHA1 matching the HEAD of a branch of the submodule remote repo.

If you have an existing submodule, you can make it follow a branch with:

cd /path/to/your/parent/repo
git config -f .gitmodules submodule.<path>.branch <branch>


cd path/to/your/submodule
git checkout -b branch --track origin/branch
# if the master branch already exist:
git branch -u origin/master master


cd /path/to/your/parent/repo
git add path/to/your/submodule
git commit -m "Make submodule tracking a branch"

There is no such thing for the moment. To keep the code up-to-date, I use the following commands:

download all for the first time: git clone --recursive http://github.com/<your repo>
download updates in existing repo: git submodule update --remote --recursive --merge