在另一个 git 回购中维护 git 回购

这是我想要的:

REPO-A
/.git
/otherFiles
/REPO-B
/.git
/moreFiles

我希望能够推动 所有的 REPO-A 的内容到远程-A 和 只有 REPO-B 到远程-B。

可能吗?

124484 次浏览

听起来你想使用 Git 子模组

Git 使用子模块解决了这个问题。子模块允许您将 Git 存储库作为另一个 Git 存储库的子目录。这使您可以将另一个存储库克隆到项目中,并保持提交的独立性。

我一直使用符号链接来维护两个独立和不同的回购协议。

是的,您可以使用您所绘制的文件层次结构完全按照您的要求进行操作。回购 -B 将是独立的,并没有回购 -A 的知识。回购 -A 将跟踪所有的变化,在它自己的文件和回购 -B 的文件。

然而,我不建议这样做。每次更改文件并在回购 B 中提交时,必须在回购 A 中提交。在 Repo-B 中的分支会与 Repo-A 混淆,而在 Repo-A 中的分支会出现问题(移除文件夹等问题)。子模块绝对是正确的选择。

你可以通过使用“ git-subrepo”来实现你想要的(REPO-A 回购包含所有的文件,包括那些在文件夹 REPO-B 中的文件,而不仅仅是一个引用) :

Https://github.com/ingydotnet/git-subrepo

如果您的一些贡献者没有安装 subrepo 命令,那么它仍然可以工作; 他们将看到完整的文件夹结构,但不能提交对 subrepo 的更改。

您可以在父 A存储库中使用 .gitignore文件(忽略 B) ,但是首先要确保当前没有跟踪 B存储库: 在添加第二个 B存储库之前提交父 .gitignore

很多选择,最好的取决于你的目标:

  • 如果希望将父代保留为不同 应用程序的容器,并且其中一些最终可能成为 回购协议,那么只需使用裸 Git 将它们视为不同的回购协议(没有子模块就没有子回购协议)。不需要学习更多的 Git 特性。

  • 如果您希望将父目录作为不同 回购协议的“项目”,并且希望在管理不同合作者的访问时感到安全,那么对不同回购文件夹使用符号链接的解决方案是一个很好的选择。同样,不需要学习更多的 Git 特性。

说明:

如果其中一个应用程序成为一个回购,只有 git init那里,添加远程回购和忘记 git 教程,并花时间为应用程序。它只是工作,并且在父 repoB 中,提交对于其余的应用程序仍然是原子的,有时会有额外的提交,是的,但是你 不要需要为每个 repoB 提交父 A。您可以对两个回购协议应用不同的权限(尽管父级可以有回购协议代码,除非您使用。忽略 repoB)。

在我的情况下,我不想合并回购 A 和回购 B,所以回购内部的回购工作完全没问题。只要仔细更新 .gitignore的两个 repos。 并确保在使用 git 命令时保持在相应的目录中。

一些小贴士:

  1. 两个 repos都将独立运作,因此不能合并。
  2. 父回购将包含子文件夹和文件中的所有更改 除非加入其 .gitignore
  3. 儿童回购将包含所有 更改其子文件夹和文件中的内容,除非添加到其 .gitignore.
  4. 父母和子女的 .gitignore文件将采取行动 相互独立。 因此,例如,如果您想忽略子回购中的一个文件,但希望 要在父回购中推送它,只需将该文件添加到子回购的 .gitignore
  5. 如果两个 repos都需要合并,以上指南将被视为无效。因此,应该正确研究整体情况,在回购策略中运用回购策略。

谢谢你给出的所有有用的答案。如果需要,请随时更新我的答案。

还有一个办法可以解决这个问题。您可以将回购(子模块)放置为每个独立的存储库。并且可以在主回购中创建到子模块回购的软链接。

$ ls
$ main-repo submodule1 submodule2


$ ln -s submodule1 main-repo/submodule1
$ ln -s submodule2 main-repo/submodule2

一旦 main-repo 中的文件被列出,子模块 SoftLinks 就会被列出

$ ls main-repo/
$ other-files submodule1 submodule2

我发现最简单的方法是编辑 REPO-A 的. git/info/

$vim .git/info/exclude

它应该看起来像这样。刚刚添加了下面的最后一行。

# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
REPO-B/

对于那些在问题发布几年后来到这里的人来说:

git subtree就是你要找的:

$ git clone https://..../REPO-A
$ cd REPO-A


# Create a remote alias for the REPO-B, for convenience
$ git origin add REPO-B  https://..../REPO-B


# clone REPO-B
$ git subtree pull --prefix=REPO-B REPO-B main --squash


# Develop as you wish, do commits to both REPO-A and REPO-A/REPO-B
# All changes will be pushed to REPO-A but not to REPO-B


# When/if you want to merge things back to REPO-B
$ git subtree push --prefix=REPO-B REPO-B main


# When you want to pull new changes for REPO-B just repeat the pull
$ git subtree pull --prefix=REPO-B REPO-B main --squash

如果其他人克隆 REPO-A,他们也会得到 REPO-B 的内容(不像 git submodule) ,但他们不会有远程规范。对他们来说,REPO-A 就好像是一个单一的存储库。

你可以在以下网址阅读更多有关 git subtree的资料: https://www.atlassian.com/git/tutorials/git-subtree