git rebase -i -autosquash conflict

牧云@^-^@ 提交于 2019-12-03 08:32:55

When you do a --fixup, you are applying a patch out of order, so the context has disappeared. In the first case, your patches are applied as follows:

  1. Insert 1 on line 1
  2. Insert This is\naBUG on lines 2, 3 after 1
  3. Delete line a BUG, on line 4, after This is, replace with NOT a BUG
  4. Insert 2 on line 2 after 1, before This is

Steps 2, 3 are pretty clear-cut. Even though the line number is different than expected in step 3, the context makes it clear. In the second case,

  1. Insert 1 on line 1
  2. Insert This is a BUG on line 2 after 1
  3. Delete line This is a BUG, replace with This is NOT a BUG on line 3 after line 2
  4. Insert 2 on line 2, after 1, before This is a BUG

In this case, patch #3 is impossible because This is a BUG does not appear on line 3 and the line before it is not 2. Git does not assume that line 2 is the correct one in this case because of the missing context.

The easiest way to fix this problem is to rearrange the order of the rebase to reflect what you are actually doing. Instead of the original order:

pick 5ef0459 Added line 2 with BUG
fixup ed5cd81 fixup! Added line 2 with BUG
pick 20e104e Insert 2 --> second line

switch the last two elements to give the patch the context it needs:

pick 5ef0459 Added line 2 with BUG
pick 20e104e Insert 2 --> second line
fixup ed5cd81 fixup! Added line 2 with BUG

In this case, you may need to add the -k flag to your command line to preserve the last commit, which is basically empty:

$ git rebase -i -k --autosquash HEAD~3
 Date: Tue Nov 3 10:45:40 2015 -0500
 1 file changed, 2 insertions(+), 1 deletion(-)
Successfully rebased and updated refs/heads/master.
$ cat test
1
2
This is NOT a BUG

The other alternative is of course to fix the conflict manually using git merge or git mergetool, following the prompts when the rebase fails.

You can make the rebase "succeed" by adding -s recursive -X theirs or -s recursive -X ours to specify the strategy. However, because of the context conflict, your fixup will get clobbered in both of those cases.

I think that the problem is the context of the changes. Look at this commit:

$ git show c3d3db7
diff --git a/test.file b/test.file
index 7a103db..8c8e69a 100644
--- a/test.file
+++ b/test.file
@@ -1,3 +1,3 @@
 1
 2
-This is a BUG
+This is NOT a BUG

And you want to apply this patch to the file with contents:

1
This is a BUG

See? The patch does not apply, because the context does not match. So a conflict arises and you have to fix it manually.


When you have the bugger line split in two, the patch is something like:

diff --git a/test.file b/test.file
--- a/test.file
+++ b/test.file
@@ -1,3 +1,3 @@
 1
 2
 This is
-a BUG
+NOT a BUG

And the file is:

1
This is
a BUG

Now, while the match is not perfect, at least the first unmodified line of the context matches, so the merge may continue.

git is giving me a major headache when using --fixup and --autosquash.

Beware there is another case, when using git rebase --autosquash, of headache.

Git 2.20 (Q4 2018) just fixed a bug related to autosquash: "git rebase -i" did not clear the state files correctly when a run of "squash/fixup" is aborted and then the user manually amended the commit instead, which has been corrected.

See commit 10d2f35, commit 2f3eb68 (31 Aug 2018) by Johannes Schindelin (dscho). (Merged by Junio C Hamano -- gitster -- in commit 87ae8a1, 24 Sep 2018)

rebase -i --autosquash: demonstrate a problem skipping the last squash

The git commit --squash command can be used not only to amend commit messages and changes, but also to record notes for an upcoming rebase.

For example, when the author information of a given commit is incorrect, a user might call git commit --allow-empty -m "Fix author" --squash <commit>, to remind them to fix that during the rebase. When the editor would pop up, the user would simply delete the commit message to abort the rebase at this stage, fix the author information, and continue with git rebase --skip. (This is a real-world example from the rebase of Git for Windows onto v2.19.0-rc1.)

However, there is a bug in git rebase that will cause the squash message not to be forgotten in this case. It will therefore be reused in the next fixup/squash chain (if any).

rebase -i: be careful to wrap up fixup/squash chains

When an interactive rebase was stopped at the end of a fixup/squash chain, the user might have edited the commit manually before continuing (with either git rebase --skip or git rebase --continue, it does not really matter which).

We need to be very careful to wrap up the fixup/squash chain also in this scenario: otherwise the next fixup/squash chain would try to pick up where the previous one was left.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!