git中的自定义行结尾(LF和CR + LF除外)

时间:2017-05-18 21:45:51

标签: git delimiter line-endings

我被聘为一名顾问,与一家大公司使用的可怕的内部DSL合作。

我说可怕,因为代替回车或换行来结束每行代码,代码行用五个字符的ASCII字符串<EOL>分隔。这些文件长达数千个“行”。任何嵌入式回车或换行都会使他们的翻译失败。

我无法更改他们的解释器或语言,但我需要使用以这种语言编写的大量(> 100 MB)代码库。

在对此代码进行任何更改之前,我想将其放入git存储库中进行跟踪。有没有办法告诉git字符串<EOL>代表行尾,就像你可以用LF指定CR+LFcore.eol=lf一样?例如,core.eol="<EOL>"。如果是这样,这将使我的生活在两个方面变得更加容易:

  1. 它会使合并和差异智能地工作; git会知道“行”的位置。
  2. 我可以(例如)使用<EOL>作为行结尾签入原始代码,然后在设置了core.eol=lf的另一台机器上检查它,git会自动来回转换。 (我可以使用常规文本编辑器和常规工具!)
  3. 我确实认识到这是一个利基,边缘案例。我也理解我可以添加一个中间处理步骤来在与git交互之前来回转换,但是我想避免这种情况,除非绝对必要,因为我更愿意将他们现有的代码库直接导入git而不先预先处理它。

    如果此功能不可用,我甚至可能更喜欢创建一个自定义版本的git来添加额外的处理步骤,所以如果有人知道可能涉及哪些复杂性,我会有兴趣了解这些。 / p>

2 个答案:

答案 0 :(得分:4)

此自定义过滤器设置会在Git存储中生成包含*.dsl的{​​{1}}个文件,但在您的工作目录中签出时会<EOL>\n git diff等工具将对签出的版本进行操作(例如\n)。这就是你想要的吗?

~/.gitconfig.git/config

[filter "crazy-eol"]
    clean = awk 'BEGIN{ORS="<EOL>"}1'
    smudge = awk 'BEGIN{RS="<EOL>"}1'
[diff "crazy-eol"]
    textconv = awk 'BEGIN{RS="<EOL>"}1'

.gitattributes.git/info/attributes

*.dsl filter=crazy-eol diff=crazy-eol

答案 1 :(得分:2)

一种方法。这根本不方便,如果文字字符串<EOL>确实 出现在一行内,它就有可能进行不可逆转的更改(尽管给出了描述)看起来这似乎不会发生这种情况。)

但是,您无法使用core.eol设置执行此操作。您需要使用涂抹清理过滤器。请查看the gitattributes documentation中的说明。您的两个过滤器会将<EOL>转换为换行符,反之亦然。事实上,这正是core.eolcore.autocrlf以及text转换过滤器所做的事情:它们将\r\n替换为\n在一个方向或另一个方向,只是正如您在一个方向或另一个方向上用<EOL>替换\n。事实上,如果你在文档中看得更远一点,那么在签入/结帐属性和#34;之间的交互中,#34;部分,您将看到Git只有一个text过滤器,其作用类似于干净和/或涂抹过滤器,作为管道的一部分。

在执行任何此操作之前,请考虑......

在你为此烦恼之前,考虑只做一次你自己的传球。将文件放入&#34;正常&#34;形式,你可以Git-ize那些。在处理这些文件之前,您始终可以运行自己的清洁剂。然后,一旦准备好了文件,就可以通过&#34; insanitizer&#34;回到疯狂的<EOL>格式,完全在Git之外。

我认为(外部消毒剂/清洁剂)更容易使用,真的。

相关问题