【问题标题】:Recovering files lost by git checkout (not staged/commited)恢复 git checkout 丢失的文件(未暂存/提交)
【发布时间】:2021-03-26 03:16:03
【问题描述】:

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

我有一个 git repo(在 GitHub 上有一个遥控器),我想创建一个新分支。我不会说我对 git 很陌生,我已经使用了很长时间并且喜欢认为我可以做一些体面的 repo 工作。

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

回到问题上来,我决定为我的合作伙伴创建一个新分支,他使用不同的数据文件。 我的工作树不干净,大约有 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

这删除了我的项目和数据文件,并为我的合作伙伴做好了准备。当我切换回主分支时,我因失去工作而愉快地头部中弹。我的数据文件仍然存在,但我所做的未暂存/提交的更改已经消失。

我现在尝试恢复这个大约 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:我不想恢复那些已删除的文件。我要恢复的是当我从主分支签出到另一个分支 (kicad) 时丢失的更改,我在其中删除了文件。

【问题讨论】:

    标签: git restore recovery


    【解决方案1】:

    编辑 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'd 文件不是包含相关更改的文件。

    现在根据他们最近的 cmets,这似乎不是真的。坦率地说,如果可以的话,我会删除我的答案,因为我对人们改变他们的故事并在我自愿提供帮助时浪费我的时间没有耐心。

    ====

    编辑:我一直在阅读您的 cmets,了解 rm'd 文件如何不是您要恢复的文件。我试了几次才明白发生了什么,因为你一直在暗示一些不正确的东西:当你改变分支时,改变就会丢失。

    在您执行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 仔细检查您是否知道您可能会丢失什么。

    【讨论】:

    • @Skaytacium 否。更改分支不会(也不会)删除任何更改。具体来说,更改到指向您当前已签出的同一提交的另一个分支不会更改您的工作树。如果您要签出到不同的提交并且如果该提交与您当前的提交之间的特定文件不同,则该文件将被替换 - 但在这种情况下, 如果您对文件进行了未提交的更改,您会收到警告并且不会发生检出。
    • @Skaytacium 根据您所说的发出的命令,您未暂存的更改是提交给另一个分支的更改之一。
    • 嗯,我认为它们是,而且在我看来,假装处于所需状态的文件存在于任何地方似乎是不负责任的。未暂存的更改是未暂存的。
    • @Skaytacium - 是的,这是正确的。当您更改分支时,对新分支中与旧分支中相同文件的任何更改 - 即,如果您更改到同一提交上的另一个分支,则所有更改 - 都会继续。
    • @Skaytacium - diff“不会”(即您认为不会)?还是“没有”(即您尝试过但没有变化)?当您说git add . 时,您的更改很可能已上演,即使您并不是要上演它们。需要明确的是:数据发生了三件事之一:(1)您明确删除了它(您没有显示任何命令); (2) 在你切换回你的分支后它仍然在工作树中(你说它没有);或 (3) 您不小心将其提交给您合作伙伴的分支机构。
    猜你喜欢
    • 2015-08-19
    • 1970-01-01
    • 2015-07-11
    • 2019-05-06
    • 1970-01-01
    • 2019-06-15
    相关资源
    最近更新 更多