Git rebase 奇怪地添加了对 .gitignore 的更改

Git rebase strangely adds changes to .gitignore

我有以下简单的测试 repo(没有 .gitignore

创建 https://gist.github.com/gabyx/6ea9cf93e3aaecc9229234ea1f1960fd

testGitExamples.sh GitTest ex-wrong-committed-files && cd GitTest
Current history is:
 * ec8ddf1 - Added file W (Wrong changes in W.2)  (HEAD -> feature)
 * 8dbb0a8 - Added file D 
 * 54f196a - Added file C 
 * 32834a3 - Added file W (Wrong committed file W.2) 
 * 44a223a - Added file B 
 * 196b079 - Added file A 
 * 9365b59 - Test your solution 
 * f00c3f7 - Init  (master)

当我使用

对这个 repo 进行 rebase 时
git checkout feature
git rebase -i -x 'git rm -r --cache . && git add . && git commit --amend --no-edit' HEAD~4

并在 git-rebase-todo

的第 2 行添加 echo "W.2" > .gitignore
pick 7678be8 Added file W (Wrong committed file)
exec echo "W.2" > .gitignore
exec git rm -r --cache . && git add . && git commit --amend --no-edit
pick ded904f Added file C
exec git rm -r --cache . && git add . && git commit --amend --no-edit
pick dfb4b33 Added file D
exec git rm -r --cache . && git add . && git commit --amend --no-edit
pick 311736d Added file W (Wrong changes)
exec git rm -r --cache . && git add . && git commit --amend --no-edit

并执行 git rebase --continue (成功运行) git strangly 将上次提交 (ec8ddf1) 中的更改添加到 .gitignore.

这是怎么回事?这是一个错误吗?

初始回购 @ https://github.com/gabyx/GitTest

由于 W.2 的内容与上一个 pick.gitignore 的内容相同,git 的重命名检测启发式认为这是一个更改到重命名的文件(由于它们的高度相似性)并将更改从 W.2 应用到 .gitignore.

这最终是由于git不存储重命名这一事实造成的。当您在 git 中重命名文件时,假设使用 git mv,记录的是一对“File Added, File Deleted”。

一些 git 操作看到这对,如果它们的内容相似(高于阈值,您可以选择使用 --find-renames= 配置),将把它们视为同一个文件,但重命名.

这不仅适用于 git status 向您展示的内容,还适用于您的问题所展示的 mergerebase 等操作。

您可以通过传递-X no-renames要求rebase不执行重命名检测。

您的 rebase 命令将是:

git rebase -i -x 'git rm -r --cache . && git add . && git commit --amend --no-edit' -X no-renames HEAD~4

这种类型的错误在最小的工作示例中更常见,因为 git 没有足够的上下文来做出正确的猜测。