如何使用git filter实现不同于仓库风格的本地代码风格?

问题描述 投票:0回答:1

项目编码风格的一些元素让我很烦。例如,我更喜欢 80 个字符的行长度,我从不希望 if 的条件和语句在同一行(用于断点放置)等。

我想使用 git 过滤器将代码从上游 repo 转换为我喜欢的格式,在开发过程中使用首选格式,然后在我推送时将其转换回来。

该项目使用 clang-format,因此有一个非常明确的样式。

这能做到吗?

git filter coding-style clang-format
1个回答
0
投票

这样做需要您自担风险! 据我所知,git 过滤器不是为此目的而设计的!

话虽如此,但有一些注意事项是可能的,我将分享一个有效的设置。

先决条件

回购需要使用样式强制工具,如

clang-format
,可以用作管道。格式和格式化工具需要满足以下属性:如果您从存储库样式格式的文件开始,应用本地格式,然后应用存储库格式,那么您将得到原始文件。

方式

假设存储库样式基于 LLVM 样式,最大行长度修改为 150 个字符,而您更喜欢最大 80 个字符的行。您只想对单个文件进行样式转换

path/file.cc
。从一个干净的存储库状态开始。

使用以下内容创建

.git/info/attributes

path/file.cc filter=style

将以下内容放入

.git/config

[filter "style"]
    clean = <path>/upstream-style.sh %f
    smudge = <path>/local-style.sh %f

提到的

upstream-style.sh
脚本有:

#!/bin/bash

<path>/clang-format --verbose --style="{BasedOnStyle: LLVM, ColumnLimit: 150}"

local-style.sh
有:

#!/bin/bash

<path>/clang-format --verbose --style="{BasedOnStyle: LLVM, ColumnLimit: 80, 
                                        ReflowComments: false}"

文件还没有重新格式化,因为没有git操作。触发重新格式化的一种简单方法是切换到另一个分支并返回。

注意事项

我们依赖于执行

local-style.sh
然后
upstream-style.sh
(或相反)你得到完全相同的文件。所有样式选项都不能保证这一点。

特别是,评论可能是个问题。选项

ReflowComments: false
应该有助于评论块,但行内评论很可能仍然是一个问题。超过允许长度的行内注释行可能会被打断,并且在转换过程中不会恢复到原来的形式。

如果注释和代码从不在同一行,应该没有问题。顺便说一句,我更喜欢遵循这条准则。 (我喜欢在文件、类、函数的开头使用注释块,而不是穿插在函数内部。)

git diff
命令可能不会显示正确的行号。

注意事项

脚本接收正在格式化的文件名。但是,调用 clang-format 时使用文件名是错误的。您可能会收到“找不到文件”错误,因为在脚本执行时磁盘可能没有副本。

脚本中的名称仍然有用。我用它来打印一条消息到标准错误,例如:

>&2 echo "Formatting $1 for local."

如果出现问题,注释掉

attributes
文件中的行并重置存储库。

我成功地使用了这个解决方案。我在 commit、rebase、cherry-pick 期间没有遇到任何问题。

© www.soinside.com 2019 - 2024. All rights reserved.