将文件移动到另一个分支

Move file to another branch

我在主分支上有一个文件,它应该在一个单独的分支中。它可能是一个未完成的文件,应该在一个单独的分支上以便稍后合并。但是现在我不能再改写main的历史了。

将文件移动到不同的分支并将其从 main 中删除的最简单方法是什么?


我尝试了以下方法

  1. 创建一个新的功能分支。该文件仍在功能中。
git switch -c feature
  1. 从主目录中删除文件。
rm file
git commit -a -m "move file to feature branch"
  1. 将功能变基到主要功能。
git rebase main feature

我希望文件看起来像是添加到功能中。相反,功能删除了文件并指向与 main 完全相同的提交。如何防止 rebase 删除文件?

你从一个错误的假设开始。这会导致您做错事:

  • Git 中的文件不在 分支上 ——无论如何都没有任何意义。

  • Git 中的文件存储在 提交 中。然后可以从 分支 访问提交:通常不止一个。

提交一旦做出,将永远冻结。您无法修复旧提交。不过,只要您是唯一一个 一些错误提交的人,您就可以停止使用它,通过创建您使用的新的和改进的提交来代替。这就是人们所说的“改写历史”。

当没有其他人有错误的提交时,这种重写效果很好:没有其他人知道你做了它,所以只要你从不回头后悔,一切都很好!当其他人 确实 有错误的提交(因为你用 git push 发送了他们),这会导致悲伤和痛苦,因为他们不知道停止使用旧的错误提交并切换到新的和改进的提交。1

在任何情况下,根据您的设置,需要执行以下操作:

  1. main 上进行新提交以删除文件。 (你已经这样做了,我只是在没有 git commit -a.2 的情况下重复它)

    git checkout main && git rm file && git commit -m ...
    
  2. 从更新的 main 创建功能分支。现在不需要变基了。

  3. 提取文件。它不在 main最新 提交中,但在 main较早的 提交中。因为你有 git switch,所以你有 git restore,这是从旧提交中获取文件的更新更好的方法:

    git restore --source=main~1 -SW file
    

    -SW 告诉 Git 将文件放在暂存区和工作树中。 git status 现在会告诉您该文件是新的并且“暂存以供提交”(因为它在暂存区中,形式为 Git 需要它用于将来的提交,并且副本 中,暂存区与工作树副本匹配)。

    您现在已准备好 运行 git commitfeature 上创建包含此文件(以及所有其他文件)的新提交。

  4. 运行 git commit 进行新的提交。这将导致 feature 上的单个提交不在 main 上。这个新提交的父级将是 main 顶端的提交,其中文件被删除; that 提交的父项是 main 之前(在步骤 1 之前)的提交,它有额外的文件。

根据谁有哪些提交,以及可能拥有这些提交的其他人是否准备好重写历史记录(参见脚注 1),您可以使用替代方法来创建从未发生原始错误的提交。但是这个特定的序列实际上说:哎呀,主上还不需要这个文件然后我们在功能上,让我们现在把文件带回来.


1如果他们知道这样做,就会导致新的和改进的历史重写规则。旧规则是“只有在没有人知道的情况下才做”;新的改进规则,关于用新的改进的提交替换旧的提交,是“只有当每个人都同意要完成并且知道如何处理时才这样做”。

2我认为 git commit -a 是个坏习惯。这是暂时避开了解 Git 的索引 AKA 临时区域的好方法。但是 Git 有这种方式可以伸出手并用它的索引拍打你,就像 Monty Python sketch,所以明智的做法是让步并了解它。