对Git子模块进行非子模块化,将所有代码带回核心存储库的最佳实践是什么?


当前回答

Git rm——缓存了the_submodule_path 从.gitmodules文件中删除子模块部分,或者如果它是唯一的子模块,则删除该文件。 执行一个提交"removed submodule xyz" Git添加了_submodule_path 另一次提交“添加xyz的代码库”

我还没找到更简单的方法。你可以通过git commit -a把3-5压缩到一个步骤中——这取决于你的喜好。

其他回答

我找到的最佳答案是:

http://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html

这篇文章很好地解释了这个过程。

Git rm——缓存了the_submodule_path 从.gitmodules文件中删除子模块部分,或者如果它是唯一的子模块,则删除该文件。 执行一个提交"removed submodule xyz" Git添加了_submodule_path 另一次提交“添加xyz的代码库”

我还没找到更简单的方法。你可以通过git commit -a把3-5压缩到一个步骤中——这取决于你的喜好。

这里有很多答案,但它们似乎都过于复杂,可能不能达到你想要的效果。我相信大多数人都想保留他们的历史。

在这个例子中,主repo将是git@site.com:main/main.git,子模块repo将是git@site.com:main/child.git。这假设子模块位于父repo的根目录中。根据需要调整说明书。

首先克隆父repo并删除旧的子模块。

git clone git@site.com:main/main.git
git submodule deinit child
git rm child
git add --all
git commit -m "remove child submodule"

现在我们将把子回购添加到主回购的上游。

git remote add upstream git@site.com:main/child.git
git fetch upstream
git checkout -b merge-prep upstream/master

下一步假设您希望将merge-prep分支上的文件移动到与上面的子模块相同的位置,尽管您可以通过更改文件路径轻松更改位置。

mkdir child

将除.git文件夹外的所有文件夹和文件移动到子文件夹中。

git add --all
git commit -m "merge prep"

现在您可以简单地将文件合并回主分支。

git checkout master
git merge merge-prep # --allow-unrelated-histories merge-prep flag may be required 

在运行git push之前,环顾四周,确保一切看起来都很好

你现在必须记住的一件事是,git日志默认情况下不会跟踪移动的文件,但是通过运行git log——follow filename,你可以看到你文件的完整历史。

从git 1.8.5(2013年11月)开始(没有保留子模块的历史):

mv yoursubmodule yoursubmodule_tmp
git submodule deinit yourSubmodule
git rm yourSubmodule
mv yoursubmodule_tmp yoursubmodule
git add yoursubmodule

将:

注销和卸载(即删除子模块的内容)(deinit,因此mv先), 清理你的。gitmodules (rm), 并删除父repo (rm)索引中表示子模块SHA1的特殊条目。

一旦子模块的删除完成(deinit和git rm),您可以重命名文件夹为原来的名称,并将其作为常规文件夹添加到git repo中。

注意:如果子模块是由旧Git(< 1.8)创建的,您可能需要删除子模块本身中嵌套的.git文件夹,正如Simon East所评论的那样


如果你需要保留子模块的历史,请参阅jsears的答案,它使用git filter-branch。

如果你只是想把你的子模块代码放到主库中,你只需要删除子模块,并将文件重新添加到主库中:

git rm --cached submodule_path # delete reference to submodule HEAD (no trailing slash)
git rm .gitmodules             # if you have more than one submodules,
                                # you need to edit this file instead of deleting!
rm -rf submodule_path/.git     # make sure you have backup!!
git add submodule_path         # will add files instead of commit reference
git commit -m "remove submodule"

如果还想保留子模块的历史,可以使用一个小技巧:将子模块“合并”到主存储库中,这样结果将与以前相同,只是子模块文件现在位于主存储库中。

在主模块中,你需要做以下工作:

# Fetch the submodule commits into the main repository
git remote add submodule_origin git://url/to/submodule/origin
git fetch submodule_origin

# Start a fake merge (won't change any files, won't commit anything)
git merge -s ours --no-commit submodule_origin/master

# Do the same as in the first solution
git rm --cached submodule_path # delete reference to submodule HEAD
git rm .gitmodules             # if you have more than one submodules,
                                # you need to edit this file instead of deleting!
rm -rf submodule_path/.git     # make sure you have backup!!
git add submodule_path         # will add files instead of commit reference

# Commit and cleanup
git commit -m "removed submodule"
git remote rm submodule_origin

生成的存储库看起来有点奇怪:将会有多个初始提交。但是它不会给Git带来任何问题。

第二种解决方案的一大优点是,您仍然可以在最初位于子模块中的文件上运行git blame或git log。实际上,这里所发生的只是在一个存储库中重命名了许多文件,Git应该自动检测到这一点。如果你仍然有git日志的问题,尝试一些选项(例如,——follow, -M, -C),它们可以更好地重命名和复制检测。