网易首页 > 网易号 > 正文 申请入驻

聊聊关于AI写代码的编码格式和行尾问题

0
分享至

问题背景

2026年起,AI越来越厉害,以前都是手写代码,后来有网页版早期的ChatGPT和Deepseek,开始资讯AI辅助写代码,最多就是复制AI给出的片段,贴到本地再适应本地项目。

而2026年后,完全可以让AI直接写Unity的或者其他引擎的代码了,甚至MCP可以直接帮你在Unity里编译好,完整debug后再交付给你,非常爽。

但是,我们团队开发一段时间后,发现了一个以前手写代码不会有的问题,那就是出现各种编码和行尾不一致的问题,一旦提交git或者svn,就会发现无缘故多了很多明明没改但提示变了的文件。这些误报会消耗很多时间精力去筛查,非常不值得。

调查情况

先看Unity这边,由于一般是用的VS来写的代码,的行尾和编码由编辑器决定的,默认行尾是CRLF,编码格式是UTF-8带BOM。但是AI编写的代码, 就由AI模型的习惯决定了,根据训练资料有关,大多LF和UTF8无BOM。





最大坑点是,有可能AI写好的代码,你用Visual Studio打开,不小心就会自动按照VS的默认设置改掉了编码和行尾,相反AI写的也可能会改掉原有文件的编码和行尾,来回变化,导致查看差异时很多误报。

到底有无BOM两者有什么区别



虽然都是UTF8,但是缺又不完全一样,到底什么区别,因此我也资讯了下AI答案:

BOM 是文件开头的三个字节,EF BB BF。它原本是给「不知道这是 UTF-8」的老工具打的一个标记。

C# 在 Windows 上的默认行为,是存成 UTF-8 带 BOM,有些配置下干脆是系统本地编码,中文 Windows 就是 GBK。

带 BOM 编译没问题,.NET 编译器认识它。麻烦出在别处。多出的三个字节会让某些 diff 工具把第一行算成改过。Linux 上的一些脚本、模板引擎、拼接工具会把 BOM 当成内容,输出里冒出一个看不见的字符。某些 JSON 解析器和字符串比较对 BOM 敏感。最烦的是抖动,同一个文件在「带 BOM」和「不带 BOM」的两台机器之间来回转,diff 会一直抖。

那到底统一成什么比较好呢?

Unity 的文档里提到,含非 ASCII 字符的脚本建议用带 BOM 的 UTF-8,保证各种环境都能正确识别编码。而 AI 生成的代码天然不带 BOM。一个主要靠 AI 写代码的项目,两边的默认值正好相反。



我其实一开始挺犹豫,让AI扫了我当前的项目编码情况,带和不带各站一半就很尴尬,特别是含中文注释的UTF8无BOM不知道有没有风险。



不过根据AI提供的资讯,带BOM主要用于老工具的识别,目前可能也用不到,无论带和不带,现在单独打开编辑器看中文注释都是没问题的。

项目往后主要靠AI写代码的话,还是应该顺着AI的默认值走,少一层来回转换的必要。所以我选择了B方案。

再看行尾的问题

AI 天然就是 LF,而Windows手写的默认是CRLF。不过我让AI实际扫描我当前项目,LF已成事实主流了。



因为同样的理由,未来会选择用AI写代码为主,所以顺应AI主流直接用LF作为规范统一是最合适的选择了。



约定成写入规范

一次性的整改只是临时的,要长期规范要真正写入成一个规范文件根治才行,AI检查后说我治理机制全缺,让我写这3个规范文件:

.editorconfig /.gitattributes /svn:eol-style



说实话以前手写代码的时候,我根本没见过这几个东西,从来没用过也能跑。但根据AI给出的资讯,其实他们在AI时代很重要,以下是AI给出的介绍:

.editorconfig卡在编辑器这一端。你新建或保存一个文件时,编辑器会先读它,按里面的规定决定用什么缩进、什么字符集、什么行尾。它是一份写给编辑器看的约定。

.gitattributes和svn:eol-style卡在版本控制这一端。文件入库的那一刻,它们负责把行尾和文本类型归一化。它们不关心你用什么工具写,只认提交这个动作。

最后一道是提交前检查,pre-commit 或者 CI。前两道都设好了,还是可能有人或者某个工具绕过去,那就靠它把漏网的文件拦下来。

最简单的文件.editorconfig

在项目根目录放一个.editorconfig,写这么几行就够了。

root = true

charset = utf-8

end_of_line = lf

insert_final_newline = true

trim_trailing_whitespace = true

indent_style = space

indent_size = 4

[*.{json,yml,yaml}]

indent_size = 2

[*.md] trim_trailing_whitespace = false

root = true表示这是最顶层,编辑器往上找到这里就停,不再往父目录找。

charset写utf-8,注意不是utf-8-bom。这一条就是「编码用 UTF-8、不带 BOM」的写法。

end_of_line写lf,对应「行尾用 LF」。

几种主流编辑器都原生读它,VS Code、Rider、Visual Studio 2022 都不用装插件。写一次,全项目生效,没有运行时成本。

放哪儿也简单。项目根目录最省事。如果只想管住 Unity 工程,放在Assets/下面也完全安全,Unity 会忽略点开头的文件,不会给它生成.meta,也不会当资源导入。

还有个容易忽略的点。VS 和 Rider 都是启动时读它,改完记得重开一次编辑器,不重开不生效。

它的弱点也很明确。它不强制。只在编辑器愿意遵守的时候才生效。你用命令行工具直接写文件、用脚本批量生成文件,或者让某个工具直接落盘,它一律管不着。

Git版本控制的.gitattributes

如果你用 Git,在仓库根目录放一个.gitattributes。

* text=auto eol=lf

*.cs text eol=lf

*.sln text eol=crlf

*.bat text eol=crlf

*.cmd text eol=crlf

*.png binary

*.dll binary

* text=auto eol=lf这一行是现在的推荐起手式。git 提交时把文本文件的行尾统一成 LF 存进仓库,检出到工作区也按 eol 走。仓库里永远只有一种行尾,跨平台协作不会互相覆盖。

下面几行是明确点名。.cs走 LF,.sln和 Windows 批处理按各自的要求单独给 CRLF,图片和 dll 直接标成 binary,别让 git 去猜。

SVN属性的svn:eol-style

SVN 没有 .gitattributes 那种放在仓库里、人人可见的声明文件。它的做法是给文件挂一个属性,属性名就叫svn:eol-style。

先分清楚几个值,选错了效果完全不一样。

native,仓库统一存 LF,检出时按平台转换。Windows 上检出成 CRLF,Linux 和 Mac 检出成 LF。适合「每个平台用自己习惯的行尾」的团队。

LF,仓库存 LF,检出也永远是 LF,在 Windows 上也是 LF。适合「行尾就统一成 LF,谁也别转」的团队。

我要的是后一种,所以选 LF。方向定了就是全项目 LF,不要再让平台转换插一脚。

怎么设。四种方式,从最直接的到最省事的。

方式一,图形界面。在要处理的文件夹上右键,TortoiseSVN,Properties,New,eol-style,选 LF,勾上「Set property recursively」,确定。适合只改一两个目录。

方式二,命令行按目录递归。一行就够。

svn propset svn:eol-style LF --recursive Assets

svn propset svn:eol-style LF --recursive .

这里有个容易误解的点。SVN 的属性不继承。--recursive是把每个文件挨个设一遍,不是「给文件夹设了,子文件就自动有」。文件夹上挂属性,不会传给里面的文件。

方式三,命令行按清单批量。如果只想处理某类文件,还要避开第三方目录,先生成一份清单再喂给它。

svn list -R > all-files.txt

svn propset svn:eol-style LF --targets cs-list.txt

第一行把受版本控制的文件全列出来。编辑这份清单,只留 .cs,把Plugins/下面的删掉,存成 cs-list.txt。--targets后面就是一个一行一个路径的文本文件。我就是这么只给版本化的 .cs 设的属性,第三方插件一个没动,别人的代码别去改。

方式四,auto-props,让新文件自动带上。前面三种只管现有文件,之后新加的文件属性还是空的。在本机的 Subversion config 里加两段,新文件一svn add就自动带上。

[miscellany]

enable-auto-props = yes

[auto-props]

*.cs = svn:eol-style=LF

*.csproj = svn:eol-style=LF

*.bat = svn:eol-style=CRLF

*.cmd = svn:eol-style=CRLF

config 文件在 Windows 上一般在%APPDATA%\Subversion\config。改完对之后新加的文件生效。

这里有两个坑。一是enable-auto-props = yes不打开,下面的 auto-props 根本不生效,这个最常见。二是 auto-props 只对之后新增的文件起作用,已经入库的老文件得靠前面三种方式手动补。

设完别忘了提交。propset 只改了你的工作副本,属性本身也是受版本控制的。要让团队其他人都拿到,得svn commit一次。

怎么确认真的设上了。查单个文件,用 propget 加属性名和文件路径。想给整个目录体检,加--recursive,它会逐个列出路径和属性值,没设的显示 none。

svn propget svn:eol-style Assets/Scripts/Player.cs

svn propget svn:eol-style --recursive Assets

顺手再看一眼svn status。属性变更和内容变更在输出里占的是两列,别搞混。

MM Assets/Scripts/Player.cs

M Assets/Scripts/Player.cs

第一列是内容状态,第二列是属性状态。MM 是内容和属性都变了。前面空一格、只有一个 M 的,是只改了属性。我第一次看的时候就没分清这两列。

设错了想撤销,把 propset 换成 propdel,一行删掉。

svn propdel svn:eol-style --recursive Assets

改成 LF 之后,SVN 还能 diff 出差异吗

这是我最关心的问题。我先拿一个文件做了次受控实验,结论分两层。



第一层,只改行尾,SVN 会不会认为文件变了。答案取决于有没有设 svn:eol-style。

没设的时候,SVN 是按行比较的,行尾符号也算在这一行里。你把整份文件的 CRLF 换成 LF,在它眼里就是每一行都变了,diff 变成整份删除加整份重新添加。几百行假差异,真正改的那几行得在噪声里捞。

设了之后,SVN 比较的是归一化之后的内容。纯行尾的变化被它吃掉了,不再产生 diff。只有你真正改过的行才会出现。

所以加 svn:eol-style 最大的好处,不是「能 diff」,而是让 diff 干净。它把行尾这一类噪声永久性地从 diff 里删掉了。

第二层,那设置属性本身,会不会造成一次全文件改动。可能会,而且这是必须付的一次性代价。

如果你的文件在仓库里存的是 CRLF,属性却要求 LF,那这次提交会让整个文件看起来被改了。这是一次性代价,吃掉它就好。

正确的做法是三步。第一步,把要改的文件挑出来,设属性、顺手把内容归一化。第二步,就这一次,单独提交,提交信息写明「纯格式变更,无逻辑改动」。第三步,之后正常写代码,diff 里只剩你真正动过的那几行。

关键在第二步。格式变更必须单独一条提交,不能和功能改动混在一起。混在一起,你以后想单独回滚这次格式变更都做不到。

总结经验

在AI时代里,编码和行尾的变化问题是值得重视的,与手写时代的默认值不同了。

非常建议加上.editorconfig /.gitattributes /svn:eol-style这3个设置,至于怎么写怎么加,找AI搞就行,只不过你不说,AI就不会去做。

声明:内容由AI生成

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
尊界刹车踏板供应商指向凯众股份?公司回应:江淮是客户但体量很小,具体供应车型等细节保密

尊界刹车踏板供应商指向凯众股份?公司回应:江淮是客户但体量很小,具体供应车型等细节保密

蓝鲸新闻
2026-10-09 16:07:12
李嘉诚再次预判我国楼市!不出意外的话,楼市或迎 “三大走向”

李嘉诚再次预判我国楼市!不出意外的话,楼市或迎 “三大走向”

李博世财经
2026-10-09 10:59:53
中年遭遇烂桃花啊!山东小店老板娘哭诉,被顾客表白,回绝后持续电话纠缠,及时拉黑后直言“一夜没睡”,评论区炸锅

中年遭遇烂桃花啊!山东小店老板娘哭诉,被顾客表白,回绝后持续电话纠缠,及时拉黑后直言“一夜没睡”,评论区炸锅

火山詩话
2026-10-11 08:36:10
局势彻底恶化了!莫迪贸然开战,印军跨境开火,美国出动F-35A支援,中印边境恐怕要生变?舆论瞬间炸锅!

局势彻底恶化了!莫迪贸然开战,印军跨境开火,美国出动F-35A支援,中印边境恐怕要生变?舆论瞬间炸锅!

谈史论今1
2026-10-10 18:54:23
4年不近男色!卡戴珊提议妹妹和造型师上床,被一口回绝:太尴尬

4年不近男色!卡戴珊提议妹妹和造型师上床,被一口回绝:太尴尬

日落于西
2026-10-10 12:40:08
广东弃将又爆发!半场6中6打爆山东,朱芳雨这笔账亏不亏

广东弃将又爆发!半场6中6打爆山东,朱芳雨这笔账亏不亏

kio鱼
2026-10-12 04:11:31
刘烨16岁儿子近照曝光!混血五官被指像年轻时小李子莱昂纳多

刘烨16岁儿子近照曝光!混血五官被指像年轻时小李子莱昂纳多

韩小娱
2026-10-11 17:18:54
百亿私募希瓦梁宏吐槽:部分保险资管巨头7月高位买入大量科技股,9月下旬却大幅减仓止损!直言“追涨杀跌令人费解”

百亿私募希瓦梁宏吐槽:部分保险资管巨头7月高位买入大量科技股,9月下旬却大幅减仓止损!直言“追涨杀跌令人费解”

投资者内参
2026-10-11 22:33:58
林俊杰和小21岁女友观赛F1后牵手离开,七七面对镜头用手挡脸,林俊杰暖心安慰“别那么紧张”

林俊杰和小21岁女友观赛F1后牵手离开,七七面对镜头用手挡脸,林俊杰暖心安慰“别那么紧张”

韩小娱
2026-10-11 22:57:17
王曼昱斩获双冠后,点名感谢3人!邓亚萍用一个字,盛赞其统治力

王曼昱斩获双冠后,点名感谢3人!邓亚萍用一个字,盛赞其统治力

十点街球体育
2026-10-11 21:36:41
1942年,浙江一位农妇冒死救助五名美军飞行员,50年后她受邀访美,得到老布什亲自设宴款待

1942年,浙江一位农妇冒死救助五名美军飞行员,50年后她受邀访美,得到老布什亲自设宴款待

饭小妹说历史
2026-10-11 19:05:37
正式退赛,高芙连夜离开中国,不满被中国球迷网暴,利用规则赢中国小将

正式退赛,高芙连夜离开中国,不满被中国球迷网暴,利用规则赢中国小将

喜欢体育的猫
2026-10-10 09:31:20
“懂车帝尊界”事件,人民日报官媒定调!

“懂车帝尊界”事件,人民日报官媒定调!

大厂财经社
2026-10-11 16:52:33
吃饭决定寿命?医生发现:活过85岁的老人,吃饭一般都有4特点

吃饭决定寿命?医生发现:活过85岁的老人,吃饭一般都有4特点

医学原创故事会
2026-10-11 23:26:04
旅行者一号飞了近半个世纪,为什么还能联系地球?

旅行者一号飞了近半个世纪,为什么还能联系地球?

观察宇宙
2026-10-10 10:41:48
王曼昱夺冠后比“1”庆祝,赛后感谢3人!邓亚萍盛赞!丁宁陈梦惊喜现身观战!马琳拍背肯定

王曼昱夺冠后比“1”庆祝,赛后感谢3人!邓亚萍盛赞!丁宁陈梦惊喜现身观战!马琳拍背肯定

好乒乓
2026-10-11 21:02:01
纪委能不能查到微信语音通话录音?别急着删聊天记录!给你讲清楚

纪委能不能查到微信语音通话录音?别急着删聊天记录!给你讲清楚

职场资深秘书
2026-10-08 10:46:53
网友吐槽阿迪海报宋雨琦指甲变犄角 门店回应:现已撤下

网友吐槽阿迪海报宋雨琦指甲变犄角 门店回应:现已撤下

快科技
2026-10-10 20:51:10
胆太肥了!英国男子翻进虎舍,手指东北虎喊“Stop”,却当场身亡

胆太肥了!英国男子翻进虎舍,手指东北虎喊“Stop”,却当场身亡

吃青菜长高
2026-10-11 21:48:24
刹车断裂之后,合肥与华为要算清一笔账

刹车断裂之后,合肥与华为要算清一笔账

雨前产经观察
2026-10-11 19:49:04
2026-10-12 06:08:49
刘俊亨of游戏开发者 incentive-icons
刘俊亨of游戏开发者
游戏开发者,游戏鉴赏家,怀旧游戏玩家
85文章数 585关注度
往期回顾 全部

科技要闻

卸任CEO后,苹果董事长库克再度到访中国

头条要闻

郑钦文回应中网夺冠:特别想赢 压力大到不停呕吐

头条要闻

郑钦文回应中网夺冠:特别想赢 压力大到不停呕吐

体育要闻

30天30队·魔术:班凯罗最后的试炼?

娱乐要闻

没夫妻生活咋办?冉莹颖绝不求邹市明

财经要闻

黄仁勋长女完婚,万亿帝国如何传承?

汽车要闻

大6座插混SUV新选择 阿维塔T09概念版亮相巴黎车展

态度原创

健康
旅游
手机
本地
公开课

痘坑留下后,还能填平吗?

旅游要闻

繁华大吉巷里,“南海会馆”珍藏着一段近代风云

手机要闻

华为憋了个大的!星芒突然曝光,这是要再造一个荣耀?

本地新闻

踏访沙县第一村,寻国民小吃本源

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版