我应该使用什么工具将git提交拆分成多个提交?

29

我在一个项目中编写了涵盖数千行修改的功能,现在它们都汇聚在一个大的提交中(我已经压缩了正在进行中的提交)。现在,为了更容易地进行审查/可能需要多个PR,我想将更改拆分为多个提交。

一些文件包含多个更改,应该分别放入不同的提交中,因此我正在寻找一个所见即所得(WYSIWYG)编辑器,使用三窗格视图,允许我将某些行移动到中间提交,同时查看以前和未来的版本(+一些手动更改)。我在开发中使用 IntelliJ IDEA,所以我想象着类似于冲突解决对话框的东西。

我可以切换到不同的分支/标签,然后进行 Git -> 比较分支(并从那里抓取更改),但我正在寻找更方便的方法。

虽然这可能被标记为超出主题/具有个人观点,但我相信提供中立的不同工作流建议可能是有价值的。

4个回答

55

我在 IntelliJ 中使用以下工作流程:

  • 打开 git 日志窗口或使用快捷键 Alt + 9
  • 右键单击要拆分的提交 → 从此处交互式地重写基础(Interactively Rebase from Here)
  • 右键单击要拆分的提交 → 停止编辑 或使用快捷键 Alt + E
  • 开始重新贴基
  • 在带有黄色标签 ️! 的 git 日志中右键单击当前提交 → 撤消提交... 或在终端中执行 git reset HEAD~1
  • Ctrl + K 选择并提交相应消息的更改。必要时重复该过程,直到所有更改都提交。
  • 在右下角单击:Rebase Stopped for Editing → 继续

5
这些指令应该被添加到官方文档的 https://www.jetbrains.com/help/idea/edit-project-history.html 页面上。 - huyz

4

不确定是否有工具可以做到这一点,但是根据Git文档所述,您可以使用内置的rebase函数来拆分提交。例如:

git rebase -i
...
pick abc1234 the commit I wanna keep
edit 5904fjl THE COMMIT I WANT TO SPLIT
pick alkj022 my latest commit to keep

之后运行git reset HEAD^,然后您可以手动将更改分成提交。您可以使用git add --patch更轻松地将文件内的更改拆分为提交。或者,如果您的Intellij IDE具有良好的git GUI,则可以使用该工具。至少在我的经验中,拆分必须从命令行完成。


1
通常情况下,git gui 也很有帮助。只有当 git gui 拒绝索引一行时,我才使用 git add -i - Laurent G
“git add --patch” 看起来非常接近,但它不能轻松地查看块之外的内容。 - Radim Vansa
谢谢,这对我非常有效。在Intellij中,我启动了“交互式变基”,用“停止编辑”标记了我想要拆分的提交,然后每次Intellij停下来给我时间编辑提交时,我都去命令行调用git reset HEAD^,并使用git-gui将它们提交为我喜欢的方式。当我完成拆分单个提交后,我回到Intellij并按“继续”。 - Martin Pecka

1

我在PyCharm / IntelliJ中找到了一个简单的方法。

该想法在于反转您要提取的更改两次(因此它类似于摄影领域中的“负”和“正”),然后将第一个反转的提交与“公共最新提交”合并,以便从该提交中删除更改。

下面的解释可能看起来很复杂,但实际上只需要点击几下即可从提交中提取一些更改:

  • 首先,使用Alt+9打开git面板
  • 在左下角面板中选择当前分支的最新提交。 在右下角面板中,您将看到已修改此提交中的文件。

此时,您的历史记录是这样的:

commit_3
   ^ 
commit_2
   ^ 
commit_1
  • 按住 Shift 键选择您想要在单独提交中提取的文件
  • 右键单击 / 撤销所选更改
  • 将这些更改提交到名为例如 temporary_reverted_commit 的提交中
git add -u :/
git commit -m "temporary_reverted_commit"

此时你的历史记录是这样的:

temporary_reverted_commit
   ^ 
commit_3
   ^ 
commit_2
   ^ 
commit_1
  • 然后在底部侧面板上右键单击该新提交,点击“还原提交”,并将提交命名为your_extracted_changes

此时您的历史记录如下:

your_extracted_changes
   ^ 
temporary_reverted_commit
   ^ 
commit_3
   ^ 
commit_2
   ^ 
commit_1

现在将temporary_reverted_commit合并到commit_3中:在temporary_reverted_commit提交上放置fixup,以便将其与commit_3压缩,并保存并退出重新基础接口。
git rebase -i origin/dev

your_extracted_changes
   ^ 
commit_3
   ^ 
commit_2
   ^ 
commit_1

0

如果你正在工作的提交树的顶部,那么简单地对你之前的提交进行混合重置,然后将你想要的更改分别暂存并逐个提交它们可能是一个不错的选择。

所以,步骤如下:

  1. 重置到当前分支上倒数第二个提交:
git reset --mixed
  1. 在第一次提交中添加您想要的更改 - 使用--interactive或您喜欢的git GUI。
git add --interactive
  1. 提交所添加的更改
git commit -m "first commit"

重复步骤2和3直到您提交所有更改。

请提供Git CLI的正确命令。 - Semnodime

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接