怎么回事? GIT看到没有变化的变化

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

Git会在干净克隆后立即看到更改。

我只是从服务器克隆项目,并且我的一个文件已经标记为已更改。

nick@DESKTOP-NUMBER MINGW64 /d
$ git clone http://nick@host/nick/test.git
Cloning into 'test'...
remote: Enumerating objects: 27, done.
remote: Counting objects: 100% (27/27), done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 27 (delta 8), reused 0 (delta 0)
Unpacking objects: 100% (27/27), done.
error: failed to encode 'Var.not' from UTF-8 to Windows-1251

nick@DESKTOP-NUMBER MINGW64 /d
$ cd test/

nick@DESKTOP-NUMBER MINGW64 /d/test (master)
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   Var.not

no changes added to commit (use "git add" and/or "git commit -a")

error: failed to encode 'Var.not' from UTF-8 to Windows-1251可以使用VTF以UTF-8代码打开文件,带有一些不可读的符号-通常是Windows-1251。但是有什么问题吗?相邻文件“ Var.yes”具有相同的文本和相同的代码页-没问题,没有伪更改。

如何解决?

git utf-8 encode windows-1251
1个回答
0
投票

您在a comment中添加的这一信息很重要:

我只在行.gitattributes中使用*.* text working-tree-encoding=Windows-1251

working-tree-encoding指令有很多副作用。有关更多详细信息,请参见the gitattributes documentation,但稍后我会在该页面中再引用一点。

此错误消息来自您上面的问题:

error: failed to encode 'Var.not' from UTF-8 to Windows-1251

建议此文件的内容实际上未存储为UTF-8数据。

gitattributes文档中列出的陷阱之一是:

例如,Microsoft Visual Studio资源文件(*.rc)或PowerShell脚本文件(*.ps1)有时被编码为UTF-16。

也许您的Var.not文件就是这种情况。

无论如何:

我是否错误并以某种方式对工作树进行编码编辑并重新保存文件?

是的,这就是工作树编码的作用。确切地说,我们需要讨论Git如何在内部存储文件,然后将它们提取到您的工作树中,以便您可以使用它们,或将它们从工作树中复制到内部格式。

Git内部:blob对象,或文件如何被永久冻结

Git并不是真正关于files,而是关于commits。每次提交后,(基本上)是永久的,并且(完全)是只读的/不可更改。提交holds文件,或者更准确地说,具有引用to文件,因此通过存储提交,Git有效地存储文件。

不过,文件的form在存储中很重要。

通常,Git只承诺文件是一袋字节。无论您存储在文件中的字节是多少,Git都会为您找回它们。原始数据文件就是这种情况-对于您在.gitattributes中说为-text的文件。如果您不要求Git乱搞all文件,就是这种情况,即,您不将它们标记为text并设置CRLF行尾或working-tree-encoding之类的选项。但是,如果您做得到……好吧,首先,让我们继续研究一下字节袋文件的工作方式。

Every提交存储Every文件的副本-但具有重复数据删除功能!假设您有一千次提交,每个提交都有一千个文件。这意味着Git可以存储一百万个各种文件的版本。但是这些文件的most是相同的。也就是说,回到第一次提交时,您可能已经创建了一个名为README.md的文件。您在文件中放入一些文本,然后将文件放入第一次提交。

之后,您还使用same README.md再次提交了99次。然后,您对其进行了一些更改,并使用README.md的第二个版本进行了其余的900次提交。提交中的

The files

就像提交本身一样,一直冻结。因此,无需制作1000个单独的README.md版本。我们只需要two版本:第一个和第二个。前100个提交所有shareREADME.md个。最后900次提交全部与第二次提交共享。

为了快速执行此操作并节省空间,Git使用字节包文件进行的操作是[[compress

(使用zlib deflate)并将其存储在Git称为blob对象。就像每个提交都获得唯一的哈希ID一样,此Blob对象获得唯一的哈希ID。第一个README.md的哈希ID基于其中的数据字节。第二个README.md的哈希ID基于该第二个README.md中的数据字节。因此,只有两个Blob对象,在所有1000个提交中共享,每个提交都引用具有正确的冻结README.md内容的对象。所有这些的结果是,每次提交的文件存储都由这些冻结的压缩

blob

对象组成。我喜欢将这种形式的文件称为“冻干”文件:它们就像冻干的咖啡,您必须在其中加水。给冻干的文件补水可以得到原始内容-原始的字节包-返回。
因此,要

签出

提交,Git必须重新为其所有冻干文件补水。该提交包含冻干(且不可修改!)副本。 work-tree保存常规格式的文件。我们待会儿再讲这个。
Git内部:索引,A.K.A。舞台区域

当您进行

new提交时,Git必须将所有文件打包为新的或重复使用的冻结Blob对象。其他版本控制系统通过例如重新冻结每个文件来完成此操作。这太慢了!相反,Git做一些聪明的事情。

当您首次检出一些现有提交时,Git不仅会重新补充其文件。 Git还存储了对现有冻干副本的引用。在[[current提交中,这些文件以其冷冻干燥的副本形式存在于Git所称的文件中,这些文件的名称分别为

index

staging area或(最近很少)缓存换句话说,索引列出了将此提交提取到工作树中所需的所有Blob哈希ID。当您修改工作树中的内容时,索引没有任何反应。您必须在每个修改的文件上运行git add <file>。此git add步骤

复制

文件

来自

工作树。它将字节重新压缩为内部冻干形式。如有必要,这将在现场创建一个新的Blob对象。现在,Git在索引中具有冻结格式的随时可提交文件的哈希ID。
换句话说,索引始终都包含准备就绪的next提交。如果要在下一次提交

in

中更新已更新的文件,则必须在其上运行git add。这将通过查找或创建内部blob对象的方式将文件复制到索引中,并且该索引再次包含next提交,可以使用了。
这也是为什么,您必须继续运行git add。更新工作树文件

不影响索引

,并且更新git commit 根据索引中的内容进行新提交。如果不在索引中,则不在新提交中。无论索引中的是什么,that新提交中的内容。
注意git status的工作者:

    比较HEAD提交给索引。无论文件是什么[[different,Git都会说
  1. 暂存提交
。当两个文件相同时-当它们是相同的Blob对象时-Git什么也没说。

将索引与工作树进行比较。只要冻干工作树文件会有所不同,Git都会说未暂存提交。当两个文件相同时(经过适当的补液或冷冻干燥后),Git什么也没说。

  • 因此索引或登台区域实际上就是要提交的内容。您的工作树仅存在,因此您可以

    使用您的文件。这些文件实际上从未提交过:提交的是索引中的冻干文件。[.gitattributes影响冷冻干燥和补液过程

    注意,每次文件来自Git out时,都必须重新补水。请注意,每次文件进入索引/暂存区时,都必须将其冻干。这些进程

    always

    通过使用zlib deflate压缩字节包文件或酌情使用zlib inflate来重新生成字节包文件。 zlib deflate / inflate是一种保留数据的操作:它从不

    changes任何字节。但是因为Git已经在处理每个文件的每个字节,所以这也是change字节的理想位置。例如,假设我们希望冻干文件始终使用换行结尾,但是Windows上的工作树文件使用CRLF行结尾。我们可以告诉Git:

    为文件补水时,将\n更改为\r\n(仅LF更改为CRLF)。

    冷冻干燥文件时,将\r\n更改为\n(仅将CRLF更改为LF)。>

    因为Git从索引(冻结干燥)提交,而不是从工作树(重新水化)提交,这使我们得到了我们想要的东西。为此,我们要做的就是编写:
    • *.txt text eol=crlf
    • 但是我们可以做的不只是LF / CRLF翻译。实际上,使用Git称为
    • clean

    smudge

    过滤器,我们可以插入自己的任意操作。 (这就是Git-LFS的工作方式。)或者,在这种情况下,我们可以设置working-tree-encoding
    工作树编码会影响冻干和补水

    工作树编码设置告诉Git:补液时,假定原始文件为UTF-8,然后重新编码为工作树编码。

    进行冷冻干燥时,假定原始文件为工作树编码,并在执行通常的zlib放气之前转换为UTF-8。

    为此,blob对象

      必须实际上
    • be
    • UTF-8。此外,此操作(对UTF-8进行任何操作,对UTF-8进行任何操作)都需要保持一致:如果不一致,则每次提交都可以将一些随机重新编码为UTF8。
  • 有关陷阱的更多信息(超过gitattributes文档所提及的信息),请参阅Joel on Software: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!),然后例如,this article on Unicode combining characters and normalization,它表明两个

    look相同(“Zoë”)的字符串可能用不同的字节顺序(将变音符号和字母E组合在一起,或使用带变音符号的小写字母E和Unicode字符)拼写。在您的情况下,最可能的问题是输入文件不是以UTF-8开头的(但可能是某种重新编码错误)。

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