如何动态更改Git回购中的行结尾

如何动态更改Git回购中的行结尾,git,Git,我在Windows上签出了一份Git回购协议。当我安装Git时,我选择了“使用CRLF作为本地行结束符”,所以repo被克隆并签出,所有文件都以CRLF作为行结束符。这给了我一些问题,因为我有很多bash脚本,并且我在WSL中使用了ubuntubash。我已经编辑了global.gitconfig文件,将行尾更改为与远程repo一致。但我的文件仍以CRLF行结尾。在不删除repo目录并重新克隆的情况下,将所有这些更改回其原始行结尾的最佳方法是什么 但我的文件仍以CRLF行结尾 如果存储库中提交中

我在Windows上签出了一份Git回购协议。当我安装Git时,我选择了“使用CRLF作为本地行结束符”,所以repo被克隆并签出,所有文件都以CRLF作为行结束符。这给了我一些问题,因为我有很多bash脚本,并且我在WSL中使用了ubuntubash。我已经编辑了global
.gitconfig
文件,将行尾更改为与远程repo一致。但我的文件仍以CRLF行结尾。在不删除repo目录并重新克隆的情况下,将所有这些更改回其原始行结尾的最佳方法是什么

但我的文件仍以CRLF行结尾

如果存储库中提交中的文件具有CRLF行结尾,则该文件的版本将永远以这种方式保留。任何现有提交的任何部分都不能更改

如果存储库中提交文件中的某个文件只有LF行结尾,则该文件的该版本将永远保持这种状态。但是,在提取文件时,您可以选择要在工作树中放置Git的结尾

如果您已经提取了文件,Git已经完成了转换。Git现在认为一切都很好,即使您刚刚更改了转换设置

因此,如果更改转换设置,则必须强制Git重新提取文件。在所有版本的Git中保持一致的最简单方法是从工作树中删除文件,然后运行
Git checkout--path/to/file
。由于文件已从工作树中删除,Git将被迫再次提取它。这次将应用更新的下线转换

(另一种方法是更改文件,然后运行相同的
git checkout
,或者在git 2.23或更高版本中使用
git restore
。告诉git git应该放弃您的文件版本,git发现您的文件版本确实“错误”由于它与索引副本不匹配,因为您更改了它,Git将被迫重新提取索引副本。)

这对你的情况可能就足够了,也可能不行。如果没有,请继续阅读

关于Git的行尾转换应该知道什么 我本人坚信“永远不要使用Windows,这样你就永远不需要让版本控制系统弄脏行尾”的理念,但如果你在其他阵营,确实想让Git弄脏行尾,有几件事需要知道。其中最重要的一点是:您在Git中存储的内容,以及在处理从Git中获取的文件时使用的内容,不一定是同一件事。

要了解其工作原理,请记住Git存储提交,而不是直接存储文件。这些提交中的文件来自Git的索引,而不是您的工作树。文件索引副本的格式与Git用于冻结所有时间提交的内部格式相同:数据是预压缩的。因此,索引中的每个文件的副本已经与工作树中使用的副本有很大不同,因为工作树中的副本不是Git blob对象,通常也不是zlib压缩的

Git先将提交读取到索引中,然后再将它们复制到工作树中。在一个文件上运行
git add
会压缩并blob-ife该文件,以便将其存储在git的索引中。就在转换的这一点上,当Git正在压缩和Git-ifying一个文件(
Git-add
)或反Git-ifying和解压缩一个文件(
Git-checkout-index
或等效文件)时,Git插入额外的转换操作是很简单的

因此Git在这一点上做了自己的事情。Git可以做的事情只有直接内置的事情是,在离开索引的过程中,Git可以用
\r\n
行结束替换
\r\n
行结束,在进入索引的过程中,Git可以用
\r\n
行结束替换
\n
行结束

换句话说,您可以安排Git在存储文件之前丢弃一些回车符,在提取文件时添加一些回车符。如果同时执行这两项操作,则在工作树中会得到CRLF行结尾,在提交中会得到仅换行的行结尾

如果愿意,您可以让Git只执行以下操作之一:特别是,使用
crlf=input
设置,您可以告诉Git:在工作树上执行一次转换,以索引复制操作

如果在提取文件时选择Git-do转换,那么这里唯一可用的转换就是将LF-only转换为CRLF。不能将CRLF结尾转换为仅LF结尾。如果在Git中提交的文件具有CRLF结尾,则在工作树中提取的文件将具有CRLF结尾

同样,这些转换中的每一个都只在一个方向上发生:

  • 索引→ 工作树:可选地,将
    \n
    替换为
    \r\n
  • 工作树→ 索引:可选地,将
    \r\n
    替换为
    \n
使用
core.autocrlf
.gittributes
指令选择的是:

  • text
    -text
    和/或
    core.autocrlf
    :哪些文件
  • eol=…
    和/或
    core.eol
    :接受哪种治疗
  • crlf=input
    :在哪个操作上
通过将文件复制到索引或从索引中复制来处理和转换文件后,Git通过从操作系统获取关键数据(文件大小和其他
lstat
系统调用值)将索引的副本标记为“与工作树的副本相匹配”。这里的具体细节各不相同,因为不同的操作系统以不同的粒度存储不同的数据

强制新转换的简单方法是删除文件的一个或另一个副本:
rm file
git rm--cached file
分别销毁工作树或索引副本,因此现在使用
git checkout--f