我有一个我在其中工作的存储库。那里有一个文件夹,我把所有我想开源的东西都放在那里,这样它就与私有部分分开了。有没有办法让 git 自动将提交到该文件夹的任何内容推送到 github 存储库,而我不必记住每次都将新更改的文件推送到那里?我想将整个存储库推送到另一个 github 位置。
2 回答
如果您有一个单独的存储库,其中部分旨在公开而部分旨在私有,那么您需要从根本上更改存储库设置中的某些内容。git 跟踪完整的存储库,因此您可以将存储库设为公共或私有,但不能部分地这样做和部分地。
如果你有一个带有“公共”文件的仓库和一个带有“私有”文件的仓库,你可以在“公共”仓库中添加一个 git 钩子来自动推送提交,并且只保留私有仓库的私有。
但是,您正在写的是您有一个包含“公共”和“私有”文件的单一存储库,因此您需要以某种方式将其拆分为“公共”和“私有”文件。
您有多种选择来解决这种情况:
将“public”文件夹拆分到它自己的存储库中,您将推送到 github。这将稍微改写“公共”文件夹的历史。我将在下面更详细地概述这一点。
创建一个只涉及“公共”文件夹的分支,并且只发布该分支。这在“意外推送,即发布,私人的东西”的意义上是有风险的,如果你有任何涉及“公共”和“私人”文件的提交,完全不可能或至少很难做到,所以我建议不要这样做选项,并且不会写更多关于它的内容。
要将“public”文件夹拆分到自己的存储库中,请从“combined”分支创建一个新的“public”分支,并使用git filter-branch
它使新的“public”分支仅包含“public”文件夹中的内容。“示例”部分显示了正确的 --subdirectory-filter 示例)。然后,您将拥有旧的“组合”分支,其中包含“公共”文件夹和私有内容,以及仅包含“公共”文件夹的新“公共”分支。
请注意,例如,新“公共”分支中的提交消息仍可能包含“私人”信息。因此,您应该浏览所有提交消息,扫描它们以获取私人信息,并可能删除该私人信息,例如使用git rebase -i
.
更新: [仅“公共”分支的后续推送可能不会传输任何其他信息,因此可能不需要此 repo 清理。]如果您需要进行任何编辑,您将需要删除旧的未编辑使用
git gc
(可能使用--prune=0
and--aggressive
选项 - 但我无法找到包含更多信息的 SO 答案)。
现在您的“公共”分支已准备好发布。为了确保它只包含“公共”信息,您可以将其推送到一个新的空本地裸仓库中,检查其中的内容以验证所有 ref 都没有私有信息。满意后,可以将“public”分支推送到 github 上一个新的空仓库。然后,github 上的 repo 将只包含“public”分支,您可能应该在 github repo 上将其命名为“master”。
带有“组合”分支的本地存储库仍然直接包含公共和私有信息,并且与新的“公共”github 存储库没有任何联系。
现在您可以重写“组合”分支的历史以仅包含非公共位,但这会牺牲所有历史期间“公共”和“私有”文件状态之间的所有连接,因此旧东西的可重复构建会变得接近不可能。因此,我建议单独保留“组合”分支的历史记录,并在新提交中从中删除“公共”文件夹。
如果您的私有文件和公共文件之间的集成非常紧密并且依赖于版本,您可以使用git submodule
将来自 github 的“公共”存储库的特定版本添加到您的私有存储库中。一个像以前的“公共”文件夹一样命名的新子模块文件夹将最大限度地减少对您私人内容的更改,因为所有“公共”文件都将位于它们的旧路径中。请注意,当某些内容被推送到 github 时,子模块文件夹不会自动更新。您可以通过向本地子模块文件夹添加一个 git 挂钩来解决此问题,该文件夹将更新“组合”存储库中的子模块信息。
如果您的私有文件和公共文件之间的集成更加松散,您还可以将公共文件视为任何外部第三方项目,并以其他任何人集成它的方式将其集成到您的私有文件中,即像任何外部项目一样您的“私有”软件所依赖的软件。
Use a githook to push on commit.