shopsys/monorepo-tools

GitHub: shopsys/monorepo-tools

一组用于将多个独立 Git 仓库合并为 monorepo 并保持完整提交历史可逆向拆分的 Shell 脚本工具。

Stars: 698 | Forks: 65

# Shopsys Monorepo 工具 [![在 Awesome Monorepo 中提及](https://awesome.re/mentioned-badge.svg)](https://github.com/korfuri/awesome-monorepo) **此包用于拆分我们的 monorepo,我们原样与社区分享它。我们不打算进一步支持或开发它。请随意 fork 它并根据您的需要进行调整。** 用于从现有包构建和拆分单体代码库(monolithic repository)的工具。 您可以在 [Shopsys 平台博客](https://blog.shopsys.com/how-to-maintain-multiple-git-repositories-with-ease-61a5e17152e0)上阅读有关 monorepo 方法的优缺点。 我们创建这些脚本是因为我们找不到一个能保持子包 git 历史记录不变的工具。 您可能需要更新您的 `git`(已在 `2.16.1` 版本上测试过)。 此代码库由 [shopsys/shopsys](https://github.com/shopsys/shopsys) monorepo 维护,有关变更的信息请查看其 `CHANGELOG` 文件。 ## 快速开始 ### 1. 下载 首先下载此代码库,以便您可以使用这些工具(例如,下载到 `~/monorepo-tools`)。 ``` git clone https://github.com/shopsys/monorepo-tools ~/monorepo-tools ``` ### 2. 准备一个添加了 remotes 的空代码库 您必须为您的 monorepo 创建一个新的 git 代码库,并将所有现有的包作为 remotes 添加进去。 您可以添加任意数量的 remotes。 在这个示例中,我们将准备 3 个来自 github 的包,以便合并到 monorepo 中。 ``` git init git remote add main-repository http://github.com/vendor/main-repository.git git remote add package-alpha http://github.com/vendor/alpha.git git remote add package-beta http://github.com/vendor/beta.git git fetch --all --no-tags ``` ### 3. 构建 monorepo 然后您可以使用 `monorepo_build.sh` 来构建您的 monorepo。 只需列出您之前添加的所有 remotes 的名称作为参数即可。 您也可以选择通过提供 `:` 来指定代码库所在的目录,否则将使用 remote 名称。 该命令将重写所有相关代码库的历史记录,就好像它们是在不同的子目录中开发的一样。 只有 `master` 分支会被合并在一起,其他分支将仅从第一个包中保留,以避免可能的分支名冲突。 ``` ~/monorepo-tools/monorepo_build.sh \ main-repository package-alpha:packages/alpha package-beta:packages/beta ``` 这可能需要一段时间,具体取决于您的代码库大小。 现在您的 `master` 分支应该包含位于不同目录下的所有包。对于我们的示例来说,这意味着: - **main-repository/** - 包含代码库 _vendor/main-repository_ - **packages/** - **alpha/** - 包含代码库 _vendor/alpha_ - **beta/** - 包含代码库 _vendor/beta_ ### 4. 拆分回原始代码库 从现在起,您应该在这个代码库中开发所有的包。 当您完成更改并希望更新原始代码库时,请使用 `monorepo_split.sh`,参数与之前相同。 ``` ~/monorepo-tools/monorepo_split.sh \ main-repository package-alpha:packages/alpha package-beta:packages/beta ``` 这会将所有相关的更改推送到您所有的 remotes 中。 它将拆分并推送您的 `master` 分支,以及您在此代码库中添加的所有 tags。 其他分支不会被推送。 这可能又需要一段时间,具体取决于您的 monorepo 大小。 **_注意:_** _拆分后代码库中的 commit 应与原始代码库中的完全一致,从而保持 git 历史记录完好无损。_ _因此,如果您之前已经检出过原始的 `master` 分支,在拆分之后,您应该能够快进(fast-forward)到新版本。_ _唯一已知的例外是签名 commit(请注意,GitHub 默认会对其 Web UI 上进行的 commit 进行签名)。_ _如果您的原始代码库中包含签名 commit,拆分后的 commit 将不会被签名。_ _这将导致 `monorepo_split.sh` 无法将未签名的 commit 推送到 remote。_ _为了解决这个问题,您可以在脚本的 `git push` 调用中添加 [`--force` 标志](https://git-scm.com/docs/git-push#git-push--f),但如果您不确定自己在做什么,这可能会导致无法预料的后果。_ ### 将新包添加到 monorepo 中 当您拥有 monorepo 之后,您可能会发现在使用该 monorepo 一段时间后,有理由需要添加一个新的包。 在这种情况下,请不要使用 `monorepo_build.sh`,而是执行以下步骤: - 创建一个新的代码库,例如 _vendor/gamma_ - 在 monorepo 中添加 remote:`git remote add package-gamma http://github.com/vendor/gamma.git` - 在 monorepo 中创建一个新目录 **packages/gamma** - 添加代码并提交 - 对新包使用拆分工具 ~/monorepo-tools/monorepo_split.sh \ main-repository package-alpha:packages/alpha package-beta:packages/beta package-gamma:packages/gamma ## 参考 这只是包中所有工具的简要说明和使用方法。 获取详细信息请直接查看脚本并阅读注释。 ### [monorepo_build.sh](./monorepo_build.sh) 从指定的 remotes 构建 monorepo。这些 remotes 必须已经添加到您的代码库并已获取。 用法:`monorepo_build.sh [:] [:] ...` ### [monorepo_split.sh](./monorepo_split.sh) 拆分由 `monorepo_build.sh` 构建的 monorepo,并将所有 `master` 分支连同所有 tags 一起推送到指定的 remotes。 用法:`monorepo_split.sh [:] [:] ...` ### [monorepo_add.sh](./monorepo_add.sh) 将指定 remotes 中的代码库添加到现有的 monorepo 中。这些 remotes 必须已经添加到您的代码库并已获取。每个代码库只会添加 master 分支。 用法:`monorepo_add.sh [:] [:] ...` ### [rewrite_history_into.sh](./rewrite_history_into.sh) 重写 git 历史(甚至是 tags),以便将所有文件路径放置在特定的子目录中。 用法:`rewrite_history_into.sh []` ### [rewrite_history_from.sh](./rewrite_history_from.sh) 重写 git 历史(甚至是 tags),以便仅保留在某个子目录中进行过更改的 commit,并将所有文件路径重写为根目录路径。 用法:`rewrite_history_from.sh []` ### [original_refs_restore.sh](./original_refs_restore.sh) 在重写后恢复原始的 git 历史。 用法:`original_refs_restore.sh` ### [original_refs_wipe.sh](./original_refs_wipe.sh) 在重写后清除原始的 git 历史。 用法:`original_refs_wipe.sh` ### [load_branches_from_remote.sh](./load_branches_from_remote.sh) 删除所有本地分支,并创建指定 remote 的所有非远程跟踪分支。 用法:`load_branches_from_remote.sh ` ### [tag_refs_backup.sh](./tag_refs_backup.sh) 将 tag 引用备份到 `refs/original-tags/` 用法:`tag_refs_backup.sh` ### [tag_refs_move_to_original.sh](./tag_refs_move_to_original.sh) 将 tag 引用从 `refs/original-tags/` 移动到 `refs/original/` 用法:`tag_refs_move_to_original.sh` ## 支持 遇到困难或需要帮助时该怎么办? 最好的方式是加入我们的 [Slack](https://join.slack.com/t/shopsysframework/shared_invite/zt-11wx9au4g-e5pXei73UJydHRQ7nVApAQ)。 如果您想[报告问题](https://github.com/shopsys/shopsys/issues/new),请使用主要的 [Shopsys 代码库](https://github.com/shopsys/shopsys)。
标签:Cutter, Git, Shell脚本, SOC Prime, 代码仓库管理, 开发工具, 网络安全研究