`

如何找回git 中丢失的提交(commit)

    博客分类:
  • SCM
阅读更多

在玩git的过程中,常有失误的时候,有时把需要的东东给删了。
不过没有关系,git给了我们一层安全网,让我们能有机会把失去的东东给找回来。

Let’s go!

准备

我们先创建一个用以实验的仓库,在里面创建了若干个提交和分支。
BTW:你可以直接把下面的命令复制到shell里执行。

mkdir recovery;cd recovery
git init
touch file
git add file
git commit -m "First commit"
echo "Hello World" > file
git add .
git commit -m "Greetings"
git branch cool_branch git checkout cool_branch
echo "What up world?" > cool_file
git add .
git commit -m "Now that was cool"
git checkout master
echo "What does that mean?" >> file 

恢复已删除分支提交

现在repo里有两个branch

$ git branch
cool_branch
* master

存储当前仓库未提交的改动

$ git stash save "temp save"
Saved working directory and index state On master: temp save
HEAD is now at e3c9b6b Greetings

删除一个分支

$ git branch -D cool_branch
Deleted branch cool_branch (was 2e43cd5). $ git branch * master

git fsck --lost-found 命令找出刚才删除的分支里面的提交对象。

$git fsck --lost-found dangling commit 2e43cd56ee4fb08664cd843cd32836b54fbf594a

用git show命令查看一个找到的对象的内容,看是否为我们所找的。

git show 2e43cd56ee4fb08664cd843cd32836b54fbf594a commit 2e43cd56ee4fb08664cd843cd32836b54fbf594a Author: liuhui <liuhui998[#]gmail.com> Date: Sat Oct 23 12:53:50 2010 +0800 Now that was cool diff --git a/cool_file b/cool_file new file mode 100644 index 0000000..79c2b89 --- /dev/null +++ b/cool_file @@ -0,0 +1 @@ +What up world?

这个提交对象确实是我们在前面删除的分支的内容;下面我们就要考虑一下要如何来恢复它了。

使用git rebase 进行恢复

 $git rebase 2e43cd56ee4fb08664cd843cd32836b54fbf594a First, rewinding head to replay your work on top of it... Fast-forwarded master to 2e43cd56ee4fb08664cd843cd32836b54fbf594a.

现在我们用git log命令看一下,看看它有没有恢复:

 $ git log commit 2e43cd56ee4fb08664cd843cd32836b54fbf594a Author: liuhui <liuhui998[#]gmail.com> Date: Sat Oct 23 12:53:50 2010 +0800 Now that was cool commit e3c9b6b967e6e8c762b500202b146f514af2cb05 Author: liuhui <liuhui998[#]gmail.com> Date: Sat Oct 23 12:53:50 2010 +0800 Greetings commit 5e90516a4a369be01b54323eb8b2660545051764 Author: liuhui <liuhui998[#]gmail.com> Date: Sat Oct 23 12:53:50 2010 +0800 First commit 

提交是找回来,但是分支没有办法找回来:

 liuhui@liuhui:~/work/test/git/recovery$ git branch * master

使用git merge 进行恢复

我们把刚才的恢复的提交删除

 $ git reset --hard HEAD^ HEAD is now at e3c9b6b Greetings 

再把刚删的提交给找回来:

 git fsck --lost-found dangling commit 2e43cd56ee4fb08664cd843cd32836b54fbf594a

不过这回我们用是合并命令进行恢复:

 $ git merge 2e43cd56ee4fb08664cd843cd32836b54fbf594a Updating e3c9b6b..2e43cd5 Fast-forward cool_file | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 cool_file

git stash的恢复

前面我们用git stash把没有提交的内容进行了存储,如果这个存储不小心删了怎么办呢?

当前repo里有的存储:
$ git stash list
stash@{0}: On master: temp save

把它们清空:
$git stash clear
liuhui@liuhui:~/work/test/git/recovery$ git stash list

再用git fsck –lost-found找回来:
$git fsck –lost-found
dangling commit 674c0618ca7d0c251902f0953987ff71860cb067

用git show看一下回来的内容对不对:

$git show 674c0618ca7d0c251902f0953987ff71860cb067 commit 674c0618ca7d0c251902f0953987ff71860cb067
Merge: e3c9b6b 2b2b41e
Author: liuhui <liuhui998[#]gmail.com> Date: Sat Oct 23 13:44:49 2010 +0800 On master: temp save diff --cc file
index 557db03,557db03..f2a8bf3
--- a/file
+++ b/file
@@@ -1,1 -1,1 +1,2 @@@ Hello World ++What does that mean?

看起来没有问题,好的,那么我就把它恢复了吧:

$ git merge 674c0618ca7d0c251902f0953987ff71860cb067
Merge made by recursive. file | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)

备注

这篇文章主要内容来自这里:The illustrated guide to recovering lost commits with Git ,我做了一些整理的工作。

如果对于文中的一些命令不熟,可以参考Git Community Book中文版

其实这里最重要的一个命令就是:git fsck –lost-found,因为git中把commit删了后,并不是真正的删除,而是变成了悬空对象(dangling commit)。我们只要把把这悬空对象(dangling commit)找出来,用git rebase 也好,用git merge 也行就能把它们给恢复。

分享到:
评论

相关推荐

    git-hydra:一个 post-commit 钩子,它有助于将你的工作分成多个分支和 PR

    git-hydra 这是一个 git post-commit 钩子,它将新提交挑选到另一个分支中,有条件地创建分支并可选地创建一个 PR。 这使得快速开发多个独立功能并将它们拆分为分支和拉取请求变得非常容易。 !重要的! 这个钩子...

    Git 提交消息和变更日志生成框架 :book:

    有时在合并冲突解决期间完整条目丢失,人们忘记提及某些内容或问题与实际提交之间的链接丢失。如果我们可以使用git的提交历史来生成一个漂亮的变更日志,而无需任何额外的工作,那就太好了。这就是 git-journal 的...

    详解git仓库迁移的两种解决方案

    Git仓库迁移而不丢失log的方法 要求能保留原先的commit记录,应该如何迁移呢? 同时,本地已经clone了原仓库,要配置成新的仓库地址,该如何修改呢? 注意:如果使用了代码审核工具Gerrit,那么在进行操作之前...

    giti:git目录的永久观察者

    我很少staeg / commit /将对github / gitlab的更改推送到github / gitlab,因为我没想到有一天我的机器会坏掉,我所有的努力都会被破坏! (TBH,我是个懒人!) 在那场悲惨的事件之后,我决定更定期地上演/提交/...

    rockjaylee.github.io

    和修改过的文件添加到暂存区git commit -m "提交备注"将暂存区文件提交git checkout --恢复对文件的修改/仓库覆盖工作区git checkout .取消对多个文件的修改所有重置的内容将丢失/有风险git reset HE

    MitraIntimarga:网站 PT。 Mitra Intimarga

    合作伙伴Intimanga PT。 Intimarga 合作伙伴 如果你有 git 问题: /* 首先提交所有内容,因为它会丢失 */ git rm -r --cached 。 git 添加。 git commit -m "修复未跟踪的文件

    bootstrap4-snippets:适用于Atom编辑器的Handy Bootstrap 4片段

    Atom编辑器的Bootstrap 4... 创建功能分支:git checkout -b my-new-feature 提交更改:git commit -m'添加一些功能' 推送到分支:git push origin my-new-feature 提交拉取请求 :grinning_face_with_smiling_eyes:执照

    getSelectionTexts:getSelection 支持多个范围

    获取选择文本 getSelection 支持多个范围。 安装 npm install selection-... 提交您的更改: git commit -am 'Add some feature' 推送到分支: git push origin my-new-feature 提交拉取请求 :D 执照 麻省理工学院

    eslint-config-metarhia:用于Metarhia项目的ESLint配置

    如果发生在本地,提交,但是不用担心,您的提交消息不会丢失,您仍然可以在.git/COMMIT_EDITMSG找到它。 发行 协作者可以使用发布新版本 npm run release git push origin master --follow-tags npm p

    NoMoreLost:一个Android应用程序,这是一个致力于帮助人们找到丢失物品的平台

    快照资料下载宣传影片贡献分叉( ) 创建功能分支( git checkout -b my-new-feature ) 提交更改( git commit -am 'Add some feature' ) 推送到分支( git push origin my-new-feature ) 创建一个新的拉取请求...

    csproj-check:检查.csproj文件,以确保它们不引用丢失的文件

    安装npm i -g csproj-check 用法csproj-check # defaults to **/*csproj-check a/specific/project.csproj another/project.csproj添加Git预提交钩子ln -s `which csproj-check` .git/hooks/pre-commit

    textlint-rule-no-dropping-i:Textlint规则来检查马虎字

    textlint-rule-no-dropping-i这是一个检测丢失单词的... 创建功能分支: git checkout -b my-new-feature 提交更改: git commit -am 'Add some feature' 推送到分支: git push origin my-new-feature 提交请求请求:

    svn功能源代码py

    G=已管理丢失 ?=未管理 3.add filename: ?→ + 新增未受管理文件(已管理不操作) 4.delete filename: 删除 已管理未修改&已管理修改 → - G(~) 5.update [version]: 没有[version]-update 默认 有...

    branch-pruner-workflow:通过手动和自动截断分支的历史记录来减小repo的大小。 较新的提交和文件版本被保留

    这意味着您可以删除Git历史记录中任意选定点之前的所有具有先前和未使用文件版本的提交,而不会丢失具有所选分支树的新文件版本的新提交。 通常情况下,您永远都不要这样做,并且有。 但是,在某些情况下,定期...

    ImarketApp:使用 React-native 制作的 Marketplace 应用

    我市场一个很棒的市场,可以列出或购买不再需要的物品!关于该项目I Market 是为我位于... 分叉项目创建您的功能分支( git checkout -b feature/AmazingFeature ) 提交更改( git commit -m 'Add some AmazingFe

    ScanApi:子域枚举、子域接管监控 api 和 S3 存储桶扫描器

    扫描接口 子域枚举、子域接管监控 api 和 S3 ... 提交docker commit &lt;container&gt; scanapi:latest以避免丢失数据库中的数据。 终点 /enum/domain/&lt;domain&gt;/ 在后台启动子域枚举任务然后更新数据库 域例如: example.

    java后端源码-AppyBuilderPersonal:AppyBuilder离线-个人

    提交您的更改(git commit -am '添加一些功能') 推送到分支(git push origin my-new-feature) 创建新的拉取请求 个人版 这是个人版本,可以在 Windows、Linux 或 Mac 上运行以用于个人目的。 披露:请注意,由于...

    ALGORITHM:算法研究

    git commit -m "feat(kwj1270): 0000_알고리즘.java 문제풀이 추가" feat ,如果您上传新文件如果要修改上传文件的名称或变量名,请使用style refactor如果要对其进行修改以获取更有效的代码) fix是否发生运行时...

Global site tag (gtag.js) - Google Analytics