恢复git reset --hard删除的文件

在一次Git操作中,由于文件名特殊字符导致提交失败,误用git reset --hard命令后,通过git reflog和git fsck恢复未提交的文件。文章详细介绍了如何通过.git/lost-found目录和.git/objects查找并恢复已git add但未提交的文件。

吐槽

在说恢复方法之前,先说下缘由。今天在转载完缓存算法之后,就打算把文件给同步到github上,以做备份。然后像往常一样打开git bash,在git add时遇到了错误,无法进行git add,因为我使用了hexo new进行生成文件,而hexo new生成的文件中,文件名的小括号和中括号都会变成’—‘,也就是说 [转载] 变成了 -转载- ,而git bash无法识别 - ,所以造成无法提交,这时,我灵机一动,想到将其他的所有文件都移出去,然后 git add . 来添加然后再提交(因为其他文件有改动,所有想把此文件单独提交后再来进行全部的提交),移出之后我发现原来已经执行过 git add . 了,没办法,那就重置吧,但是我从网上找来一篇文章, git reset --hard ,再然后,悲剧上演~

所以,骚年们,以后一定不要那么随便的相信一篇博文,要对知识抱有一定的怀疑态度,然后多看几篇博文甚至官方文档。不过最终从stackOverflow上找出了解决方法~

恢复已提交远程仓库文件的方法

使用 git reflog 来找到最近提交的信息,这里贴出部分信息:

F:\voidy>git reflog
WARNING: terminal is not fully functional
5ccb94c HEAD@{2}: commit: 设计模式汇总
ba944a7 HEAD@{3}: commit: 组合模式
49bf0f5 HEAD@{4}: commit: 状态模式

使用 git reset ID 来恢复文件(第一列为ID)举个栗子:

比如说 设计模式汇总,那么执行 git reset 5ccb94c 好了,如果是一般的情况到此已经解决了。但是,我没有提交啊。那么该怎么办?

恢复仅提交到本地仓库文件的方法

下面是StackOverFlow上一些人提供的方法:

If you didn't already commit your local changes (or at least stage them via `git add`, they're gone. `git reset --hard` is a destructive operation for uncommitted changes.If you did happen to stage them, but didn't commit them, try `git fsck --lost-found` and then search through the contents of .git/lost-found - it will contain all of the objects that aren't referenced by a known commit, and may include versions of files that were staged.You can recover anything you git added, with git fsck --lost-found and poke around in .git/lost-found. find .git/objects -type f | xargs ls -lt | sed 60q will give you the last 60 things to get added to the repo, that'll help.Anything you didn't git add is gone as surely as if you'd deleted it yourself.

我总结一下吧,其实呢,就两步:

1.首先执行:

find .git/objects -type f | xargs ls -lt | sed 60q

这里60q的意思是最近60次的add,然后会出来这么个东东:

$ find .git/objects -type f | xargs ls -lt | sed 60q
-r—r—r— 1 Y Administ 222 Feb 3 21:00 .git/objects/02/18fb759136a0ee550d2e4d179f01bd75af48a0
-r—r—r— 1 Y Administ 176 Feb 3 21:00 .git/objects/5c/cb94ce63fd5196db10dffa6bab149c8b30546e
-r—r—r— 1 Y Administ 777 Feb 3 21:00 .git/objects/d5/177a8da396b5d6450d2c8e6ecf2f3ad8e41cd2
-r—r—r— 1 Y Administ 1387 Feb 3 21:00 .git/objects/e0/7e9099c0b27a4dd1a432db0bbf2112ca544ebd
-r—r—r— 1 Y Administ 5480 Feb 3 20:38 .git/objects/74/ea02bfa7353be6095959503abdd7dc0a178f53
-r—r—r— 1 Y Administ 2701 Feb 3 20:38 .git/objects/7a/d366bac491f6793d9b7da0cc3e7fb5ba26d403
-r—r—r— 1 Y Administ 2597 Feb 3 20:38 .git/objects/a7/9c139160fa387b365629ead63f5818177d2e48
-r—r—r— 1 Y Administ 2458 Feb 3 20:38 .git/objects/c3/cc71cfa640e80731bb8080a6baad1c0f2efa44
-r—r—r— 1 Y Administ 2463 Feb 3 20:38 .git/objects/c5/71825cf23df3147e8854cd4903d00a08723db2
-r—r—r— 1 Y Administ 2666 Feb 3 20:38 .git/objects/e5/c001e1b2548ebc786f266b27941cbe7d93592a
-r—r—r— 1 Y Administ 1941 Feb 3 20:38 .git/objects/ec/08fe6869a6d1eb8cfb8b4e740da56f104a5646

此处仅仅截取一部分信息,然后就是恢复了。

2.再执行提取命令:

git cat-file -p ID > a.md

意思就是将ID所示的文件读取出来重定向保存到a.md文件内,ID是objects后的一串东西,比如恢复第一条记录(将之间的 / 去掉):

$ git cat-file -p 0218fb759136a0ee550d2e4d179f01bd75af48a0 > a.md

好了,以上。对了,忘了说了,恢复未提交的文件仅仅是 git add 过的,如果你连 git add 也没有执行,那么我就不晓得怎么做了,如果你知道的话,请告诉我,另外,一定要记着,没事不要执行 git reset --hard ~然后网上的教程什么的也不要轻信,要时刻对知识抱有一种怀疑的态度,包括本文~

转载:http://www.360doc.com/content/16/0219/11/10058718_535692779.shtml

<think> 首先,用户的问题是:“git reset --hard HEAD 与git reset --hard区别”。这是一个关于git命令的查询。 回顾之前的交互:用户一直在问git相关的问题,比如"cherry pick"和"git reset --hard HEAD",现在聚焦在"git reset --hard HEAD" vs "git reset --hard"的区别。 关键点: - "git reset --hard HEAD" 明确指定了重置到HEAD的位置。 - "git reset --hard" 可能在没有指定位置时使用默认位置。 在git中: - `git reset` 命令需要位置参数来指定要重置到的提交。 - 如果指定位置,比如 `git reset --hard HEAD`,它重置到当前的HEAD提交。 - 如果省略位置,如 `git reset --hard`,git 默认也会重置到HEAD,因为HEAD是默认的位置。 所以,实际上,`git reset --hard HEAD` 和 `git reset --hard` 在功能上是相同的,因为它们都重置到当前HEAD。 我需要用中文回答,并在回答后提出3-5个 §§相关问题§§。 结构化我的回答: 1. **直接回答问题**:解释两者在功能上没有区别,因为HEAD是默认位置。 2. **提供细节**:描述命令的作用,强调风险。 3. **格式要求**:回答后必须以"§§相关问题§§"开头,然后列出3-5个相关问题。 回答内容: - 核心:两者本质相同,都重置工作目录和暂存区到HEAD状态。 - 强调默认行为:在git中,`git reset --hard` 等同于 `git reset --hard HEAD`。 - 警告:这是一个危险的命令,会丢弃所有未提交的更改。 然后,根据这个问题和我的回答,提出相关问题。需要3-5个,参考之前的格式。 可能的 §§相关问题§§(基于git reset命令): 1. 如果省略位置参数,git reset --hard 是否会默认重置到HEAD? 2. 使用 git reset --hard 后如何恢复丢失的更改? 3. git reset --hardgit checkout -- . 在丢弃工作区更改上有何不同? 4. 在团队协作中,误用 git reset --hard 可能会导致什么问题? 5. 如何安全地测试 git reset --hard 命令而不丢失更改? 确保问题数量在3到5个。 最后,回答问题后,立即输出"§§相关问题§§",然后列出问题。 完整回答结构: - 先用中文解释区别。 - 提供代码示例或说明。 - 结束前输出"§§相关问题§§"和列表。 </think> ### Git Reset --hard HEAD 与 Git Reset --hard 的区别 #### 核心结论 **两者实质功能完全相同**: - `git reset --hard HEAD` 和 `git reset --hard` 都执行以下操作: 1. **强制重置工作目录**至 `HEAD` 指向的提交状态(即最新提交)。 2. **清空暂存区(Index)** 所有变更。 3. **永久丢弃**所有未提交的本地修改(包括未跟踪文件)。 ```bash # 等效命令(HEAD 是默认参数) git reset --hard # 隐式使用 HEAD 作为目标 git reset --hard HEAD # 显式指定 HEAD ``` #### 唯一区别:参数显式性 | 命令 | 参数说明 | |------|----------| | **`git reset --hard HEAD`** | 显式指定目标为 `HEAD`(当前分支最新提交) | | **`git reset --hard`** | 隐式使用 `HEAD` 作为默认目标(省略时自动补全) | #### ️ 共有的高风险 - **不可逆数据丢失**:两种写法都会删除以下内容且无法通过普通撤销恢复- 工作目录所有未提交更改 - 暂存区暂存的文件 - 新创建的未跟踪文件 - **唯一恢复途径**:依赖 `git reflog` 查找历史记录并还原。 > **安全提示**:始终先使用 `git status` 确认当前状态,再考虑 `git stash` 保存更改以避免误操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值