还原以前进行的更改(或:撤消对.git/index的更改)
当我试图理解撤销各种git操作的方法时,我想到了一个场景,我不知道如何处理它。免责声明:我在“生产”中实际使用git时没有这种情况,但我仍然认为这不仅仅是一个学术问题 让我们看看下面的场景还原以前进行的更改(或:撤消对.git/index的更改),git,git-stage,git-plumbing,Git,Git Stage,Git Plumbing,当我试图理解撤销各种git操作的方法时,我想到了一个场景,我不知道如何处理它。免责声明:我在“生产”中实际使用git时没有这种情况,但我仍然认为这不仅仅是一个学术问题 让我们看看下面的场景 操作先前提交的文件:echo“some content”>>example.txt 阶段更改:git add example.txt 上次提交的签出更改:git checkout@--example.txt 意识到您选择了错误的文件,并且希望撤消最后一个命令以恢复更改(“某些内容”) 我认为发生在引擎盖下
- 操作先前提交的文件:
echo“some content”>>example.txt
- 阶段更改:
git add example.txt
- 上次提交的签出更改:
git checkout@--example.txt
- 意识到您选择了错误的文件,并且希望撤消最后一个命令以恢复更改(
)“某些内容”
git checkout index
这样的东西来还原它们
除非垃圾收集开始,否则从技术上讲,内容仍然存在。但我不知道如何将其取回,然后手动尝试以某种方式查找散列并使用git cat file
读取内容。例如,多次运行git add
也是如此,尽管在这里想要恢复之前进行的更改可能不是一个真正的用例。(或者,当从隐藏处弹出更改时?…)
所有这些问题归结为以下几个问题:
- 索引是否有类似于
的内容git reflog
是否被认为是像gitgit checkout@--file
这样的危险命令,在这里您可能会丢失您的工作reset--hard
- 是否有手动更改/重写索引的管道命令?(请参见上面的情况,其中对象仍然存在)
奖励:有没有其他方法可以签出单个文件而不立即将其暂存?您的幕后描述基本正确。唯一与此部件无关的是: 每次使用
git add进行暂存更改时,都会在.git/objects下创建一个blob对象/
在内部,git add
散列工作树文件中的数据内容,即lagit散列对象-w-t blob
。这并不一定会创建一个新对象:如果哈希内容已经在存储库中,它只会重新使用现有对象。现有对象可能已打包,即在.git/objects/pack
中,而不是作为单独的blob松散
此外,由于干净的过滤器,写入blob对象的内容可能与工作树中的内容任意不同。更常见的情况是,由于行结束设置,CR LF行结束与工作树中的内容不同。清洁过滤器和行尾设置部分(或大部分,取决于Git的使用情况)通过.gittributes
文件控制,部分(或大部分)通过配置中的设置控制
在任何情况下,重要的是获得blob对象的散列ID。blob对象肯定以松散对象或包文件的形式存在于.git/objects
目录中的某个位置。现在,git add
可以写入.git/index
(或者git\u index\u file
指示的任何其他文件):它将在暂存槽0处的索引中存储给定路径的条目,使用计算出的blob哈希和模式100644
或100755
,具体取决于工作树文件是否应在以后标记为可执行
如果你失去了它,你大部分都是运气不佳
[场景被截断,但它以git checkout HEAD--path
关闭索引项结束,其$path
表示$blobhash
和mode$mode
信息,和关闭路径中文件的工作树副本)
除非垃圾收集开始,否则从技术上讲,内容仍然存在。但我不知道如何将其取回,然后手动尝试以某种方式查找哈希并使用git cat file
读取内容
事实上,你不能:散列ID计算是一个复杂的过程,只有你有散列,你才能让Git溢出内容,但是如果你没有散列,你需要有内容。这是你的问题
如果这是一个非常重要的“如果”-内容是唯一的,因此,git add
确实创建了一个新的blob对象,并且您刚刚覆盖了索引中的blob引用,该blob对象确实不再在任何地方被引用。另一方面,如果git hash object-w
最终重用了一些现有的blob,则blob对象仍然被引用所以现在有两个有趣的例子:blob是唯一的,现在可以进行垃圾收集,或者blob不是唯一的,也不是唯一的
使用git-fsck--lost-found
或git-fsck--unreable
或git-fsck--hanging
(默认),您可以让Git遍历整个对象数据库,确定哪些对象是可访问的,哪些是不可访问的,并告诉您一些或所有无法访问的对象,和/或将这些对象的信息复制到.Git/lost-find
。如果无法访问blob对象,它将被列为这些无法访问或悬空的blob之一,或ha把它的内容写下来
git show :file # file in index at stage zero
git show :3:file # file in index at stage three, during merge conflict
git show HEAD:file # file in current commit
git show master~7:file # file in commit 7 first-parent hops back from master
git reset HEAD -- file # copy HEAD:file to :file leaving work-tree file undisturbed