在我们的项目中,我们使用 git,我们在新分支中发布的每个功能以及在 codereview CTO 之后将其重新绑定到开发分支中。在我完成我的票后,CTO 说他不能重新调整我的更改,因为发生了冲突。我在本地机器上复制了它:
git clone ...
cd project1
git checkout my-branch
git rebase develop
...
Auto-merging admin/contest.html
CONFLICT (content): Merge conflict in admin/contest.html
Failed to merge in the changes.
Patch failed at 0019 contest: admin, dashboard, /contest
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
Run Code Online (Sandbox Code Playgroud)
好的,我解决了这个冲突,而不是添加了这个文件,但我不能继续 rebase 或 push 一些东西。解决此类冲突的最佳方法是什么?
更新
在我执行git rebase --continue 之后,我得到了:
Applying: $0 in admin/contest dropdown
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
Run Code Online (Sandbox Code Playgroud)
无论是否交互,rebase 都通过重复一个简单的挑选过程来工作。
首先让我们定义一个“樱桃选择”。
假设您有一个分支(例如,生产分支)尚未准备好进行一般升级,但您也有一个错误。进一步假设,在开发分支上,有人已经修复了那个特定的错误,并且修复简单而干净,并且可以在生产代码中使用。(例如,更改一行输入fileA和两行输入可以fileB解决问题,这可以在生产分支上完成。)
你可以:
$ git show 15fd3dc > /tmp/bug-fix
Run Code Online (Sandbox Code Playgroud)
查看更改并将补丁写入文件,然后手动复制补丁git add和git commit。或者您甚至可以执行上述操作,或者使用git format-patch,然后使用git apply或git am将补丁导入到 branch production。但它更容易:您可以简单地进入分支production并使用:
$ git cherry-pick 15fd3dc
Run Code Online (Sandbox Code Playgroud)
本质上,git 会自动提取修复并应用和提交它。换句话说,它复制一个提交。
现在让我们考虑一个rebase. 在这里,我们有这样的事情:
... o - o - o - * - * - X - * - * <-- your-work
\
o - Y - Z <-- their-work
Run Code Online (Sandbox Code Playgroud)
我已经标记了你的一个提交X和他们的两个Y和Z,只是为了以后我可以用它们做一些特别的事情。首先让我们看看 rebase 的机制。
要进行 rebase,git 只需要获取您的每个提交(*那些提交,以及X中间的提交)并将它们挑选到their-work. 也就是说,我们创建一个新的临时分支并开始复制提交:
... o - o - o - * - * - X - * - * <-- your-work
\
o - Y - Z <-- their-work
\
* - * <-- temp-branch
Run Code Online (Sandbox Code Playgroud)
在许多情况下,所有的提交都会简单地复制:没有冲突,并且您的所有提交都干净利落。在这种情况下,git 然后执行最后一步:擦除旧的分支标签your-work,并将分支标签更改temp-branch为your-work,以便您的(复制的)提交现在位于 commit 之上Z。
但是,在这种情况下,尝试选择 commit 时会发生冲突X。它与一个或两个提交冲突,Y并且Z:其他两个提交在您的更改所在的同一区域更改了某些内容X。
这是 rebase 停止并为您提供您看到的消息的地方:
Run Code Online (Sandbox Code Playgroud)When you have resolved this problem run "git rebase --continue". If you would prefer to skip this patch, instead run "git rebase --skip". To check out the original branch and stop rebasing run "git rebase --abort".
您可以通过编辑冲突文件(使用合并工具而不是纯文本编辑器,但效果相同)并编辑git add最终文件来开始手动解决。
接下来,您运行git rebase --continue. 此时有两种可能性(假设您确实git add根据需要记住了文件):
Z如果这是第一个被复制的提交,或者是您*提交的副本之一,如果稍后;考虑到我绘制的位置X,这将是这些副本之一)。Y有你所做的一半,然后 commitZ有剩下的,所以现在你的 commitX与这两个commit是多余的。您似乎遇到了案例 (2)。在情况 (1) 中,git rebase --continue只需继续复制其余的*提交,然后移动您的分支标签。然而,在情况 (2) 中,git rebase --continue抱怨:
Run Code Online (Sandbox Code Playgroud)No changes - did you forget to use 'git add'? If there is nothing left to stage, chances are that something else already introduced the same changes; you might want to skip this patch.
在这种情况下(并且仅当您没有忘记执行该git add步骤时),您应该,正如下一位告诉您的那样,使用git rebase --skip. 这告诉 gitX完全忘记您之前的提交,并继续挑选剩余的*提交。