git rebase [last_good_commit]
但它只是说了这样的话
current branch *** is up to date.
git rebase [last_good_commit]
但它只是说了这样的话
current branch *** is up to date.
只需强制将尚未推送的提交进行变基,并告诉它在补丁中应用空格修复:
git rebase --whitespace=fix -f <last_good_commit>
重新设置基础的内部工作原理是通过应用补丁进行的,方便的是,git-apply
支持使用--whitespace
选项修复空格。
core.whitespace
控制了哪些是错误,所以我认为(未经测试)您可以添加 -c core.whitespace=blank-at-eol
来限制正在修复的内容。这将防止修复 space-before-tab
,但仍然会修复 所有 尾随空格,而不仅仅是行末的 CR。 - Matthijs Kooijman--ignore-whitespace
,但是它(如果我正确理解文档的话)会抱怨混合应用和合并选项。我有另一种方法可以在这种情况下进行一些手动工作,并将其单独回答分享。 - Matthijs Kooijman我成功应用的一个技巧是使用git rebase
和dos2unix
来自动修复这个问题。
要做到这一点,运行一个交互式的rebase:
git rebase -i [last_good_commit]
这将使您进入一个编辑器,其中列出了所有要重新应用的提交。例如:
pick ad31eff3 Some commit message
pick 138fab7d Some other commit message
现在将每一行修改为exec git checkout xxx . && dos2unix *.txt && git commit -a -C xxx
,其中两个xxx
都是相关提交的哈希值,并且*.txt
列出了需要修正行末的所有文件。
对于上面的示例,变成了:
exec git checkout ad31eff3 . && dos2unix *.txt && git commit -a -C ad31eff3
exec git checkout 138fab7d . && dos2unix *.txt && git commit -a -C 138fab7d
保存文件并退出编辑器:Git将依次处理每个命令,您应该得到一个修改后的历史记录,其中行尾永远不会出错。
这是一个正则表达式(实际上是一个vim
命令 - 根据您的编辑器语言适应它),可用于将具有pick
行的rebase命令文件转换为此修复程序的正确命令:
:%s/pick \([^ ]*\) .*/exec git checkout \1 . \&\& dos2unix *.txt \&\& exec git commit -a -C \1
对于每个提交,此技巧运行以下命令:
git checkout xxx .
这将更新当前工作副本的内容,使其与原始提交(具有不正确的行尾)完全匹配,而不会触及分支头(当前提交)或索引。
dos2unix *.txt
这将修复工作副本中的所有行尾,使用Unix LF替换dos CRLF(如果需要其他转换,可以在此处使用unix2dos
或其他命令)。
git commit -a -C xxx
这将提交所有更改(来自原始提交,但换行符已更改),重用原始提交的提交消息。
这里的技巧是对于每个提交,第一个命令会切换回原始文件。通常情况下,在重新定义基础时,您只需选择提交即可,但在这种情况下不起作用 - 一旦您在第一个提交中修复了行尾,后续提交可能将不再适用,留下您来解决混乱。在这种情况下,例如第二个提交,使用的git checkout
将只使用原始提交(树)中的文件,因此它完全忽略(因此也还原)为第一个提交修复的行尾。但没关系 - dos2unix
命令将愉快地为每个提交再次修复它们,最终结果是一个干净的历史记录,您无法告诉行尾曾经错误过。
聪明的读者会注意到,我们实际上并没有真正使用任何重新定义基础功能,因为所有提交都是使用显式的git commit
命令创建的,而不是让重新定义基础处理此问题。因此,这只是使用重新定义基础重置到好的提交,生成要应用的提交列表并按顺序执行命令(并进行一些有用的检查,例如工作副本是否干净以及命令是否失败)。
这种方法也适用于其他自动可重复修复的问题,例如代码格式调整。我最初 发现这种方法 是为了在新的代码库上运行 astyle
而不必创建一个大规模的修复提交。