无法放弃 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 不 理解 它们,您可能想以某种方式调整它们。不幸的是,进行上述调整几乎没有好的选择。
过滤器的方式——称为 clean 和 smudge 过滤器——的工作方式与 core.autocrlf
和end-of-line 处理工作。要自己理解它们,请从一些简单的事实开始:
任何 Git object 的内容——提交、树、blob 或带注释的标记——字面上 不能 更改。这是因为内容是通过其数据库密钥检索的,该数据库密钥是 必须匹配 的哈希 ID(当前为 SHA-1,将来可能是 SHA-3 或其他一些非常好的哈希)内容的计算哈希值。
您通过哈希 ID 检索提交。 master
或 develop
等分支名称仅包含该分支上最新提交的实际哈希 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最初只是调用索引。这不是一个很好的名字,所以这个数据结构有三个名字:index,staging 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 unchanged位forceGit来无论如何认为该文件是干净的。这是非常粗糙的解决方案,不是一个令人满意的解决方案,但它可以完成工作。
尝试git rm --cached -r .
在git reset --hard
之后
这是唯一对我有用的解决方案。
希望对大家有所帮助!
一两个星期前,我用一个简单的 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.texno 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 不 理解 它们,您可能想以某种方式调整它们。不幸的是,进行上述调整几乎没有好的选择。
过滤器的方式——称为 clean 和 smudge 过滤器——的工作方式与 core.autocrlf
和end-of-line 处理工作。要自己理解它们,请从一些简单的事实开始:
任何 Git object 的内容——提交、树、blob 或带注释的标记——字面上 不能 更改。这是因为内容是通过其数据库密钥检索的,该数据库密钥是 必须匹配 的哈希 ID(当前为 SHA-1,将来可能是 SHA-3 或其他一些非常好的哈希)内容的计算哈希值。
您通过哈希 ID 检索提交。
master
或develop
等分支名称仅包含该分支上最新提交的实际哈希 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最初只是调用索引。这不是一个很好的名字,所以这个数据结构有三个名字:index,staging 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 unchanged位forceGit来无论如何认为该文件是干净的。这是非常粗糙的解决方案,不是一个令人满意的解决方案,但它可以完成工作。
尝试git rm --cached -r .
在git reset --hard
这是唯一对我有用的解决方案。 希望对大家有所帮助!