恢复因 git 结帐(而非 staged/commited)丢失的文件

Recovering files lost by git checkout (not staged/commited)

我知道这是一个愚蠢的错误,但听我说完。

我有一个 git 存储库(在 GitHub 上有一个远程),我想创建一个新的 b运行ch。我不会说我对 git 很陌生,我已经使用它很长时间了并且 我可以做一些像样的回购工作。

现在,这个 repo 大部分都是二进制数据,那是因为 repo 没有代码,而是它有我的软件使用的二进制专有数据文件。

回到问题,我决定为我的合作伙伴创建一个新的 b运行ch,他使用不同的数据文件。 我的工作树不干净,大约有 2 或 3 个修改过的文件和 1 个新文件。 我 运行 以下内容:

git branch kicad
git checkout kicad

(no error is shown about dirty working tree/uncommitted changes)

rm ./my_data_files
md partners_data_files

git add .
git commit

这删除了我的项目和数据文件,并为我伙伴的准备好了。当我切换回主 b运行ch 时,我因为失去工作而愉快地中了头。我的数据文件仍然存在,但我所做但未进行的更改 stage/commit 已经消失。

我尝试恢复这个大约 2 小时,但没有成功。

以下是一些命令的输出:

  1. git reflog
0fad3c8 ... checkout: moving from kicad to main
3b0a8dc ... checkout: moving from kicad to kicad
3b0a8dc ... checkout: moving from main to kicad
0fad3c8 ... reset: moving to HEAD

(This is when I realized changes were gone)

0fad3c8 ... checkout: moving from kicad to main
3b0a8dc ... commit: Initial Kicad Commit

0fad3c8 ... checkout: moving from main to kicad
0fad3c8 ... commit: Connected VCC, might have to redo due to uC stuff
  1. git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (1266/1266), done.
dangling blob acd050aef0bd6151b46f99ea038af062110622ad
dangling blob dae060387c5998e4c2461fbaf003558222eb30d0
dangling tree 1f21c30039821372359108c6bc747a7510f93ce7
dangling blob c53216ba759028d68c64ca80bb1cc23a3aa025a9
dangling commit d8b2cf1f8c088f9fcc6990bd788bbc18615ebe41
dangling blob e642369390cb27753f17fee430a60db08719115a
dangling blob 7004c58d393d1e54c6080a8bf4eae9a56f25c160
dangling blob 8914c8d1aa0d9857fc9dfd7680db9590916827b1
dangling blob aa9433c2a651ad8c9878274007f39e61562570d8
dangling blob 5fa66c17c63b384a8120dee4dbadb726427e372e
dangling blob 22b71a4553fe6af87528aafaeb50133e21ca9938
dangling blob 3197630158eb88f93d2626a3cca8c1dab52d50b8
dangling blob 0308d60f2b21f83d941fdff735888549d19f17b1
dangling blob 7f68dac2ec15393bea041d87541d1fbb360bc065
dangling tree 8588ef3d5242870e9aedf782674122ab20b8f28f
dangling commit 35d9c0eb3b49b808ffa2178a3f098fe7a4b44d91
dangling commit 38ed38b357bb113d6bd43d99b391711933db123b
dangling commit 371d767b784a7119b3523de88aeee85748f83230
dangling blob 539dccc2799619ccd7bd588b0615415f25f62bed
dangling blob c5fd0dc4261c1481f3a3991c2311440643df9aac
dangling blob 087ed8e94498048c6702fd098e0d948593d9d93b
dangling blob 2b5e415606b875839c782cb226762273b023793d
dangling blob c14e5265de71f27b74cc06fb461886753b495021
dangling blob db4f32caf30cdf922918315954ffa3d1d0e775d8

我试过重置、恢复、检查,但没有任何效果。

回购是 here。我读了一些回答说这是不可能的,但我不确定这个。欢迎任何回复,我很乐意提供详细信息。

编辑 1:我不是要恢复那些已删除的文件。我要恢复的是当我从主 b运行ch 检出到另一个 b运行ch (kicad) 时丢失的更改,我在其中删除了文件。

编辑 2:

只是回顾一下 - 问题中列出的步骤是

git branch kicad
git checkout kicad

(no error is shown about dirty working tree/uncommitted changes)

rm ./my_data_files
md partners_data_files

git add .
git commit

当多人告诉 rm 删除了数据(而不是任何 git 操作)时,OP 表示 rm 的文件不包含有问题的变化。

现在根据他们最近的评论,看来事实并非如此。坦率地说,如果可以的话,我会删除我的答案,因为当我自愿提供帮助时,我对人们改变他们的故事并浪费我的时间没有耐心。

====

编辑:我一直在阅读您关于 rm 的文件不是您要恢复的文件的评论。我试了几次才明白发生了什么,因为你一直在暗示一些不正确的事情:当你改变分支时,改变就会丢失。

在您完成 git checkout 之后,更改 仍然存在 作为未上演的 chagnes。

当你说 git add . 时,你就上演了它们。

当您提交合作伙伴的分支时,您也提交了这些更改。

当你切换回你自己的分支时,git 说“哦,好吧,你提交给那个 other 分支的更改与这个分支无关我们正在切换到“- 因为这就是分支。

所以你实际上有两个相关的问题:

  1. 您对合作伙伴的分支提交了可能不属于那里的更改

  2. 您需要在工作树中进行这些更改

所以你应该能够通过将你的分支与你的合作伙伴进行比较来找到你的分支。从那里您可以从他的分支签出单个文件以将这些更改恢复到您的工作树。

git checkout other_branch -- path/to/file

恢复工作状态后,您还需要清理另一个分支。类似的过程(将文件从您之前提交的状态检出到该分支上的工作树中)可能就足够了。

我也将保留原来的答案,因为最后的建议仍然适用。

====

git 绝不会知道从未上演的更改。报告此类更改的命令直接从工作文件中获取信息,因此如果这些信息消失了,git 就没有什么可以告诉您的了。如果您有备份,您可以从中恢复。

你提到 git 没有给出任何警告。由于您正在执行的命令(切换到与当前 HEAD 指向同一提交的另一个分支)不会影响工作树,因此 git 没有理由认为您在做任何危险的事情.直到随后的 rm - 一个非 git 命令 - 才丢失任何数据。

我的建议是:

  1. 如果您要做的事情需要您的工作状态,请使用 git stash(甚至 git stash -u)来获得干净的工作树状态同时能够恢复您的工作状态。 https://git-scm.com/docs/git-stash

  2. 对于此操作,您完全可以避免涉及您的工作树,方法是创建一个新的工作树 (https://git-scm.com/docs/git-worktree) 或再次简单地克隆。这将为您提供一个单独的工作区来创建新分支。

  3. 无论如何,您的工作树是最容易丢失数据的存储区域,因为那里的更改尚未添加到 git 的数据库中。因此,如果您打算对工作树做任何破坏性的事情(例如 rm 命令),您可以使用 git status 来仔细检查您是否知道您可能会失去什么。