如何在不修改git历史记录的情况下在源代码上运行代码格式化程序?
我正在尝试使用代码格式化工具格式化整个回购协议。在这样做的过程中,我希望保留关于谁提交了哪一行的信息,以便像如何在不修改git历史记录的情况下在源代码上运行代码格式化程序?,git,formatting,git-filter-branch,prettier,Git,Formatting,Git Filter Branch,Prettier,我正在尝试使用代码格式化工具格式化整个回购协议。在这样做的过程中,我希望保留关于谁提交了哪一行的信息,以便像git-dull这样的命令仍然显示正确的信息。我的意思是,它应该显示作者以前编辑过每一行(在格式化之前) 有一个git filter branch命令,它允许您从一开始就对repo的每个版本运行一个命令 git filter-branch --tree-filter '\ npx prettier --write "src/main/web/app/**/**.{js, jsx}" |
git-dull
这样的命令仍然显示正确的信息。我的意思是,它应该显示作者以前编辑过每一行(在格式化之前)
有一个git filter branch命令,它允许您从一开始就对repo的每个版本运行一个命令
git filter-branch --tree-filter '\
npx prettier --write "src/main/web/app/**/**.{js, jsx}" || \
echo "Error: no JS files found or invalid syntax"' \
-- --all
这将需要永远运行,我真的不在乎过去。我只想在不改变每一行所有权的情况下格式化主分支。我该怎么做?我尝试在末尾使用
rev list
和其他过滤器类型,但仍然不起作用。必须有一种方法来格式化代码库,同时保留每行的作者信息。您试图做的是不可能的。您不能在某个时间点更改一行代码,而让git报告对该行代码的最新更改是在该时间点之前发生的
我认为源代码管理工具可以支持“不重要的更改”的想法,即将提交标记为修饰,然后历史分析将跳过该提交。我不确定该工具将如何验证更改是否真的是表面的,如果没有某种形式的工具强制,该功能肯定会被误用,导致错误引入可能隐藏在“不重要”的提交中。但实际上,我认为这是一个坏主意的原因在这里是学术性的——底线是,git没有这样的特性。(我想不出有哪种源代码管理工具可以做到这一点。) 您可以继续更改格式。您可以保留过去更改的可见性。您可以避免编辑历史记录。但是你不能同时做这三件事,所以你必须决定牺牲哪一件 顺便说一句,重写历史实际上有一些不利因素。您提到了处理时间,让我们先来看看: 正如您所注意到的,使用
过滤器分支执行此操作的简单方法将非常耗时。您可以做一些事情来加速它(比如为它的工作树提供一个ramdisk),但它是一个树过滤器
,它涉及到处理每个文件的每个版本
如果您做了一些预处理,您可能会更有效率。例如,您可以预处理数据库中的每个BLOB
,并创建映射(其中树包含BLOB
X,将其替换为BLOB
Y),然后使用索引过滤器执行替换。这将避免所有签出和添加操作,并避免重复重新格式化相同的代码文件。因此,这节省了大量I/O。但这是一件非常重要的事情,而且可能仍然很耗时
(基于同样的原理,可以编写更专业的工具,但恐怕还没有人编写过。有先例表明,更专业的工具可以比过滤器分支
更快。)
即使你找到了一个运行速度足够快的解决方案,也要记住,重写历史记录会干扰你所有的参考文献。像任何历史重写一样,repo的所有用户都有必要更新他们的克隆。对于这种彻底的更新,我建议的方法是,在开始重写之前扔掉克隆,然后再重新克隆
这也意味着,如果您有任何依赖于提交ID的内容,那么它也将被破坏。(这可能包括构建基础设施或发布文档等,具体取决于项目的实践。)
因此,重写历史是一个相当激进的解决方案。另一方面,假设格式化代码是不可能的,因为它不是从第一天开始就完成的,这似乎是极端的。因此,我的建议是:
在新提交中重新格式化。如果您需要使用git-gull
,并且它将您指向发生重新格式化的提交,那么接下来在重新格式化提交的父级上再次运行git-gull
是啊,糟透了。有一段时间。但是,一段特定的历史往往会随着时间的推移而变得不那么重要,因此,从那时起,你就让问题逐渐消失在过去。你试图做的是不可能的。您不能在某个时间点更改一行代码,而让git报告对该行代码的最新更改是在该时间点之前发生的
我认为源代码管理工具可以支持“不重要的更改”的想法,即将提交标记为修饰,然后历史分析将跳过该提交。我不确定该工具将如何验证更改是否真的是表面的,如果没有某种形式的工具强制,该功能肯定会被误用,导致错误引入可能隐藏在“不重要”的提交中。但实际上,我认为这是一个坏主意的原因在这里是学术性的——底线是,git没有这样的特性。(我想不出有哪种源代码管理工具可以做到这一点。)
您可以继续更改格式。您可以保留过去更改的可见性。您可以避免编辑历史记录。但是你不能同时做这三件事,所以你必须决定牺牲哪一件
顺便说一句,重写历史实际上有一些不利因素。您提到了处理时间,让我们先来看看:
正如您所注意到的,使用过滤器分支执行此操作的简单方法将非常耗时。你可以做一些事情来加速它(比如给它一个ramdisk作为它的工作树),但是它是一个树过滤器
,它涉及到对每个版本的ea的处理
--skip <REV[+]>
revision to not display (EXPERIMENTAL)