即使只有一行被更改,由于Git CR的自动删除,我的分支的提交也全部损坏。
我们的存储库本身已损坏:它是从SVN转换而未剥离CR的。
因此,任何没有autocrlf = input
修复CR / LF的Git客户端都会自动结束。
我修复了一系列可怕的提交,例如(使用core.autocrlf=false
和在文件中添加和删除最后一行以使它们有所不同):
git co broken
git co -b fixed HASH_OF_BROKEN
git -c core.autocrlf=false reset --hard
for f in broken.txt; do echo >>$f; unix2dos $f; done
git -c core.autocrlf=false add -u
git -c core.autocrlf=false ci --amend --no-edit
for f in broken.txt; do sed -i '$ d' $f; done
git -c core.autocrlf=false add -u
git -c core.autocrlf=false ci --amend --no-edit
git cherry-pick HASH_OF_NEXT_TO_BROKEN..broken
git push origin fixed
有简单的方法可以解决以下结果:
warning: CRLF will be replaced by LF in ...
如果目标是使存储库具有一致的行尾,那么最好使用重写整个历史记录,而git-filter-branch
不是逐个提交地处理它。假设您要使用一致的DOS行尾。
编写一个小程序,该程序可以转换目录树中除之外的所有文件的行尾.git
。如果您有二进制文件,则还必须跳过它们。这是一个简单的例子。
$ cat ~/bin/all2dos
#!/bin/sh
find . -path ./.git -prune -o -type f -print0 | xargs -0 unix2dos
然后在中使用tree-filter
来转换所有历史记录中每次提交的行尾。
$ git filter-branch --tree-filter 'all2dos' -- --all
虽然重写历史记录很可怕,但在一段时间内它是完全可逆的。Git不会重写提交,它会编写新的提交并使用它们。您的原始提交可通过reflog访问,您可以将分支移回它们。
$ git reflog
10eed67 (HEAD -> master) HEAD@{0}: filter-branch: rewrite
e8615e3 HEAD@{1}: commit (initial): Test files
也就是说,最初的提交master
是e8615e3
,新的重写了10eed67
。我可以使用移master
回原始位置git reset --hard e8615e3
。
这将导致新的提交ID,因此,当前在您的项目上工作的任何人都可能必须git pull --rebase=preserve
进行更新(无论如何,他们都应该这样做),--ignore-cr-at-eol
以避免由于换行符更改而引起的冲突。如果他们有任何开放的分支机构,他们将会是旧的master
; 他们应该git rebase master
以新改写的master
分支为基础。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句