为什么在解决 rebase 冲突时显示之前提交的代码?

Why code from previous commit is showing while resolving rebase conflicts?

我已经在功能分支上创建了一个包含 5 次提交的拉取请求,现在我的上游已经领先于大约 10 次提交,我想重新定位我的功能分支,但是在重新定位时,由于合并冲突而失败了!当我检查冲突时,代码类似于第一次提交代码!,我可以跳过这个(rebase --skip)吗?并且在以后与最新代码合并提交时再次出现冲突?如果 rebase 完成并且我搞砸了什么,我也可以在完成 rebase 后执行 rebase --abort 吗?

我不明白为什么我在合并第一次提交时需要解决相同的冲突!

注意:我已经在 PR 中合并了第一个提交,后来又做了两个提交并合并,然后再次添加了 2 个提交,这次我尝试变基而不是合并!

更新 1:我试图通过解决冲突来变基,但我得到 this error,现在我不确定是否可以删除它!请帮忙!

TL;DR:这对你的情况来说实际上很正常

因为 rebase 包括 复制 提交,并且您正在将提交复制到一个新的且略有不同的源库中,这些类型的冲突,并且必须 re-resolve他们,很正常。

您可以考虑使用 Git 的 rerere.enabled 功能(参见 Are there any downsides to enabling git rerere?)来自动执行其中的一些操作。我没试过。

使用您的 link—https://github.com/mesonbuild/meson/pull/3277—我能够克隆存储库并找到补丁:

$ git clone https://github.com/mesonbuild/meson
Cloning into 'meson'...
remote: Counting objects: 33400, done.
[snip]
$ cd meson/
$ git fetch origin refs/pull/3277/head:refs/heads/feature
remote: Counting objects: 31, done.
remote: Total 31 (delta 20), reused 20 (delta 20), pack-reused 11
[snip]

(这为我创建了一个名为 feature 的本地 b运行ch,然后我检查了它)。现在让我们看一下提交图。这太长了,所以我要剪掉一些——但不是全部——不相关的部分,用一系列的点代替它们:

$ git log --decorate --oneline --graph master feature
* 9b2e533d (origin/master, origin/HEAD, master) Always build parser objects anew to avoid leaking old data.
* 977acc94 Do not leave open file handlers, use context manager to clean them up
* 8efd9400 pkgconfig generator: Add required version
*   f6f07840 Merge pull request #2976 from dzabraev/fix-reversed-order
|\  
| * ea6e9298 keep include paths order
............
* | c4192a04 Support data types larger than 128 bytes
| | * 6a3db989 (HEAD -> feature) Fixing typo closes #2865
| | * 8fe1adcb Fixing typo closes #2865
| | *   d3554ceb Fixing PR changes closes #2865
| | |\  
| |_|/  
|/| |   
* | | 3e48d476 Squash target_type warning for jar targets
................
* | |   12bac512 Fix b_ndebug=if-release silently not working
|\ \ \  
| * | | 6910f604 Disable b_ndebug tests on MSVC
................
| * | | 39a3bdb4 Add tests for b_ndebug=if-release and buildtype default options
* | | | 30827b56 Do not install configure_file output if install_dir is empty. Closes #3270.
|/ / /  
| | * 21e7e1fe PR review changes closes #2865
| | * 531120e8 fix2865
| |/  
|/|   
* | dd614015 Open mesontest logfiles in utf-8 mode
............

现在,这里的五个 "most interesting" 提交是可以从 feature(从您的拉取请求)而不是从 master:

访问的提交
$ git log --no-decorate --oneline master..feature
6a3db989 Fixing typo closes #2865
8fe1adcb Fixing typo closes #2865
d3554ceb Fixing PR changes closes #2865
21e7e1fe PR review changes closes #2865
531120e8 fix2865

这通过哈希 ID 标识提交。查看上面的图表输出,我们可以看到 531120e821e7e1fe 是普通提交,但是 d3554ceb 是一个 merge 有两个父项的提交:第一个是21e7e1fe(你自己的作品),第二个是3e48d476 Squash target_type warning for jar targets.

any git rebase 的一个问题是它通过复制提交来工作。1 从任何有用的意义上来说,它都是,不可能正确复制合并提交,并且 rebase 甚至 try。相反,它只是完全放弃了合并。

因此,如果我们现在 运行 git rebase -i master2 而在 b运行ch feature,我们会得到在我们的编辑器会话中,一组四个而不是五个 pick 命令:

$ git rebase -i master
pick 531120e8 fix2865
pick 21e7e1fe PR review changes closes #2865
pick 8fe1adcb Fixing typo closes #2865
pick 6a3db989 Fixing typo closes #2865

# Rebase 9b2e533d..6a3db989 onto 9b2e533d (4 commands)
[snip rest of instructions]

请注意,此处未列出 d3554ceb。 Git 不会尝试复制合并提交。

当您进行合并时,您解决了 "after" 旧提交中发生的合并冲突。由于 rebase 不会 保持 合并,而且,您的新副本将到达 "after" 发生冲突的地方,您将不得不解决相同的冲突又一次,可能不止一次。


1Rebase 复制提交使用 git cherry-pick,没有任何 -m 参数,或 git apply -3 格式化补丁。

2我们在这里想要的是在提交 9b2e533d 上变基。在我的克隆中,名称 masterorigin/master 都指向此提交哈希。我也可以 运行 git rebase -i 9b2e533d.


手动解决冲突

如果你只是让这个 rebase 运行,它会立即遇到合并冲突:

Auto-merging run_unittests.py
CONFLICT (content): Merge conflict in run_unittests.py
Auto-merging mesonbuild/build.py
error: could not apply 531120e8... fix2865

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Could not apply 531120e8... fix2865
$ git status
[snip]
        both modified:   run_unittests.py

我使用与合并时相同的方法自己手动解决了它,运行 git rebase --continue,很快又遇到了问题:

$ git add run_unittests.py
$ git rebase --continue
[snip editor session]
[detached HEAD bbd74944] fix2865
 Author: chitranjali <chitranjali189@gmail.com>
 6 files changed, 51 insertions(+)
 create mode 100644 test cases/unit/25 shared_mod linking/installed_files.txt
 create mode 100644 test cases/unit/25 shared_mod linking/libfile.c
 create mode 100644 test cases/unit/25 shared_mod linking/main.c
 create mode 100644 test cases/unit/25 shared_mod linking/meson.build
Removing test cases/unit/25 shared_mod linking/installed_files.txt
Auto-merging run_unittests.py
CONFLICT (content): Merge conflict in run_unittests.py
Auto-merging mesonbuild/build.py
error: could not apply 21e7e1fe... PR review changes closes #2865

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Could not apply 21e7e1fe... PR review changes closes #2865

这个合并冲突有点不同,但相关,并且再次出现在 run_unittests.py 中——基本上,Git 无法 cherry-pick 原始提交,因为它的周围上下文太不同的。 (通过在此 class 的最后两个单元测试之后而不是之前添加新测试,可能有助于也可能不会解决先前的冲突。)

再次修复:

$ git add run_unittests.py
$ git rebase --continue
[snip editor session]

我们又遇到了一个合并冲突:

[detached HEAD 08b4eefc] PR review changes closes #2865
 Author: chitranjali <chitranjali189@gmail.com>
 4 files changed, 10 insertions(+), 11 deletions(-)
 delete mode 100644 test cases/unit/25 shared_mod linking/installed_files.txt
Auto-merging run_unittests.py
CONFLICT (content): Merge conflict in run_unittests.py
error: could not apply 8fe1adcb... Fixing typo closes #2865

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Could not apply 8fe1adcb... Fixing typo closes #2865

这是因为提交 8fe1adcb 的父级是您自己的合并提交 d3554ceb,Git 已跳过,所以它正在比较 d3554ceb8fe1adcb 来查看要复制的内容,同时将 d3554cebHEAD(由前一个 cherry-pick 刚刚构建的提交)进行比较,以查看应该保留的内容。这里有一个小的白色 space 差异会影响自动分辨率。

手动修复该问题以支持正确的白色 space 并继续,我得到:

$ git add run_unittests.py
$ git rebase --continue
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Otherwise, please use 'git reset'
interactive rebase in progress; onto 9b2e533d
Last commands done (4 commands done):
   pick 8fe1adcb Fixing typo closes #2865
   pick 6a3db989 Fixing typo closes #2865
No commands remaining.
You are currently rebasing branch 'feature' on '9b2e533d'.

nothing to commit, working tree clean
Could not apply 6a3db989... Fixing typo closes #2865

忽略相当奇怪的(虽然技术上还可以)指示,我 运行:

$ git rebase --continue
Successfully rebased and updated refs/heads/feature.

这可能是正确的(我对这个软件一无所知,也没有测试过任何这些版本)。

没有 --interactive

的变基

这真的很相似,只是互动少了很多。 Git 使用 git format-patch 将四个(不是五个)提交中的每一个都变成补丁,然后使用 git am --3way 应用每个提交。第一个运行陷入合并冲突,这次我手动解决了,把新添加的测试函数放在最后:

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: fix2865
Using index info to reconstruct a base tree...
M   mesonbuild/build.py
M   run_unittests.py
Falling back to patching base and 3-way merge...
Auto-merging run_unittests.py
CONFLICT (content): Merge conflict in run_unittests.py
Auto-merging mesonbuild/build.py
error: Failed to merge in the changes.
Patch failed at 0001 fix2865
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

[snip editor session on run_unittests.py]
$ git add run_unittests.py
$ git rebase --continue
Applying: fix2865
Applying: PR review changes closes #2865
Using index info to reconstruct a base tree...
M   mesonbuild/build.py
M   run_unittests.py
.git/rebase-apply/patch:10: trailing whitespace.
                mlog.warning('''target links against shared modules. This is not 
.git/rebase-apply/patch:36: trailing whitespace.
        msg = ('''WARNING: target links against shared modules. This is not 
warning: 2 lines add whitespace errors.
Falling back to patching base and 3-way merge...
Removing test cases/unit/25 shared_mod linking/installed_files.txt
Auto-merging run_unittests.py
Auto-merging mesonbuild/build.py
Applying: Fixing typo closes #2865
Using index info to reconstruct a base tree...
M   run_unittests.py
Falling back to patching base and 3-way merge...
Auto-merging run_unittests.py
CONFLICT (content): Merge conflict in run_unittests.py
error: Failed to merge in the changes.
Patch failed at 0003 Fixing typo closes #2865
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

[snip editor session again]
$ git add run_unittests.py
$ git rebase --continue
Applying: Fixing typo closes #2865
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 prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

事实证明不再需要此特定修复程序,因此跳过它是正确的:

$ git rebase --skip
Applying: Fixing typo closes #2865
Using index info to reconstruct a base tree...
M   run_unittests.py
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.

现在变基完成了。