git 存储元素存储在哪里?数据结构真的是栈吗?
Where are the git stash elements stored? Is the data structure really a stack?
为了更好地理解 git stash,我想知道: git stash 的元素存储在哪里以及存储在什么数据结构中?在堆栈中?在有序集合中?
详情:
所有文档、文章和书籍(Git Internals 除外)都说 git 存储是一个 堆栈 。
最近,我发现您可以从存储中以任意顺序检索和删除元素——多么有用的功能。由于此功能和 A Hacker's Guide to Git,在我看来,藏匿处似乎是由某处 按时间顺序排列的引用集 组成的。但是,在 .git/refs/stash
中仅以合并提交的形式存储最新的存储元素(其中还包含创建存储元素的日期)。
是否有另一个 (top-secret pre-index stash-cache;) 数据结构保存所有存储元素?还是 git stash (list|pop|apply) 从其常规对象存储中检索元素?如何?
那么stash元素形成什么样的数据结构呢?合并提交的日期是否隐含地给出了元素的时间顺序?如果元素实际上存储在堆栈中,git 如何以任意顺序检索和删除元素?
如, all but the current stash are stored in the reflog for the reference refs/stash
. See the definitions of "ref" and "reflog" in the gitglossary。请注意,master
和 develop
等分支名称是一种引用,分别是全名 refs/heads/master
和 refs/heads/develop
的缩写。标签名称是另一种参考;标签 v2.2
实际上是引用 refs/tags/v2.2
.
大多数参考文献都以 refs/
为前缀。事实上,各种 HEAD——HEAD
本身,以及 MERGE_HEAD
、CHERRY_PICK_HEAD
、ORIG_HEAD
等等——是唯一的例外,大多数 那些 没有 重新记录。 HEAD
是唯一一个这样做的。
通常,reflog 条目只是线性编号:HEAD@{1}
或 master@{1}
是 "the commit to which HEAD
or master
pointed before its most recent update",master@{2}
是两步前的提交,依此类推。 gitrevisions 中对此进行了描述。为方便起见,current 值可以用 @{0}
引用:master@{0}
和 master
总是解析为相同的哈希 ID。如果 refs/stash
引用以与其他引用相同的方式使用,它将作为队列而不是堆栈工作——但它不是 used 那样。相反,git stash
代码明确地 删除了 个早期条目。
由于编号始终是连续的,删除一个条目会导致所有 更高 的数字下降一个。例如,如果您手动删除 master@{5}
,那么以前的 master@{6}
现在是 master@{5}
,以前的 master@{7}
现在是 master@{6}
,等等上。
当然,添加一个新条目会将所有内容推高一个。因此,当您创建一个新的 stash 时,以前 stash
又名 stash@{0}
的那个现在是 stash@{1}
。原来是stash@{1}
的现在是stash@{2}
,以此类推。对于其他 reflogs,比如 master
,没有人会调用这个 "pushing",它只是一个普通的队列在起作用。
一旦您 删除 stash@{0}
又名 stash
,但是,所有较高的条目——stash@{1}
、stash@{2}
和以此类推——下降一个,所以现在 stash
已经是 "popped" 而之前的 stash@{1}
只是 stash
。当然,您也可以 git stash drop stash@{4}
删除该特定条目,保留 0 到 3 并重新编号 5 及以上。请注意,任何特定存储的 git stash pop
仅表示 "apply and, if that seems to succeed, drop".
请注意,并非完全偶然,每个 reflog 条目 也 附有时间戳。您可以写 master@{yesterday}
或 master@{3.hours.ago}
并且 Git 将根据时间戳找到适当的 reflog 条目的哈希 ID。1 因为 stash标识符只是 reflog 条目,同样的语法在那里工作。 (我从来没有真正发现这在任何地方都有用,也许是因为我在工作时没有时间感,不记得现在是星期几现在,更不用说我工作的时候了早些时候做了一些事情。:-) ) 为了使用这些时间戳,most reflogs expire:默认情况下,旧的 reflog 条目将消失90 天后,或者仅 30 天,如果它命名的对象从同一引用的当前值不是 reachable。2 但是,[=默认情况下,10=] 本身免于此过期。所有这些都是可配置的:请参阅 the git config
documentation.
中的所有 gc.reflogExpire
设置
1如果您一天更新引用数次但每小时不超过一次,则 @{yesterday}
表示 @{24.hours.ago}
。如果每小时更新不止一次,再乘以 60:@{1440.minutes.ago}
。如果您每分钟更新多次,请再次乘以 60:@{86400.seconds.ago}
。分辨率没有比这更好的了。
2这就是 Git 保留 30 天但最终清除的方式,例如,被 git rebase
放弃的旧提交。 可达性 是由存储库中的标记、提交和树对象形成的有向无环图或 DAG 提供的一个关键概念。 (Blob 是 在 DAG 中,但不参与扩展它,因为它们始终是叶节点。因此,blob 本身可能可达或不可达,但它永远不会影响任何 其他个对象。)
为了更好地理解 git stash,我想知道: git stash 的元素存储在哪里以及存储在什么数据结构中?在堆栈中?在有序集合中?
详情:
所有文档、文章和书籍(Git Internals 除外)都说 git 存储是一个 堆栈 。
最近,我发现您可以从存储中以任意顺序检索和删除元素——多么有用的功能。由于此功能和 A Hacker's Guide to Git,在我看来,藏匿处似乎是由某处 按时间顺序排列的引用集 组成的。但是,在 .git/refs/stash
中仅以合并提交的形式存储最新的存储元素(其中还包含创建存储元素的日期)。
是否有另一个 (top-secret pre-index stash-cache;) 数据结构保存所有存储元素?还是 git stash (list|pop|apply) 从其常规对象存储中检索元素?如何?
那么stash元素形成什么样的数据结构呢?合并提交的日期是否隐含地给出了元素的时间顺序?如果元素实际上存储在堆栈中,git 如何以任意顺序检索和删除元素?
如refs/stash
. See the definitions of "ref" and "reflog" in the gitglossary。请注意,master
和 develop
等分支名称是一种引用,分别是全名 refs/heads/master
和 refs/heads/develop
的缩写。标签名称是另一种参考;标签 v2.2
实际上是引用 refs/tags/v2.2
.
大多数参考文献都以 refs/
为前缀。事实上,各种 HEAD——HEAD
本身,以及 MERGE_HEAD
、CHERRY_PICK_HEAD
、ORIG_HEAD
等等——是唯一的例外,大多数 那些 没有 重新记录。 HEAD
是唯一一个这样做的。
通常,reflog 条目只是线性编号:HEAD@{1}
或 master@{1}
是 "the commit to which HEAD
or master
pointed before its most recent update",master@{2}
是两步前的提交,依此类推。 gitrevisions 中对此进行了描述。为方便起见,current 值可以用 @{0}
引用:master@{0}
和 master
总是解析为相同的哈希 ID。如果 refs/stash
引用以与其他引用相同的方式使用,它将作为队列而不是堆栈工作——但它不是 used 那样。相反,git stash
代码明确地 删除了 个早期条目。
由于编号始终是连续的,删除一个条目会导致所有 更高 的数字下降一个。例如,如果您手动删除 master@{5}
,那么以前的 master@{6}
现在是 master@{5}
,以前的 master@{7}
现在是 master@{6}
,等等上。
当然,添加一个新条目会将所有内容推高一个。因此,当您创建一个新的 stash 时,以前 stash
又名 stash@{0}
的那个现在是 stash@{1}
。原来是stash@{1}
的现在是stash@{2}
,以此类推。对于其他 reflogs,比如 master
,没有人会调用这个 "pushing",它只是一个普通的队列在起作用。
一旦您 删除 stash@{0}
又名 stash
,但是,所有较高的条目——stash@{1}
、stash@{2}
和以此类推——下降一个,所以现在 stash
已经是 "popped" 而之前的 stash@{1}
只是 stash
。当然,您也可以 git stash drop stash@{4}
删除该特定条目,保留 0 到 3 并重新编号 5 及以上。请注意,任何特定存储的 git stash pop
仅表示 "apply and, if that seems to succeed, drop".
请注意,并非完全偶然,每个 reflog 条目 也 附有时间戳。您可以写 master@{yesterday}
或 master@{3.hours.ago}
并且 Git 将根据时间戳找到适当的 reflog 条目的哈希 ID。1 因为 stash标识符只是 reflog 条目,同样的语法在那里工作。 (我从来没有真正发现这在任何地方都有用,也许是因为我在工作时没有时间感,不记得现在是星期几现在,更不用说我工作的时候了早些时候做了一些事情。:-) ) 为了使用这些时间戳,most reflogs expire:默认情况下,旧的 reflog 条目将消失90 天后,或者仅 30 天,如果它命名的对象从同一引用的当前值不是 reachable。2 但是,[=默认情况下,10=] 本身免于此过期。所有这些都是可配置的:请参阅 the git config
documentation.
gc.reflogExpire
设置
1如果您一天更新引用数次但每小时不超过一次,则 @{yesterday}
表示 @{24.hours.ago}
。如果每小时更新不止一次,再乘以 60:@{1440.minutes.ago}
。如果您每分钟更新多次,请再次乘以 60:@{86400.seconds.ago}
。分辨率没有比这更好的了。
2这就是 Git 保留 30 天但最终清除的方式,例如,被 git rebase
放弃的旧提交。 可达性 是由存储库中的标记、提交和树对象形成的有向无环图或 DAG 提供的一个关键概念。 (Blob 是 在 DAG 中,但不参与扩展它,因为它们始终是叶节点。因此,blob 本身可能可达或不可达,但它永远不会影响任何 其他个对象。)