Git 中的行结尾混乱 - 如何在修复大量行结尾后跟踪另一个分支的更改?
我们正在使用定期更新的第三方 PHP 引擎。 版本保存在 git 中的单独分支上,我们的分支是主分支。
这样我们就可以将新版本的引擎的补丁应用到我们的分支上。
我的问题是,在对我们的分支进行多次提交后,我意识到引擎的初始导入是用 CRLF 行结尾完成的。
我将每个文件都转换为 LF,但这做出了巨大的提交,删除了 100k 行并添加了 100k 行,这显然破坏了我们的初衷:轻松合并来自第 3 方引擎的工厂版本的补丁。
我能知道什么? 我怎样才能解决这个问题? 我已经在我们的分叉上进行了数百次提交。
最好的办法是在初始导入之后和分支我们自己的分支之前以某种方式进行行结尾修复提交,并在历史稍后删除那个巨大的行结尾提交。
但是我不知道如何在 Git 中执行此操作。
谢谢!
We are working with a 3rd party PHP engine that gets regular updates. The releases are kept on a separate branch in git, and our fork is the master branch.
This way we'll be able to apply patches to our fork from the new releases of the engine.
My problem is, after many commits to our branch, I realized that the initial import of the engine was done with CRLF line endings.
I converted every file to LF, but this made a huge commit, with 100k lines removed and 100k lines added, which obviously breaks what we intended to do: easily merge in patches from the factory releases of that 3rd party engine.
What whould I do know? How can I fix this? I already have hundreds of commits on our fork.
What would be good is to somehow do a line endings fix commit after the initial import and before branching our own fork, and removing that huge line ending commit later in history.
However I have no idea how to do this in Git.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我终于设法解决了它。
答案是:
fix-line-endings.sh 包含:
在所有提交中的所有树中修复所有行结尾之后,我进行了交互式变基并删除了所有修复行结尾的提交。
现在我的存储库是干净和新鲜的,准备好推送了:)
访客请注意:如果您的存储库已被推送/克隆,请不要这样做,因为它会把事情搞得一团糟!
I finally managed to solve it.
The answer is:
fix-line-endings.sh contains:
After all line endings were fixed in all trees in all commits, I did an interactive rebase and removed all commits that were fixing line endings.
Now my repo is clean and fresh, ready to be pushed :)
Note to visitors: do not do this if your repo has been pushed / cloned because it will mess things up badly!
你看过
git rebase
吗?您将需要重新设置存储库的历史记录,如下所示:
但您需要了解的是这将破坏所有下游存储库 - 那些从父存储库克隆的存储库。 理想情况下,您将从头开始。
更新:示例用法:
将为最后 3 次提交启动变基会话。
Did you look at
git rebase
?You will need to re-base the history of your repository, as follows:
What you do need to understand though is that this will break all downstream repositories - those that are cloned from your parent repo. Ideally you will start from scratch with those.
Update: sample usage:
Will start a rebase session for the last 3 commits.
展望未来,请通过
core.autocrlf
设置避免此问题,记录在git config --help
:Going forward, avoid this problem with the
core.autocrlf
setting, documented ingit config --help
:我们将来会通过以下方式避免这个问题:
1)每个人都使用一个删除尾随空格的编辑器,并且我们用 LF 保存所有文件。
2) 如果 1) 失败(它可以 - 有人出于某种原因意外地将其保存在 CRLF 中),我们有一个预提交脚本来检查 CRLF 字符:
该脚本使用 GNU grep,并且可以在 Mac OS X 上运行,但它应该是在其他平台上使用之前进行了测试(我们在使用 Cygwin 和 BSD grep 时遇到了问题)
3)如果我们发现任何空格错误,我们对错误文件使用以下脚本:
we are avoiding this problem in the future with:
1) everyone uses an editor which strips trailing whitespaces, and we save all files with LF.
2) if 1) fails (it can - someone accidentally saves it in CRLF for whatever reason) we have a pre-commit script that checks for CRLF chars:
This script uses GNU grep, and works on Mac OS X, however it should be tested before use on other platforms (we had problems with Cygwin and BSD grep)
3) In case we find any whitespace errors, we use the following script on erroneous files:
一种解决方案(不一定是最好的解决方案)是使用 git-filter-branch 重写历史记录以始终使用正确的行结尾。 这应该是比交互式变基更好的解决方案,至少对于大量提交而言; 此外,使用 git-filter-branch 处理合并可能会更容易。
当然,这是假设历史未发布(存储库未克隆)。
One solution (not necessarily the best one) would be to use git-filter-branch to rewrite history to always use correct line endings. This should be better solution that interactive rebase, at least for larger number of commits; also it might be easier to deal with merges using git-filter-branch.
That is of course assuming that history was not published (repository was not cloned).