你的描述基本上是正确的。唯一不是百分之百与这部分有关的是:
每次转移更改时
git add
blob对象是在
.git/对象/
在内部,
Git添加
哈希工作树文件中数据的内容
git hash-object -w -t blob
. 这不是
必要地
创建
新的
对象:如果哈希内容是
已经在存储库中
,它只是重新使用现有对象。现有对象可能是
拥挤的
,即,在
.git/objects/pack
,而不是
释放
作为一个独立的整体。
此外,写入blob对象的内容
可以
是
任意地
与工作树中的内容不同,因为
清洁过滤器
. 由于行结束设置的原因,更常见的情况是,CR LF行尾与工作树中的内容不同。通过您的
.gitattributes
文件,部分(或大部分)通过配置中的设置。
在任何情况下,重要的是获得blob对象的hash id。blob对象肯定存在于
.git/objects
作为松散对象或在包文件中的目录。现在
Git添加
可以写入
.git/index
(或其他任何文件
GIT_INDEX_FILE
指示):它将在临时槽0的索引中存储给定
path
,使用计算的blob散列和模式
100644
或
100755
取决于以后是否应将工作树文件标记为可执行。
如果你失去了它,你多半是运气不好
[场景被截取,但以
git checkout HEAD --
path
用它的
$path
代表
$blobhash
和模式
$mode
信息,
和
在中删除文件的工作树副本
路径
)
除非垃圾收集在技术上仍然存在。但我不知道怎样才能把它弄回来,然后手动地寻找散列,并用
git cat-file
。
实际上,您不能:哈希ID计算是
trapdoor function
,只有当你
做
有散列可以让git溢出内容,但如果没有散列,就需要有内容。那是你的
Catch-22 situation
。
如果
这是一个相当重要的“如果”的内容
是
独一无二,所以
Git添加
真的创造了
新的
blob对象,
和
您刚刚覆盖了索引中的blob引用,该blob对象确实不再在任何地方被引用。另一方面,如果
git hash-object -w
在重用某些现有blob时,blob对象仍然被以前引用它的任何对象引用。所以现在有两个有趣的例子:blob
是
唯一的,现在可以进行垃圾收集,或者,blob是
不
独一无二的。
使用
git fsck --lost-found
或
git fsck --unreachable
或
git fsck --dangling
(默认情况下),您可以让git遍历整个对象数据库,确定哪些对象是
可达成的
不是的,告诉你一些或所有无法到达的,和/或从他们那里复制或关于他们的信息到
.git/lost-found
. 如果blob对象
是
遥不可及,它
将
被列为这些无法到达或悬挂的斑点之一,或将其内容还原为
.git/失物招领
.
这里的缺点是可能有几十个甚至几百个悬空的blob对象。现在你的任务已经从“猜杂烩”(实际上是不可能的)变成了“大海捞针”(不是那么困难,但是很乏味,你很可能会发现
错误的
针线不是大海捞针,毕竟是一堆针)。当然,这只适用于“blob是唯一的”情况。
特定问题的答案
(顺便说一下,这个问题
不是
真的是
Can git undo a checkout of unstaged files
. 但那本书还是很有用的,所以你也可以看看。)
有什么像
git reflog
为了索引?
不,你
可以
自己制作备份:只是
cp .git/index
在某个地方。但Git不会自己这么做。你可以在
Git结账头--
路径
操作,通过用于执行此类危险操作的别名或shell函数。
注意git不知道这些备份副本,所以
git gc
不考虑引用的对象受保护。将备份与管道命令一起使用的步骤
git ls-files
,将路径名放入
git_索引文件
在命令执行期间。
是
git checkout @ --
被认为是危险命令的文件,如
git reset --hard
你可能会失去工作的地方?
答案取决于谁在考虑。我建议你自己也考虑一下,因为你问的是这个问题。-)
有手动更改/重写索引的管道命令吗?(见上例,物体仍在那里)
对:
git update-index
是一次一项更新程序(使用
--cacheinfo
或
--stdin
提供原始索引项数据,而不是让它重复很多
Git添加
工作)。许多其他命令也会部分或整体更新索引。
如果您有一个在
git checkout HEAD -- ...
操作,可以从备份索引中读取条目(使用
GIT_INDEX_FILE=... git ls-files
例如)然后使用
git更新索引
,
没有
有
git_索引文件
设置,将信息放入常规索引中。当然,这是一个index-overwrite-y操作,您可能希望首先对索引进行另一次备份。
有没有另一种方法来签出单个文件而不立即暂存它?
不,只是因为动词
结帐
在这里。到
查看内容
在索引中或在任何commitso中的文件,其内容的名称为
git rev-parse
能理解使用
git show
:
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
可以覆盖索引中的一个或多个文件,而不接触工作树中的文件:
git reset HEAD -- file # copy HEAD:file to :file leaving work-tree file undisturbed
如果你给
Git重置
一个目录的路径,它重置所有已经在索引中并且位于目录中的文件。