将一个分支折叠成一个提交。

3
基本上,我一直在开发一个功能,但当我将该功能推回主要代码库进行代码审查时,他们希望整个功能作为一个提交进行推送。我通常使用git rebase -i来完成这项工作,并将除第一个提交之外的所有内容设置为squash,第一个提交设置为edit。每次发生冲突时,我都会粘贴最新的文件。
我不想在冲突期间粘贴各种文件。我希望能够轻松地保留最新的文件并删除它们如何生成的历史记录。
编辑:
我正在寻找一个Git命令,它相当于这个bash脚本:
for file in `git diff --name-only master foo`
git checkout foo $file
2个回答

14

使用压缩合并

您需要的是一个压缩合并。这将把所有更改合并到工作目录中,但实际提交的任务由您来完成。例如:

git checkout foo
git rebase -i master
git checkout master
git merge --squash foo
git commit -m 'Squashed commit.'

在变基分支中的所有更改将作为一个单独的提交与一个提交消息一起进行。只要您在 foo 分支中解决了任何与重演相关的冲突,当您合并到主分支时,合并应该不会产生冲突。


1
根据我的理解,在这种特殊情况下,交互式重置不是必需的,也就是说,在第二个命令中使用rebase -i是有歧义的。 - Eugene Sajine
1
如果在合并之前不将主题分支变基到主分支上,那么很可能会出现冲突。在我看来,你最好在主题分支上处理潜在的冲突,而不是在主分支上处理,但你的情况可能有所不同。 - Todd A. Jacobs
我没有表达清楚,抱歉。我的意思是rebase的交互部分并不是必要的。也就是说,“git rebase master”应该足够了,甚至更好的是一个简写的“git rebase master foo”,它等同于“git checkout foo; git rebase master”。 - Eugene Sajine
无论是执行 git rebase master 还是 git rebase -i master,我都会遇到冲突。我只想要最新的代码,不关心中间过程。 - kporter
我发现在这样做之后,对于我的特性分支的任何后续变基,我必须像这里描述的那样使用git rebase --onto ... - harmic

0

如果你使用 git rebase -i '@{upstream}'(按照所述的方式压缩)可能会出现真正需要解决的冲突。如果你只是复制粘贴更改,那么你可能会撤销远程上自你开始功能开发以来发生的更改,从而导致功能退化。

如果你知道这对于单个文件是安全的,那么在变基过程中,你总是可以执行 git checkout --theirs $file 来避免复制粘贴,尽管这将替换整个文件,可能会替换自动合并的块;在这种情况下,“theirs”是正在应用的更改集,即你的更改。

如果你确定这总是适用的,那么你可以设置合并策略,例如 git rebase -m -s merge-recursive -X theirs -i '@{upstream}'

注意:这仅适用于 Git 的最近版本中的交互式变基。

在我看来,更简单的方法是执行git rebase -i\git merge-base HEAD '@{upstream}'\(按照所述压缩),将分支有效地重新定位到自身。结果将没有合并冲突需要在此步骤中解决,因为更改是按照它们创建的顺序应用于相同的代码。然后,您可以使用git rebase '@{upstream}',此时您将以正常方式解决与上游的冲突。
更简单的方法是,假设您能够很好地管理文件,则可以执行git reset\git merge-base HEAD '@{upstream}'\。此时,您只需将更改的文件添加到阶段,并进行新的提交,该提交可以像前一段所述那样重新定位。

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