无法放弃 git 中的更改

Can't discard changes in git

一两个星期前,我用一个简单的 find |sed|tar|xz|gpg bash 脚本提取了一些文件,将它们全部解压,然后将它们的内容放入 git 存储库中,提交,将下一个档案内容放入回购协议,提交(冲洗并重复)以获得更好的系统。

所有文件都是在我的两台计算机中的一台上编辑的,都使用 Arch Linux,在 TeXstudio 或 Vim.

我试图签出一个旧版本,但它失败了 --- 由于更改非常出色,它不允许我这样做。我尝试了所有我知道的方法,然后继续 Google 找出我不知道的东西。

关于这个主题还有许多其他问题。不幸的是,他们的回答对我没有帮助。为了完成,我将列出问题。

$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)

modified: Arcs/arc1.tex
modified: Arcs/arc2.tex
modified: Arcs/frontmatter.tex

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

还有,大家不用看,下面我已经做了很明显的。

git reset --hard
git -a commit
git stash
git pull

以及从索引中删除所有内容并将其添加回来。

Cant discard file changes in GIT

我不在Windows。此外,这应该与行尾有关,因为我是唯一的用户。没有理由出现奇怪的行尾。

Git refuses to reset/discard files

git reset --hard HEAD (among other possibilities)

git stash
git stash drop

git config core.autocrlf input
git rm --cached -r .
git reset --hard
git add .
git commit -m "Normalize line endings"

这不仅不起作用,而且增加了行为不当的文件数量,并且还向文件写入了 700 多行。 . .原因。它甚至不是行为不端的文件。

Can't seem to discard changes in Git

更多结束线内容。

How do I discard unstaged changes in Git?

git clean -df
git checkout -- .
git checkout -- ./.

git checkout-index -a -f

git checkout --force master

我没看到但还是尝试过的东西

我尝试提交更改 git commit -am "WORK DAMN YOU!" 然后 git revert --hard HEAD^

我也尝试从我的私人遥控器中拉取,但只是被告知本地存储库已经是最新的。

这非常令人沮丧。

尝试git config --global core.autocrlf true

根据a comment

It was .git/info/attributes. ... Why was that having such an effect? ... I need those [*.tex] filters ...

可以使用它们。您只需要知道 Git 不 理解 它们,您可能想以某种方式调整它们。不幸的是,进行上述调整几乎没有好的选择。

过滤器的方式——称为 cleansmudge 过滤器——的工作方式与 core.autocrlf 和end-of-line 处理工作。要自己理解它们,请从一些简单的事实开始:

  • 任何 Git object 的内容——提交、树、blob 或带注释的标记——字面上 不能 更改。这是因为内容是通过其数据库密钥检索的,该数据库密钥是 必须匹配 的哈希 ID(当前为 SHA-1,将来可能是 SHA-3 或其他一些非常好的哈希)内容的计算哈希值。

  • 您通过哈希 ID 检索提交。 masterdevelop 等分支名称仅包含该分支上最新提交的实际哈希 ID。

  • 每个提交存储其 parent 提交的原始哈希 ID 作为其内容的一部分,并存储导致 object 的树的原始哈希 ID blob objects 并因此为该提交生成快照。

要将新的 object 存储到数据库中,您需要将 object 提供给 git hash-object -w(或者 Git 在内部自行完成)。 Git 现在计算 内容的散列,包括给出 object 的类型和大小的 header,并存储值——内容——进入数据库并发出密钥。然后您可以在将来使用该密钥来检索内容。那时,Git re-checks 哈希:它必须匹配密钥。如果不匹配,则数据已损坏,Git停止。

因此,提交哈希必须与提交内容匹配,提交内容为树内容提供树哈希,为 blob 内容提供 blob 哈希。如果提交本身不是分支的尖端,则通过尖端提交返回到一些先前的提交,所有提交都是通过它们的哈希 ID 找到的。生成的数据结构是 Merkle Tree,它提供 Git 的 data-integrity 保证。

这意味着不能对already-committed内容进行任何过滤。然而,它 必须 在 already-committed 内容上完成,以便 Windows 用户可以有 CRLF 行结尾,例如。 Git如何解决这个悖论?

答案在于关于 Git 的另外几个事实:

  • 您不能直接使用提交内容。它们需要被提取到一个工作区,称为work-tree。 work-tree(或工作树,或者您喜欢拼写的其他方式)以 de-compressed 形式提取文件,可以在其中读取和写入它们。

  • 但是Git也添加了一个中间数据结构,Git最初只是调用索引。这不是一个很好的名字,所以这个数据结构有三个名字:indexstaging area缓存。例如,该索引密切关注 work-tree、缓存(因此第三个名称)stat 系统调用数据。来自当前提交的每个文件首先被提取到索引中,以其特殊的压缩形式保存它——实际上,只是直接使用原始的 blob 哈希 ID——这样索引就有,或者真的,有一个 引用到,提交中文件的副本。

  • 运行 git add 将文件 复制到 索引(实际上,将其添加为 blob object 进入主数据库并计算其哈希 ID,然后更新索引中的哈希 ID)。这意味着索引在任何时候都是 Git 将用于您可以进行的 next 提交的图像。这是它获得名称 暂存区 的地方。因为你可以用 git add 覆盖索引文件,所以它们在这里是可写的,而在提交中它们是不可写的。

  • 运行 git commit 将当前索引打包成一棵树 object,将其永久冻结——blob 哈希不再可变——并使用tree object 进行新的提交。

与其他版本控制系统相比,此索引是 Git 获得大量速度的原因。由于索引跟踪 work-tree,Git 可以比平常更快地做很多事情:例如,git status,可以在目录或文件上调用 stat并将结果与​​缓存的 stat 数据进行比较,而无需读取文件本身。

(索引在冲突合并期间也发挥了扩展作用。这与清洁和污迹过滤器以及 LF/CRLF 战争无关,但在我们谈论索引时值得一提。相反每个 file-to-be-committed 只有一个条目,索引可以包含三个 not-to-be-committed 条目:一个来自合并基础,并且 oe 来自正在合并的两个分支提示中的每一个。)

过滤的工作原理

我们现在可以了解过滤的实际工作原理了。让我们总结一下关于提交、索引和 work-tree:

的要点
  • git checkout 将提交树复制到索引,之后它与提交树完全匹配,但形式更适合跟踪 work-tree.
  • git checkout also 将每个提交的 file 复制到 work-tree,同时为其更新索引槽文件.
  • git add 将文件从 work-tree 复制回索引,以便将来 git commit 可以冻结索引。

现在,请记住,涂抹过滤器 应用于已提交的内容,因为它已变成 work-tree 文件。 clean filter 应用于 work-tree 内容,因为它变成了提交的——或者至少,to-be-committed——内容。 smudge过滤时间是LF-only行尾可以变成Windows用户的CRLF行尾,clean过滤时间是CRLF行尾可以变回LF-only行尾。

应用污迹滤镜的理想时间是在扩展文件时,即从索引复制到 work-tree。 应用干净过滤器的理想时间是在压缩文件时,即从 work-tree 复制到索引。所以这是 Git 做到了。

与此同时,索引的主要特点之一是速度。所以 Git 假设 在某种意义上应用污迹过滤器不会 "change" 文件。 work-tree 文件中的内容可能不再与解压缩的 blob 匹配,但是——至少从意图和目的来看——它仍然与你通过清理和re-compressing work-tree 文件。

当这个 不是 正确时,麻烦就来了。如果清理和 re-compressing 文件产生不同的内容,具有不同的哈希 ID 怎么办?答案是Git可能会注意到,而Git可能不会注意到,这一切都取决于index-as-cache和stat 数据保存在索引中,对比 stat 稍后系统调用传递的数据。

如果污迹和清洁过滤器是完美的镜像——所以污迹和 re-cleaned 文件总是与原始文件匹配——你可以 git add 提取后的文件,并且 Git 将更新保存的 stat 数据。只要不再次更改,Git 现在就会认为该文件是干净的。如果底层文件系统有不可靠的stat数据,可以使用索引的assume unchangedforceGit来无论如何认为该文件是干净的。这是非常粗糙的解决方案,不是一个令人满意的解决方案,但它可以完成工作。

尝试git rm --cached -r .

git reset --hard

之后

这是唯一对我有用的解决方案。 希望对大家有所帮助!