我不止一次被编码折磨了,我的情况如下:
我在 linux 虚拟机下使用 emacs,用 samba 将一个文件夹共享给 Windows。我在 linux 下的文件都是有版本控制的,使用 utf-8-unix 编码。
然后问题来了,我在 Windows 工作环境下所使用的一个程序只支持 chinese-gbk-dos 编码,否则中文会乱码(这个程序是工作必须,没有替代)。
如果使用 utf-8-unix 保存文件,那么 windows 下面中文乱码;如果用 chinese-gbk-dos 保存文件,行尾为 crlf,会在 git diff 时在行尾显示 ^M,这是我想尽量避免的。
有没有什么两全其美的办法呢?
专有软件?
不如用脚本自动转换编码。只要替换一下换行符就可以。
spacemacs/uxix2dos, spacemacs/dos2unix用这两个函数
(defun spacemacs/dos2unix ()
"Converts the current buffer to UNIX file format."
(interactive)
(set-buffer-file-coding-system 'undecided-unix nil))
(defun spacemacs/unix2dos ()
"Converts the current buffer to DOS file format."
(interactive)
(set-buffer-file-coding-system 'undecided-dos nil))
LdBeth:
专有软件?
是的
有没有好的工作流?目前我想到两种方式:
一种方案是就用 gbk 编码,然后每次 commit 时都自动转成 utf-8,我个人不太喜欢这种工作流,因为编辑和最后提交的都不是同一个文件,心里感觉很不踏实 。
另外一种方案是每次保存都另外生成一个 gbk 版本的文件用于在 windows 下面运行,这样做有两个弊端,一个是增加了维护的难度,另外从 Windows 对文件进行修改后,同步更改到另一个版本会比较麻烦。
我需要的不是手动转换,因为我要频繁在两种环境下切换,在 Linux 下编辑,在 Windows 下运行。
那给你的mode加个exit/save hook,记得判断下你的系统
我可能没有表述清楚,windows 下面用的是专有软件,不是 emacs。它类似于 IDE,主要用于运行,测试 Linux 下面写好的文件,偶尔编辑。Linux 下面用的才是 Emacs。
把这个函数加到magit-diff-mode-hook里面试试?
(defun ztlevi/hidden-dos-eol ()
"Do not show ^M in files containing mixed UNIX and DOS line endings."
(interactive)
(setq buffer-display-table (make-display-table))
(aset buffer-display-table ?\^M []))
1 个赞
这个问题是由于你在 linux/windows 修改了同一个副本 。
diff 的时候自然就检测到:Linux 下编辑产生的 LF,Windows 下编辑产生的 CRLF。
可以通过以下设置忽略:
$ git config core.whitespace cr-at-eol
在一个文件中同时存在 CRLF 和 LF 有点凌乱,最好统一起来。文件采用 chinese-gbk-dos
编码,然后 Linux 下的仓库设置:
$ git config core.autocrlf true
checkout 出来的文件就自动转 LF 结尾了,commit 自动转回 CRLF。
在 windows 另外克隆一份 ,用来跑专用程序和偶尔修改。
(我没有环境重现你的问题,以上方案来自过去的经验)
5 个赞
这样做有一个缺点,就是 git diff 的时候中文显示乱码,有解决办法吗?
所以这也是为什么我一直坚持 utf-8 编码的原因——不会在意想不到的地方乱码。
因为我用 magit,git diff 乱码这个问题可能无解的:
opened 09:18PM - 29 Mar 15 UTC
closed 03:30PM - 31 Aug 15 UTC
support
Since I have to edit files in cp1251 encoding, I'd like to versioning them.
Mag… it diff buffer shows cp1251-encoded text wrong.
To fix it in bare git via `git diff` I can use:
```
[core]
pager = iconv -f windows-1251 -t utf-8 | less
```
in my `.git/config`.
So, is it possible to solve this problem in magit diff buffers?
看来还得用回 utf-8 编码啊,问题依旧。
我现在使用一种相对比较 hacky 的解决办法:
保存文件时,检查文件中是否含有 non-ascii 字符:
- 如果有,另存一份 gbk 编码的副本,后缀为原来后缀前面加 .dos,比如 .dos.txt 这样的。
然后在 Windows 下面使用 dos 版本的文件,并且尽量不修改。
在 Linux 下面修改原始版本 (utf-8) 的文件,并做版本控制。
代码很简单,而且适用范围很窄,我就不放了。如果有感兴趣的同学可以留言,我再放出来。
在找到更好的解决方案之前,先用这种办法凑合一下。
magit 没用过不知道,git diff 还是有解的,(为了不影响其它项目)在当前 .git/config
中加入:
[diff "localizablestrings"]
textconv = "iconv -f gbk -t utf-8"
然后项目根目录创建一个 .gitattributes
文件,内容为:
* diff=localizablestrings
可以只对特定文件,比如 *.txt
。
参考:http://blog.xk72.com/post/31456986659/diff-strings-files-in-git
3 个赞
我试试 magit 下可行不
Edit:
我是不是哪里做错了,diff 乱码倒是没有了,但是 ^M 也回来了:
甚至连 gitattributes 文件(utf-8)里也有。
et2010
2017 年8 月 12 日 13:59
17
正解!
我都不知道还有这个变量,这下解决了我的大问题,十分感谢!
et2010
2017 年8 月 19 日 14:45
18
我又来提问了,用这种方法,其它问题都解决了,然后一直用英文写 commit message 都没有问题。今天用中文写了 一次commit message,结果乱码又出现了。
请问这个应该怎样解决? @twlz0ne
吐槽一下,版本控制时用 utf-8 之外的编码坑真多啊
因为文件的内容是 gbk,而 commit 又是 utf-8?
magit 能不能分别设置编码?