git - 如何在 rebase 后解决冲突并推送它们

标签 git branch rebase

在我们的项目中,我们使用 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".

最佳答案

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

首先让我们定义一个“ cherry-pick ”。

假设您有一个尚未准备好升级的分支(例如,生产分支),但您也有一个错误。进一步假设,在一个开发分支上,有人已经修复了那个特定的错误,并且修复简单而干净,并且可以在生产代码中工作。 (例如,更改 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 的机制。

要进行 rebase ,git 只需要获取您的每个提交(* 以及中间的 X)并将它们挑选到 their-work 的末尾.也就是说,我们创建一个新的临时分支并开始复制提交:
... o - o - o - * - * - X - * - *   <-- your-work
              \
                o - Y - Z   <-- their-work
                          \
                            * - *   <-- temp-branch

在许多情况下,所有的提交都被简单地复制了一遍:没有冲突,所有的提交都干净利落。在这种情况下,git 然后执行最后一步:删除旧的分支标签 your-work ,并更改分支标签 temp-branchyour-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".


您开始手动解决,通过编辑冲突文件(使用 merge 工具而不是纯文本编辑器,但效果相同)和 git add最终文件。

接下来,运行 git rebase --continue .此时有两种可能性(假设您确实记得 git add 文件):
  • 与之前的版本相比,您仍然有一些更改( Z 如果这是第一个被复制的提交,或者您的 * 提交的副本之一,如果稍后;鉴于我在哪里绘制 X ,这将是其中之一副本)。
  • 您实际上已经在冲突解决期间删除了所有更改。也许提交 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 步骤的情况下),您应该使用 git rebase --skip。 .这告诉 git 忘记你之前的提交 X完全,然后继续挑选剩余的*提交。

    关于git - 如何在 rebase 后解决冲突并推送它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24639037/

    相关文章:

    svn - 提交到 SVN 分支也会影响主干

    mercurial - mercurial 如何确定分支处于非事件状态?

    git - 使用上游分支重新设置本地分支

    git - 运行 docker 容器非 root 用户权限被拒绝

    git - jenkins 构建完成后如何将更改推送到 github?

    build-automation - 源代码控制构建分支

    git - 在 git 中重新定位功能分支后 merge

    Git rebase --onto : atal: Needed a single revision

    git - cherry-pick 与 rebase

    git - 在远程机器上没有git的Git克隆