无法放弃git中的更改

时间:2018-08-07 01:50:44

标签: git git-checkout git-stash git-reset

一两个星期前,我用简单的find |sed|tar|xz|gpg bash脚本提取了一些我正在归档的文件,将它们全部解压缩,然后将它们的内容放入git repo中,提交,然后将下一个归档内容放入回购,提交(冲洗和重复)以便拥有更好的系统。

所有文件都是在我的两台计算机之一上使用TeXstudio或Vim都使用Arch Linux进行编辑的。

我试图签出一个旧版本,但是它被淘汰了--由于出色的更改,它不会让我。我尝试了我所知道的一切,然后在Google上找到了我不知道的东西。

关于此主题还有许多其他问题。不幸的是,他们的回答并没有帮助我。为了完整起见,我将列出问题。

  

$ git status
  在分支主管上
  未进行提交的更改:
    (使用“ git add ...”更新将提交的内容)
    (使用“ git checkout-...”放弃工作目录中的更改)

     

已修改:Arcs / arc1.tex
    修改:Arcs / arc2.tex
    修改:Arcs / frontmatter.tex

     

未添加任何更改来提交(使用“ git add”和/或“ 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^

我还尝试过从我的私人遥控器中拉出,但被告知本地存储库已更新。

这真令人沮丧。

3 个答案:

答案 0 :(得分:2)

根据a comment

  

.git/info/attributes。 ...为什么会有这种效果? ...我需要那些[{*.tex]过滤器...

可以使用它们。您只需要知道Git不能理解即可,您可能想以某种方式对其进行调整。不幸的是,进行上述调整的方法很少。

过滤器(称为 clean smudge 过滤器)的工作方式与core.autocrlf和行尾处理的工作方式直接相关。要自己理解它们,请从一些简单的事实开始:

  • 任何Git对象(提交,树,blob或带注释的标签)的内容实际上都不能更改。这是因为内容是通过其数据库密钥检索的,该数据库密钥是必须与匹配的散列ID(当前为SHA-1,将来可能为SHA-3或某些其他非常好的散列)内容。

  • 您可以通过其哈希ID检索提交。像masterdevelop这样的分支名称仅包含该分支上最新提交的实际哈希ID。

  • 每个提交都存储其父提交的原始哈希ID作为其内容的一部分,并存储树对象的原始哈希ID,该树对象通向blob对象,从而为该提交生成快照。 / p>

要将新对象存储到数据库中,请将该对象输入git hash-object -w中(或Git在内部自行完成此操作)。 Git 现在计算内容的哈希,包括给出对象类型和大小的标头,并将值(内容)存储到数据库中并发出密钥。然后,您将来可以使用该密钥来检索内容。那时,Git 重新检查哈希值:它必须与密钥匹配。如果不匹配,则表明数据已损坏,Git停止。

因此,提交哈希必须与提交内容匹配,提交内容将为树内容提供树哈希,而树内容将为斑点内容提供斑点哈希。如果提交本身不是分支的尖端,则通过向尖端提交返回一定数量的先前提交(全部通过其哈希ID)来找到该提交。最终的数据结构是Merkle Tree,它提供了Git的数据完整性保证。

这意味着不能对已经提交的内容进行任何过滤。但是,必须对已经提交的内容进行 操作,以便Windows用户可以使用CRLF行结尾。 Git如何解决这个矛盾?

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

  • 您不能直接使用提交内容。需要将它们提取到一个称为 work-tree 的工作区域。工作树(或工作树,或者您更喜欢拼写的树)具有解压缩格式的提取文件,可以在其中读取和写入文件。

  • 但是Git也添加了一个中间数据结构,Git最初只是将其称为 index 。这不是一个很好的名称,因此该数据结构包含三个名称:索引临时区域缓存 。该索引将选项卡保留在工作树上,例如缓存(因此为第三个名称)stat系统调用数据。首先,将当前提交中的每个文件提取到索引中,并以其特殊的压缩形式(实际上,仅直接使用原始的blob哈希ID)即可,以使索引具有或实际上具有引用,即提交中文件的副本。

  • 在文件上运行git add会将文件复制到索引中(实际上,将其作为blob对象添加到主数据库中并计算其哈希ID,然后更新索引中的哈希ID)。这意味着索引始终是Git用于您可以进行的 next 提交的图像。这就是它的名称​​ staging area 。因为您可以使用git add覆盖索引文件,所以它们在此处可写,而在提交中则不可写。

  • 运行git commit将当前索引打包到一个树对象中,并一直冻结它-Blob哈希不再可更改-并使用树对象进行新的提交。

与其他版本控制系统相比,该索引是Git如何提高其速度的方式。由于索引跟踪工作树,因此Git可以比平时更快地完成很多事情:例如,git status可以在目录或文件上调用stat并将结果与​​缓存进行比较stat数据,而不必读取文件本身。

(索引在冲突的合并中也起着扩展的作用。这与清除过滤器和弄脏过滤器以及LF / CRLF战争无关,但是值得一提的是我们在讨论索引时。不仅仅是一个条目对于每个要提交的文件,索引可以包含三个不提交的条目:一个来自合并基础,一个来自要合并的两个分支提示中的每个。)

过滤的工作原理

我们现在准备看看过滤是如何工作的。让我们总结一下有关提交,索引和工作树的关键点:

  • git checkout将提交的树复制到索引,此后它与提交的树完全匹配,但格式更适合于跟踪工作树。
  • git checkout 将每个提交的文件复制到工作树,同时更新该文件的索引槽。
  • git add将文件从工作树复制回索引,以便将来的git commit仅冻结索引。

现在,请记住,在已提交的内容上已应用了一个 smudge过滤器,因为它已变成工作树文件。 干净过滤器应用于工作树内容,因为它已变成已提交(或至少要提交)的内容。污点过滤时间是指仅LF的行尾可以变为Windows用户的CRLF线尾,纯净的过滤时间是指CRLF的行尾可以返回到仅LF的行尾。

应用污迹过滤器的理想时间是在文件扩展时 ,即从索引复制到工作树。 应用干净过滤器的理想时间是在文件被压缩时 ,即从工作树复制到索引。因此,这是 Git执行的时间。

同时,索引的主要功能之一是 speed 。因此,Git 假定,从某种意义上说,应用污迹过滤器不会“更改”文件。工作树文件中的内容可能不再与解压缩的blob匹配,但是(至少出于意图和目的)它仍然与通过清理并重新压缩工作树而得到的 匹配文件。

当此不是正确时,就会出现摩擦。如果清理并重新压缩文件会导致具有不同哈希ID的不同内容怎么办?答案是 Git可能会注意到,但Git可能不会注意到,这完全取决于索引即缓存的有效性和保存在索引中的stat数据的变化,与稍后系统调用传递的stat数据进行对比。

如果污迹和干净的过滤器是完美的镜像(因此污迹和重新清理的文件始终与原始文件匹配),则可以在提取后git add提取文件,Git会更新保存的stat数据。只要不再更改,Git现在就会认为该文件是干净的。如果基础文件系统具有不可靠的stat数据,则可以使用索引的假定未更改位来 force Git认为文件还是干净的。这是很粗略的,不是令人满意的解决方案,但可以完成工作。

答案 1 :(得分:1)

尝试git rm --cached -r .

git reset --hard之后的

那是唯一对我有用的解决方案。 希望对您有所帮助!

答案 2 :(得分:0)

尝试git config --global core.autocrlf true