git子模块提交/推/pull

标签 git git-submodules

我想使用 git 子模块。

我需要采取的步骤将我的更改推送到我的项目是

  1. add/commit/push from submodule directory
  2. add/commit/push from parent directory


我需要采取的步骤来 pull 我的项目的更改。

  1. git pull from parent directory
  2. git submodule update from parent directory


从原始存储库更新子模块的步骤

  1. git pull from submodule directory


让我担心的是以下摘自http://git-scm.com/book/en/Git-Tools-Submodules

The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial submodule update, commit in that submodule directory without creating a branch to work in, and then run git submodule update again from the superproject without committing in the meantime,(?? update/commit/update will lose change?) Git will overwrite your changes without telling you. Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve.

To avoid this issue, create a branch when you work in a submodule directory with git checkout -b work or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to.



我要修改子模块,不想搞砸,上面的文档简要提到了丢失更改的可能性,我不明白可能导致丢失的原因。

I wonder what additional steps more than I listed above I need to take to prevent the loss. Especially several team members modify submodules, what do they need to do not to mess up?

最佳答案

作为在 Visual Studio 解决方案中处理外部项目并试图解决类似问题的人,我想与您分享我的经验。我对 git 比较陌生,所以如果有人有任何 build 性的批评,我将不胜感激。

如果您使用的是 Visual Studio,则 Git 源代码控制提供程序扩展是免费的 ( http://visualstudiogallery.msdn.microsoft.com/63a7e40d-4d71-4fbb-a23b-d262124b8f4c ),并且在我对其进行测试时似乎会递归提交子模块。

然而,我在家里使用 VS Web Developer Express 进行开发,所以我不想依赖扩展(我也认为了解幕后发生的事情很好)。因此,我被迫弄清楚命令,并在下面添加了一些注释。

备注

如果您还没有完成,请通读一遍 http://git-scm.com/book/en/Git-Tools-Submodules .有很多警告,我会回到这个页面。如果你在没有阅读本文的情况下尝试使用子模块,你会很快让自己头疼。

我的方法遵循本教程,并添加了一些额外内容:http://blog.endpoint.com/2010/04/git-submodule-workflow.html

初始化 super 项目后(例如 git init && git remote add origin ... ),开始添加子模块,如下所示:

git submodule add git://github.com/you/extension1.git extension
git submodule init
git submodule update

检查您的 .gitmodules 文件是否反射(reflect)了此添加,例如
[submodule "extension1"]
        path = extension
        url = git://github.com/you/extension1.git

切换到您的子模块目录(即 cd extension )。跑:
git fetch #I use fetch here - maybe you can use pull?
git checkout -b somebranchname #See the Git-Tools-Submodules link above for an explanation of why you need to branch

我在这里对 README.txt 进行了更改,以便我可以提交它(也因此我会记录我在此提交中所做的事情),然后提交模块以应用分支(仍在子模块目录中):
git add .
git commit -a -m "Branching for extension submodule"

现在进入 super 项目(即 cd .. )。您还需要在此处提交(如果您查看我提到的 git 子模块页面,它解释了为什么这是必要的):
git status #will show you that your submodule has been modified
git commit -a -m "Commiting submodule changes from superproject"

现在,如果需要,我们可以像这样递归地推送我们的项目:
git push --recurse-submodules=on-demand

您需要对所有子模块执行一次上述步骤。

为所有子模块完成此操作并开始进行要提交和推送的更改后,您可以使用:
git submodule foreach 'git add .' #recursively add files in submodules

不幸的是,我还没有找到一种不使用 git-slave 之类的东西就可以递归提交的方法。 (有人吗?),因此您需要进入每个子模块目录并为您刚刚添加的文件运行常规提交。在 super 项目中:
git status #tells you that `extension` submodule has been modified
cd extension
git commit -a -m "Commiting extension changes in superproject edit session"

一旦子模块提交,您还需要(再次)提交 super 项目,因此:
cd ..
git add .
git commit -a -m "Altered extension submodule"
git status #should now show 'working directory clean', otherwise commit other submodules in the same manner

这可能会有点烦人(因为你最终提交了两次),但是一旦你意识到它实际上并没有那么糟糕(因为它迫使你检查你在每个项目中提交的内容)。只是我的意见 - 如果你已经将你的 super 项目的一些功能隔离到子模块中,它应该与你的项目的其余部分隔离开来(所以在不同的时间提交它们而烦人并不是世界末日)。

现在我们可以再推一次...
git push --recurse-submodules=on-demand

如果你随后进入你的子模块并再次尝试推送,你会发现它不会做任何事情,因为最新的提交已经被推送了。

super 项目的克隆(或使用远程源)也可能非常困惑 - 例如需要运行 git submodule update两次之后 git submodule init .阅读 http://git-scm.com/book/en/Git-Tools-Submodules 的“使用子模块克隆项目”部分.

克隆我的 super 项目时让我感到惊讶的是获取子模块的最新更改。见 Easy way pull latest of all submodules

我的变体是使用“开发”分支来 check out 子模块(但你可以随意调用它),然后在 super 项目中使用它:
git submodule foreach git pull origin development

当我设置它时,我也会切换到我想将我的更改推送到 checkout 的子模块的分支,如下所示:
cd extension
git checkout -b development #This will tell you this is a new branch, but I believe this means a new branch of the local git repository - this will get pushed to the 'development' branch
#Make your changes, commit etc.

我可以确认,当我按照上述步骤操作时,克隆/远程源项目(推送时)中子模块的更改出现在同一项目的其他克隆/远程源中(不要忘记最后一个子模块 pull 命令)。

我希望这对你有用。

关于git子模块提交/推/pull ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14233939/

相关文章:

git - 如何从当前分支中删除子模块

git - 如何使用子模块和 n 层 git 存储库策略

git - 如何从(用户)文本内容可靠地重新计算 blob sha1 哈希(或其他身份)并逃脱行尾/空白 hell ?

git - 有没有办法在执行 `git merge` 命令时绕过 post-merge git hook

git - 是否可以知道用户是否已从 git 存储库中 pull

git - "git remote add"究竟是做什么的?

git-submodules - Circleci:带有 AWS ECR orb 的私有(private) git 子模块

java - 禁止使用所有工具进行 SVN check out

git - 我如何 "git clone"一个 repo,包括它的子模块?

从接收后 Hook 更新 Git 子模块