编辑特定提交并重新应用后续提交

Edit a specific commit and reapply subsequent commits

我目前正在提交开源代码,提交的结构非常严格。我有三个提交,我们称它们为 A、B 和 C。重要的是要注意所有更改都在同一个文件中。

此外,我在所有三个提交中都收到了有关代码的反馈。是否可以放入暂存代码,例如,提交 B,编辑几行代码,重新提交,然后重新应用 C,而不会有太多麻烦?

我现在能想到的最好的方法是撤消所有三个提交,然后再次进行块暂存,这需要时间才能完美,因为一些代码就在附近。

无论你如何实现结果,当你完成时,你将不会使用原来的三个提交。如果允许A 100%单独留下,可以保留原来的A,但如果一定要碰B,就没有原来的B任何更多,因此也必须制作 C 的新副本。

到目前为止,这只是对事实的陈述,而不是关于如何实现您想要的目标的建议。获得您 想要的 的方法通常是使用 git rebase -i.

假设您现在在 feature 分支:

...--o--o--o--o   <-- main
               \
                A--B--C   <-- feature (HEAD)

你只需 运行 git rebase -i main 和 Git 提出一条指令 sheet 告诉 Git 将三个提交保持原样:

# instructions
pick <hash-of-A> <subject-of-A>
pick <hash-of-B> <subject-of-B>
pick <hash-of-C> <subject-of-C>

将第二个 pick 更改为 edit 并将指令 sheet 写回去并退出编辑器。1 Git现在将尝试直接复制提交 A 到位,这将成功。然后它将继续尝试将提交 B 复制到位,这也会成功,但现在它会在此复制的中间停止:

...--o--o--o--o   <-- main
               \
                A--B   <-- HEAD
                    \
                     C   <-- feature

您将处于 分离 HEAD 模式,HEAD 选择提交 B

您现在可以对要更改的文件进行更改,git add,运行 git commit --amend--amend 将让 Git 进行 new 提交——我们称它为 B'——使用提交 A 作为其父项,而不是提交 B。结果如下所示:

...--o--o--o--o   <-- main
               \
                A--B'  <-- HEAD
                 \
                  B--C   <-- feature

您现在可以 运行 git rebase --continue 使 Git 继续执行 pick C 命令。这将挑选提交 C,创建一个我们称之为 C' 的新提交。 这里可能会发生一些合并冲突,因为cherry-pick实际上是一个合并。如果是这样,您需要在提交 C' 之前修复它们并再次恢复。 但是,如果没有发生冲突,我们现在处于这种状态:

...--o--o--o--o   <-- main
               \
                A--B'-C'  <-- HEAD
                 \
                  B--C   <-- feature

这就完成了交互式 rebase 要执行的一组操作,所以它现在执行 any rebase 的最后一个技巧,即将分支名称拉到“这里"(无论 HEAD 现在在哪里)并重新附加您的 HEAD:

...--o--o--o--o   <-- main
               \
                A--B'-C'  <-- feature (HEAD)
                 \
                  B--C   [abandoned]

如果您想查看原始提交,它们仍然存在:您只需找到原始提交的哈希 ID C。这可用于:

  • ORIG_HEAD,只是很短的时间(因为 ORIG_HEAD 不断被覆盖);
  • HEAD 的 reflog,默认至少 30 天;和
  • 分支 feature 的 reflog,默认至少再保留 30 天。

reflog 条目具有数字后缀的名称:feature@{1}。您还可以使用时间相关的名称,例如 HEAD@{yesterday}。通常,如果某个名称在任何给定时间段内发生了多次更改,您会希望 运行 git reflog,而不是尝试猜测“昨天。10.am”之类的内容".


1如果你有一个长 运行ning 编辑器(emacs、atom 等的一些变体),使用任何它必须发回信号的方法等待 Git 这个文件现在完成并且 Git 应该恢复。

也许。

我偏执于Git,所以我总是走得很慢。

  1. 从提交 A(我假设是第一个提交)创建一个新分支
  2. Git修改最后一个commit,应该是A,可以更新评论了。你得到 A' - 它就像 A 但是一个新的提交,因为你改变了它
  3. Git cherry pick 提交 B 到新分支。 Git 修改最后一次提交,这将是 B'(它是精心挑选的,所以也是一个新的提交)
  4. Git cherry pick commit C 到新分支。你明白了。

这是一种安全的方法。您的原始提交仍在原始分支上。您的新分支具有相同的逻辑提交,但具有您想要的更改。

将新分支推送到 git 中心。与那个一起工作。