Git: 如何按文件拆分分支(而不是按提交)?

Git: How can I split a branch by file (not by commit)?

底线:

我想将一个拉取请求拆分为两个具有不同文件子集的较小拉取请求。我不想按提交拆分,我想按文件拆分。

详情:

假设我有一个分支 branch_1(在 master 分支之外),我在其中修改了 2 个文件:file_1file_2。假设这些文件在一次或多次提交中一起修改(更改不能通过提交分开),并假设这些文件不以任何方式相互引用。

一段时间后,我想将 branch_1 合并到 master,但决定只有 file_1 可以合并。以后可能会合并file_2,所以放在新的分支上

所以我在 branch_1 的基础上创建了一个 branch_2branch_2 现在包含对 file_1file_2 的更改。没关系,因为 branch_2 无论如何都会在 branch_1 之后合并。

现在,我怎样才能很好地还原 branch_1 以删除对 file_2 的更改?

如果我继续 branch_1git checkout master file_2,它会起作用,但是:当我将 branch_1 合并到 master,然后将 master 合并到branch_2,则删除file_2。这根本不是我想要的!

基本上我想让它看起来好像 file_2branch_1 上根本不存在。

而不是从 branch_1 制作 branch_2。我将从 master 分支创建 branch_2 并根据需要进行更改以将其合并到主分支,然后将 branch_2 合并到 branch_1

这基本上是 git workflow(读到这里很不错)

所以,我得出的结论是 git 没有一个很好的机制,但是使用 PyCharm(可能还有一些其他工具)很容易做到。

要使用 pycharm 执行此操作,首先 git checkout master,然后 git checkout branch_3,然后在 Pycharm 的项目工具栏中右键单击项目的根文件夹然后转到 Git -> Compare with Branch、select branch_1,然后将要合并的 branch_1 中的 file_1 复制到当前代码中(branch_3).现在您可以从 branch_3master.

发起拉取请求

一种更方便的选择特定文件的方法:

  • master
  • 创建 branch_2
  • 使用 --no-commit 和 --squash
  • branch_1 合并到 branch_2
  • 还原要从新分支中排除的特定文件 (*)
  • 提交 branch_2
  • 中的剩余文件

现在您可以通过反向文件选择再次重复该过程,立即完全拆分两个分支,或者等到 branch_2 合并到 master 然后再合并 master 回到 branch_1,实际上 "fast-forwarding" 那些选定的文件,并将它们从原始 branch_1.

中排除

(*) 许多基于 UI 的 git 客户提供批量还原工具,使过程非常舒适

编辑:添加了 --squash 选项,否则来自 branch_1 的提交可能会在 master 中结束,只有其实际内容的一部分