git fsck 结合 --lost-found 和 --unreachable

2024-06-09

我发现了很多有趣的帖子git fsck,所以我想对它们进行一些实验。首先我在这个问题之前阅读的资料来源:

  • 如何通过关键字在 GIT 存储库中找到无法访问的提交哈希? https://stackoverflow.com/questions/31388918/how-can-i-find-an-unreachable-commit-hash-in-a-git-repository-by-keywords

  • git fsck: --dangling 与 --unreachable 与 --lost-found 有什么不同? https://stackoverflow.com/questions/36621730/git-fsck-how-dangling-vs-unreachable-vs-lost-found-differ

  • 获取所有 git 提交的列表,包括“丢失”的提交 https://stackoverflow.com/questions/4786972/get-a-list-of-all-git-commits-including-the-lost-ones

我从这个仓库开始:

* 9c7d1ea (HEAD -> test) f
* cd28884 e
| * 7b7bac0 (master) d
| * cab074f c
|/  
* d35af2c b
| * f907f39 r # unreferenced commit
|/
* 81d6675 a

Where r是从一个独立的HEAD from a。 然后我想重新建立基础master on test,但我有一些未分阶段的更改,所以我这样做了:

git rebase --autostash test

获取(我没有显示r但它仍然存在):

* caee68c (HEAD -> master) d
* 2e1cb7d c
* 9c7d1ea (test) f
* cd28884 e
* d35af2c b
* 81d6675 a

接下来我运行:

$ git fsck
#...
dangling commit 6387b70fe14f1ecb90e650faba5270128694613d # stash
#...
$ git fsck --unreachable
#...
unreachable commit 6387b70fe14f1ecb90e650faba5270128694613d # stash
unreachable commit d8bb677ce0f6602f4ccad46123ee50f2bf6b5819 # stash index
#...
$ git fsck --lost-found
#...
dangling commit 6387b70fe14f1ecb90e650faba5270128694613d # stash
dangling commit f907f39d41763accf6d64f4c736642c0120d5ae2 # r
#...

第一个问题

为什么只有--lost-found版本返回r犯罪?为什么不是c and d之前rebase显示在无法访问的范围内?我以为我理解了阅读链接问题的区别,但我显然错过了一些东西。我仍然有完整的引用日志,但我想你不需要它,因为所有提交(除了那些与stash) 被引用。


我知道我应该创建另一篇文章,但第二个问题部分相关。出于好奇我尝试了一下:

$ git fsck --lost-found --unreachable
#...
unreachable commit 6387b70fe14f1ecb90e650faba5270128694613d # stash
unreachable commit d8bb677ce0f6602f4ccad46123ee50f2bf6b5819 # stash index
unreachable commit f907f39d41763accf6d64f4c736642c0120d5ae2 # r
unreachable commit 7b7bac0608936a0bcc29267f68091de3466de1cf # c before rebase
unreachable commit cab074f2c9d63919c3fa59a2dd63ec874b0f0891 # d before rebase
#...

第二个问题

结合这两个选项,我得到了所有无法访问的提交(而不仅仅是--lost-found and --unreachable),这是非常出乎意料的。为什么它会这样?


其中一些确实令人费解,并且似乎没有正确记录,但快速浏览一下内置/fsck.c https://github.com/git/git/blob/225365fb5195e804274ab569ac3cc4919451dc7f/builtin/fsck.c#L767-L801表明使用--lost-found:

  1. 打开--full;
  2. 打开--no-reflogs.

Item 1 isn't particularly interesting since --full is now on by default anyway, but the documentation really should call out that --lost-found disables --no-full. Item 2 explains most of the rest; I have a guess at the last part [Edit: the rest].

请注意,当您运行时:

git checkout master && git rebase --autostash test

这使得 Git 运行起来git stash push,这创建了一个由两个新提交组成的新存储。然后 Git 像往常一样进行 rebase,复制了cab074f and 7b7bac0提交,在原始版本中可见git log --all --decorate --oneline --graph输出,到新的2e1cb7d and caee68c提交在第二个输出中可见。

为什么只有--lost-found版本返回r犯罪?为什么不是c and d在无法访问的变基之前显示?

大概该提交仍在HEAD重新记录。这使得它可以通过引用到达 - 但因为--lost-found暗示--no-reflogs,这次就变得无法访问了。原件也是如此c and d:可以通过多个引用日志条目访问它们HEAD的重新记录和master's.

结合这两个选项,我得到了所有无法访问的提交(而不仅仅是--lost-found and --unreachable),这是非常出乎意料的。为什么它会这样?

That's more puzzling. [Edit: solved; see below.] Let's run these in order of your git fsck commands:

  • fsck 1 和 fsck 2:两者都发现自动存储提交。那是因为git stash push复制了原件refs/stash到存储重新日志,以便refs/stash可以指向自动存储w(工作树)提交。那么隐含的git stash apply && git stash drop (git stash pop)应用了藏匿物并将其丢弃,移动了stash@{1}条目返回到refs/stash并删除隐藏的引用日志。所以w来自自动存储的提交确实是“悬而未决”的。它不在refs/stash它甚至不在stash转发,因为git stash(ab) 使用此 reflog 作为“存储堆栈”。然而,它确实指出i从自动存储提交。

    然后,第一个 fsck 打印6387b70fe14f1ecb90e650faba5270128694613d并称其为“悬空”。这就是w被删除的提交。第二fsck, with --unreachable, adds d8bb677ce0f6602f4ccad46123ee50f2bf6b5819: 相应的i被删除的提交。

  • fsck 3:r并且重新调整的提交在以下情况下仍然不可见git fsck --unreachable因为它们是从引用日志中引用的。但现在,随着--lost-found,fsck 不查看 reflog。我们应该期待看到自动存储w提交,将r提交和预变基d,都像悬空一样。 [Edit: 按照comment https://stackoverflow.com/questions/66401232/git-fsck-combining-lost-found-and-unreachable/66405506?noredirect=1#comment117400592_66405506,这是错误的:w链接回i and d,所以这将隐藏d.]

    We actually see the w and r commits but not the d commit. Why not? This is my guess but it's easy to test if you still have the setup around: when you use git rebase successfully, Git creates or updates the pseudo-ref named ORIG_HEAD to remember the hash ID of the tip commit before the rebase completes. Note that this same name is used to remember the previous value of a ref after a successful git reset that moves one, and after any other operation that might move a branch name some distance (fast-forward merge, for instance).

    It's pretty obvious that git fsck must consider all of the various *_HEAD pseudo-refs as starting points for reachability. This, too, is not documented (and it's not even completely clear it's intentional here—the ref code has been under some fairly heavy rework lately, to support alternative ref backends).

  • fsck 4, just before your SECOND QUESTION section: either --unreachable turned off the pseudoref inclusion, or—I think this is more likely—you did something in between that touched ORIG_HEAD so that it no longer selected the original, pre-rebase d commit. [edit] Since --unreachable lists all unreachable commits, the fact that d is reachable indirectly from the autostash w commit is irrelevant, and we see everything.

如果您想报告 Git 文档错误,fsck 文档没有指出--lost-found暗示--no-reflogs,你应该这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

git fsck 结合 --lost-found 和 --unreachable 的相关文章

  • “*text=auto”和“*text=auto eol=lf”有什么区别?

    我正在读关于 gitattributes文件和强制行结尾的规则some https rehansaeed com gitattributes best practices line endings教程是这样写的 text auto and
  • 当 git 说它正在“解决增量”时,它在做什么?

    在存储库的第一次克隆期间 git 首先接收对象 然后花费大约相同的时间 解析增量 在克隆的这个阶段实际上发生了什么 的阶段git clone are 接收存储库数据库中所有对象的 pack 文件 为收到的包创建索引文件 查看头部修订版 显然
  • Git 提交到公共子模块(主分支)

    我有两个或更多项目 我们称它们为Foo项目 and 项目栏 有一些通用代码我放入了一个子模块 我的理解是 如果我从内部提交对子模块的更改Foo项目它将在一个超然的头脑中 只有所有Foo项目克隆人可以看到 master cd ProjectF
  • 递归地将整个文件夹添加到存储库

    我正在尝试向 GitHub 上的 master 分支添加一个分支 并将一个文件夹推送到该分支上 分支的文件夹结构如下所示 Social App Source Code Dev Trunk Social App 以及所有源代码文件都在最后一个
  • Git 子树导出和重新导入问题

    我有一个更大的 git 存储库 A 它与我的另一个项目 B 共享一定量的代码 为了使维护更容易 我决定使用公共代码 C 创建第三个存储库 然后通过git subtree 我准备了 A 中的所有内容 将通用代码放在文件夹 sub 中 并使用了
  • 如何比较本地 Git 分支与其远程分支

    我怎样才能看到diff本地分支和远程分支之间 git diff
  • VS Code / Bitbucket / SSH - 权限被拒绝(公钥)

    我试图通过 ssh 从 vscode 访问 bitbucket 但总是得到权限被拒绝 公钥 SSH 密钥位于 ssh 公钥已正确设置在bitbucket settings security sshkeys 按键已经过测试并且可以工作 启动后
  • 当我所做的只是压缩提交时,为什么 git-rebase 会给我带来合并冲突?

    我们有一个包含 400 多个提交的 Git 存储库 其中前几十个提交需要大量的反复试验 我们希望通过将许多提交压缩为单个提交来清理这些提交 当然 git rebase 似乎是最佳选择 我的问题是它最终会产生合并冲突 而且这些冲突并不容易解决
  • 分支和文件夹的 gitolite 权限

    在 gitolite 我想要 developers能够推送到除以下之外的任何分支master I want user1能够推送到任何分支 包括master 除了不是某个目录master 我该怎么做呢 这应该解决以下两个问题 repo are
  • Git 更新文件时更改默认 umask

    我的 Git 有问题 我在 Google 和 StackOverflow 中搜索了解决方案 但没有任何帮助 问题是 每次 git 更新工作目录中的某些文件时 当我签出分支或合并分支等时 文件权限都会更改 以便添加 可写到组 标志 如果该文件
  • Visual Studio 代码中的“Git:gpg 未能签署数据”

    全新安装 Linux 后 我尝试设置我的环境 并且不断收到Git gpg failed to sign the data在本地提交更改时出错 我使用的是 Visual Studio Code 专有版本 而不是开源版本 gitconfig u
  • Git fetch 在 for-each-ref 中不显示远程分支

    我有一个远程分支feature test2 我想把它拿过来 我跑 git fetch origin feature test2 我得到 From
  • 将环境变量从 fastlane 传递到 Xcode 构建阶段脚本

    是否可以 如果可以 如何 将环境变量从运行 fastlane 的脚本传递到 Xcode 运行脚本阶段 我的最终目标是在运行脚本阶段读取当前的 git 分支名称 我们的 CI 由 Team Foundation Server 运行 它执行以下
  • Emacs shell:保存提交消息

    我几天前开始使用 emacs 在 emacs shell M x shell 中使用 git 时遇到问题 当我 git commit 或 git commit amend 时 它会打开 vim 来编辑并保存提交消息 我对此表示同意 但我找不
  • git:推送单个提交

    假设我进行了多次提交 并希望挑选哪些提交到远程存储库 我该怎么做 在ascii中 C1 gt C2 gt C3 gt C4 我想推C2和C4 通过变基 重置 推送然后重置进行重新排序是否有效 C1 gt C2 gt C3 gt C4 gt
  • 使用 git 合并两个文件夹

    我正在和一些以前从未使用过 git 的人一起开发一个项目 由于不了解 git 的功能 他们创建了该项目的两个版本 开发版本和生产版本 这两个版本都存在于当前环境中 更复杂的是 除了旧的开发文件夹之外 另一个用户还创建了这些文件夹 所以项目目
  • 获得干净的 git 沙箱的最有效方法是什么?

    对于我的持续集成构建 我想确保我的 git 沙箱中没有存放任何杂散文件 并且没有任何文件被无意中更改 我知道关于git reset hard HEAD 这解决了部分问题 但我想我想做的是删除所有未跟踪和忽略的文件 我可以用蛮力的方式做到这一
  • 使用 git 同时维护不同版本的代码

    我有一个需要优化的代码 我想同时维护一组版本的代码 每个版本可以描述为一些功能 优化的组合 最终 我将决定哪个版本是最好的 我不想将这些版本合并为更少的版本 但是 我希望能够对 大 源文件进行 小 修改 这可能会跨版本转移 并且我希望这一修
  • git merge 和 git merge origin 之间的区别

    这不是一个关于git merge origin branch vs git merge origin branch git merge
  • 如何快速查看哪个 Git 分支是最新的?

    例如 如果 git 上有 4 个分支 如下所示 branch1 branch2 current branch branch3 newest commits here master oldest 我的问题是 如何从 git 命令行检查我当前的

随机推荐

  • C++ 中与追溯定义已定义类的超类最接近的事情是什么?

    假设我有课 class A protected int x y double z w public void foo void bar void baz 在我的代码和其他人的代码中定义和使用 现在 我想编写一些可以很好地对 A 进行操作的库
  • 查询对 git 存储库的最后一次提交而不进行克隆

    假设我希望从 URL 克隆一个大型 git 存储库 当且仅当在最后一次提交到 master 时n 比如 24 小时 我不想克隆它 因为对于这么大的存储库来说这相当耗时 我也不希望克隆它一次然后检查例如定期查看 git 状态 我希望能够知道克
  • 在良好的实践中,多少个 setIntervals 就太多了? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我喜欢用效果 不是太多 来为我的网站
  • 从 DER 格式的字符串 base64 编码创建 PrivateKey 和 PublicKey

    我的私钥和公钥位于 base64 的字符串中 使用 ANS1 DER 进行编码 我尝试创建 java 的实例PrivateKey and PublicKey byte llave2 DatatypeConverter parseBase64
  • 从 Android 的内部存储中删除文件夹吗?

    如何从内部存储中删除文件夹 包含某些文件夹和文件 文件夹下面有一些树 folder C2 folder 1 folder 1 gif 2 gif 3 gif 4 gif 2 folder 1 gif 2 gif
  • 包装 NLog 时如何保留调用点信息

    我有一个包装 NLog 的类 称为 NLogger 我的日志保存到我的数据库中 我遇到的问题是如何显示日志记录发生的位置 我有这个
  • 如何在 Java 中使用 SwingWorker?

    与我之前的问题相关 从Java中的另一个类调用重绘 https stackoverflow com questions 772713 call repaint from another class in java 我是 Java 新手 我看
  • React Hooks 背后的 JavaScript 机制是如何工作的?

    我的问题涉及使 React hooks 成为可能的 Javascript 机制 React 最近的发展允许我们创建钩子 即 对于 React 状态 使用简单的函数 例如 function App const someVar setSomeV
  • SqlDataSource和存储过程调用问题

    我偶然发现了一个问题 但无法自己解决 希望有人能帮我解决 所以 我在 SQL Server 2005 数据库中有一个简单的存储过程 CREATE PROCEDURE spTest pin varchar 128 AS BEGIN SELEC
  • TFS 2017 API;使用变量对构建进行排队

    我正在尝试创建构建请求并为 TFS 构建定义中定义的自定义变量指定新值 我想我可以在不先更新构建定义的情况下完成此操作 我将以下 JSON 发布到 URL http
  • 我想最小化@Transactional 的范围吗?

    不确定 范围 在这里是否是正确的术语 我使用 Spring 进行 JPA 事务管理 下面有 Hibernate 我执行数据库事务的方法是私有的 但是由于您只能在类或类上设置 Transactional公共方法 http static spr
  • 如何在扫描操作中使用 FilterExpression 查询 DynamoDB 中的对象数组

    如何使用扫描操作查询 dynamoDb 中仅包含 Tue 的对象数组 workingDays 键 我已使用过滤器表达式进行查询 但没有得到任何结果 var queryData TableName tableName FilterExpres
  • 如何在 d3.js 中的节点上制作双击事件?

    我想在节点上进行双击事件 所以我尝试了 on dbclick function d return http google com and bind dbclick function d alert hello 但一切都失败了 谁能帮我 完整
  • git:如何在多台电脑之间正确共享本地副本

    我拉了一些公共存储库 在这里和那里做了一些更改 我将它们提交给我的本地副本 我经常从远程获取公共存储库中的更改 有时 我会处理来自不同 PC 的本地副本 并且需要在 PC 之间移动整个源代码 以便它们共享完全相同的更改 有几次我搞砸了复制并
  • Python无法识别目录 os.path.isdir() [重复]

    这个问题在这里已经有答案了 我有以下 Python 代码来删除目录中的文件 由于某种原因 我的 svn 目录未被识别为目录 我得到以下输出 svn 不是目录 任何想法 将不胜感激 def rmfiles path pattern patte
  • 想要在Sql中获取两列的差异

    我想获取表的列的差异 我们的列名称为 Planned date 所以现在我想获取这两列的差异 A Planned Date of stop1 Planned Date of stop5 那么我如何编写查询来获取 A 的值 下面是我编写的示例
  • 将Redmine问题与SVN修订版联系起来的最佳方法

    我们使用 Redmine 进行问题和错误跟踪 我们添加了 SVN 集成 但通过这样做 它仅显示活动中的 SVN 修订 如果能看到由错误或问题引起的所有 SVN 更改 那就太好了 但这似乎不可能 有没有办法做到这一点 如果不是Redmine
  • 如何从命令行构建 .csproj 将日志写入指定位置?

    虽然 无日志 构建似乎可以顺利地与类似的东西一起工作 c Program Files Microsoft Visual Studio 9 0 Common7 ide VCSExpress Project1 csproj build 以下失败
  • 日期时间:打印为秒

    我有一个datetime目的 我想将其打印为秒数 即 1 分 30 5 秒应打印为 90 5 秒 似乎找不到办法做到这一点strftime 我认为对于您的情况 您最好使用 datetime timedelta 对象 它有一个函数可以完全满足
  • git fsck 结合 --lost-found 和 --unreachable

    我发现了很多有趣的帖子git fsck 所以我想对它们进行一些实验 首先我在这个问题之前阅读的资料来源 如何通过关键字在 GIT 存储库中找到无法访问的提交哈希 https stackoverflow com questions 31388