【问题标题】:How to fix conflicts after rebase and push them如何在变基后解决冲突并推送它们
【发布时间】:2014-08-29 14:44:57
【问题描述】:

在我们的项目中,我们使用 git,我们在新分支中发布的每个功能,在 codereview 之后,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".

好的,我解决了这个冲突,而不是添加了这个文件,但我无法继续 rebase 或推送一些东西。解决此类冲突的最佳方法是什么?

更新

在我做了 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".

【问题讨论】:

  • 运行git rebase --continue时出现什么问题?
  • @RohitJain,更新了问题。

标签: git branch rebase


【解决方案1】:

无论是否交互,rebase 都是通过重复一个简单的挑选过程来工作的。

首先让我们定义一个“樱桃采摘”。

假设您有一个尚未准备好升级的分支(例如,生产分支),但您也有一个错误。进一步假设,在一个开发分支上,有人已经修复了那个特定的错误,并且修复简单而干净,并且可以在生产代码中工作。 (例如,更改fileA 中的一行和fileB 中的两行即可解决问题,这可以在生产分支上完成。)

你可以:

$ git show 15fd3dc > /tmp/bug-fix

查看更改并将补丁写入文件,然后手动复制补丁和git addgit commit。或者您甚至可以执行上述操作,或者使用git format-patch,然后使用git applygit am 将补丁导入分支production。但它更容易:您可以简单地进入分支production 并使用:

$ git cherry-pick 15fd3dc

本质上,git 会自动提取修复并应用和提交它。换句话说,它复制一个提交。

现在让我们考虑一个rebase。这里我们有这样的东西:

... o - o - o - * - * - X - * - *   <-- your-work
              \
                o - Y - Z   <-- their-work

我已将您的一个提交标记为X,并将他们的两个提交标记为YZ,以便稍后我可以用它们来做一些特别的事情。首先让我们看看 rebase 的机制。

要进行变基,git 只需要获取您的每个提交(* 以及中间的 X)并将它们精选到 their-work 的末尾。也就是说,我们创建一个新的临时分支并开始复制提交:

... o - o - o - * - * - X - * - *   <-- your-work
              \
                o - Y - Z   <-- their-work
                          \
                            * - *   <-- temp-branch

在许多情况下,所有的提交都被简单地复制了一遍:没有冲突,所有的提交都干净利落。在这种情况下,git 然后执行最后一步:删除旧的分支标签your-work,并将分支标签temp-branch 更改为your-work,这样您的(复制的)提交现在位于提交Z 之上。

但是,在这种情况下,尝试选择提交 X 时发生了冲突。它与YZ 中的一个或两个提交冲突:其他两个提交在您对X 的更改所在的同一区域中更改了某些内容。

这是 rebase 停止并为您提供您看到的消息的地方:

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 adding 最终文件。

接下来,您运行git rebase --continue。此时有两种可能性(假设您确实记得根据需要git add 文件):

  1. 与上一个版本相比,您仍然有一些更改(Z,如果这是被复制的第一个提交,或者您的 * 提交的副本之一,如果稍后;考虑到我在哪里绘制 X,这将是其中一份)。
  2. 您实际上已在冲突解决期间删除了所有更改。也许提交 Y 完成了一半的操作,然后提交 Z 完成了其余部分,所以现在您的提交 X 与这两个提交是多余的。

您似乎遇到了案例 (2)。在情况 (1) 中,git rebase --continue 只是继续复制其余的 * 提交,然后移动您的分支标签。但是,在情况 (2) 中,git rebase --continue 抱怨:

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 步骤),您应该使用@987654364 @。这告诉 git 完全忘记您之前的提交 X,并继续挑选剩余的 * 提交。

【讨论】:

  • 感谢您的精彩回答!如果我 checkout --theirs 更改,它工作正常,继续变基我有几个文件要更改,最后变基没问题。如何做一个可以添加到我的分支的补丁以避免产品服务器上的冲突?
  • 我不明白最后一个问题。请注意,rebase 中的 checkout --theirs 实际上会为您提供 your 版本(签出的 --ours--theirs 标志与 git merge 相关;rebase 使用的樱桃选择,使用合并,但是在此过程中交换我们/他们的“方面”),所以它可能是正确的,但它可能会丢失他们实际所做的事情(在上面的 revs Y 和/或 Z 中,在我的插图中)。跨度>
猜你喜欢
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2011-01-29
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多