当git core.autocrlf设置为输入时,我们真正拥有什么

当git core.autocrlf设置为输入时,我们真正拥有什么,git,core.autocrlf,Git,Core.autocrlf,我在一个项目中有几个shell脚本。在windows中,每次我在LF和commit中使用它时,git客户端都会将本地文件转换为CRLF:我相信本地和git存储库都有相同的CRLF版本文件。然后,我将core.autocrlf更改为再次输入并提交,什么在本地,什么在git存储库中?我有这个问题是因为我观察到: 未配置core.autocrlf时: 将CRLF windows脚本更改为LF,git状态显示我有 修改了这些文件,并且仅修改了这些文件 git add.,git发出警告,本地文件再次位于C

我在一个项目中有几个shell脚本。在windows中,每次我在LF和commit中使用它时,git客户端都会将本地文件转换为CRLF:我相信本地和git存储库都有相同的CRLF版本文件。然后,我将core.autocrlf更改为再次输入并提交,什么在本地,什么在git存储库中?我有这个问题是因为我观察到: 未配置core.autocrlf时:

  • 将CRLF windows脚本更改为LF,
    git状态
    显示我有 修改了这些文件,并且仅修改了这些文件
  • git add.
    ,git发出警告,本地文件再次位于CRLF中。但
    git status
    显示本地分支与远程分支是最新的
  • 然后我将core.autocrlf配置为输入:

  • 将CRLF windows脚本更改为LF,
    git状态
    显示我有 修改了这些文件,并且仅修改了这些文件
  • git add.
    ,无警告,本地文件仍在LF中。但
    git status
    显示本地分支与远程分支是最新的
  • 然后问题是,在这两种情况下,本地分支与远程分支都是最新的。远程分支中有什么?LF或CRLF

    未配置core.autocrlf:

    core.autocrlf=输入:

    (你可以知道提交中的内容,但不能告诉你进行提交的方式。你必须使用低级工具直接查看提交。一般来说,但并不总是提交中的内容仅限于LF。)

    你把一些需要分开的概念混合在一起。这些概念是提交,这是Git真正的用途;工作树和索引,这是Git进行提交的方式。我将很快地介绍所有这些,因为我们必须有很多共同的术语和理解,然后才能深入了解CRLF和LF-only行结束语的工作原理

    提交、分支(如
    master
    )和远程跟踪名称(如
    origin/master
    请记住,Git是关于提交的。每个提交都有自己唯一的哈希ID。该哈希ID实际上是提交的真实名称。提交本身表示一组文件的永久且不可变的1快照,以及一些元数据,如提交人的姓名和电子邮件地址、提交原因(日志消息)以及提交父提交的原始哈希ID

    因为每个提交都记录其父级的哈希ID,所以我们可以从任何提交向后工作到其父级。我们说这个commit指向它的父对象。我们可以得出这种情况。如果我们让一个大写字母代表一个真正的散列ID(因为真正的散列ID太大太难看,人类无法记住和使用),我们可以绘制一个简单的三个提交存储库,如下所示:

    A <-B <-C
    
    我们可以与其他Git共享这些提交。我们的Git和他们的Git将始终使用相同的散列ID(请参见脚注1),因此它们具有完全相同的三个提交。但它们有自己的分支名称。他们的
    主机是他们的。目前,他们还指向(共享)提交C:

    A--B--C   <-- master (HEAD) [in their Git]
    
    现在,让我们在自己的存储库中进行新的提交。新的提交会得到一些丑陋的散列ID,这是新提交所独有的;我们称之为
    D
    。分支名称的特殊之处在于,当我们在某个分支上进行新提交时,Git会将新提交的哈希ID写入分支名称中,以便分支名称自动指向新提交:

    现在,我们将让我们的Git调用他们的Git,并获得他们没有的任何提交—在本例中只是提交
    E
    —并更新我们的
    源代码/master
    ,我们的Git使用它来记住他们的
    主代码,指向
    E

    A--B--C--E   <-- master (HEAD) [in their Git]
    
    A--B--C--E   <-- origin/master
           \
            D   <-- master (HEAD)
    
    git status
    告诉您您的分支机构是
    ahead 3
    时,这就是它的意思:我们在
    master
    上有三个提交,它们在
    master
    上没有(我们记住它们是我们的
    源代码/master
    )。当
    git status
    告诉您您的分支
    在1
    之后时,这也是它的意思:他们在
    主控上有一个提交(我们的
    源/主控
    ),而我们在
    主控上没有

    这就是
    git status
    所指的
    前方
    后方
    的全部含义:我们有他们没有的承诺,反之亦然,或者两者都有


    在某些情况下,提交可能会被遗忘,最终它们将消失,而散列ID将不再具有任何意义。但在它们消失之前,这种承诺实际上是永久性的。它是完全不可变的,原因很简单,哈希ID是该提交内容的加密校验和。如果您试图更改任何内容,即使是一个位,您得到的是一个具有不同哈希ID的新的、不同的提交。原始提交保持不变。因此,所有提交实际上都是不可变的


    索引和工作树 提交是不可变的。它们在时间上永远冻结:每次提交中的快照都不能更改,一点也不能更改。它们还存储在一种特殊的压缩Git-only格式中,可以说是冷冻干燥的,以节省空间。这对存档来说很好,它让你可以回去看看昨天、上周或任何时候都有什么,但它对完成任何新工作都毫无用处。如果您不能更改任何文件,那么Git有什么好处?此外,如果它们都是Git专用的,您将如何使用它们

    当然,Git允许您进行新的提交,但是要进行新的提交,您仍然需要更改一些文件。好吧,那个,或者删除一些,或者添加一些新的,或者这些的任意组合。所以Git必须有一种方法让你接受一个已经存在的提交并对它进行再水化,把它的所有文件都转换成有用的形式,在那里你可以看到
    A--B--C   <-- origin/master
           \
            D   <-- master (HEAD)
    
    A--B--C--E   <-- master (HEAD) [in their Git]
    
    A--B--C--E   <-- origin/master
           \
            D   <-- master (HEAD)
    
    A--B--C--E   <-- origin/master
           \
            D--F--G   <-- master (HEAD)
    
    Changes not staged for commit
    
    git add .
    
    git cat-file -p HEAD:A.txt
    
    $ echo foo | hexdump -C
    00000000  66 6f 6f 0a                                       |foo.|
    00000004