git stash clear后如何恢复

为啥要恢复

昨天因为写代码的时候一下子忘记git pull upstream,所以就先把当前的修改git stash save暂存起来,代码拉下来以后,就习惯性的想输入git stash pop恢复刚才代码,然后手抖输入了git stash clear反向操作把暂存的全部清了,操作如下

[bigham@DESKTOP-MKMH2OT /d/Work_Space/vant-project]$ git stash save
[bigham@DESKTOP-MKMH2OT /d/Work_Space/vant-project]$ gp
[bigham@DESKTOP-MKMH2OT /d/Work_Space/vant-project]$ git stash clear
复制代码

然后输入git stash pop瞬间人麻了,提示没有任何历史,大量修改一下子没了。

解决方案

网上说,发现可以使用git fsck --lost-found显示之前所有的stash记录,如下


[bigham@DESKTOP-MKMH2OT /d/Work_Space/vant-project]$ git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (374/374), done.
dangling blob f94019b06efd6579106397257e89ee42eb846cd9
dangling commit 673a01f0feda0cb1bfffd80813637de1dd301d2c
dangling blob 720225cba2c9b56bac0a2f89d9bc7e2e58735e18
dangling blob 21438a2b9613e9d1b0c1ca8fc336b44770c12964
dangling blob 0125d98ea333928261d89f948930aa56c600e1a8
dangling blob 84ad1c2287429d8b19450c885c7e397d27217db4
dangling blob a8e511fa943f6840f7b3ad8876c120a071d309a5
dangling commit d4967c308e83189edd0b61661f0cb82e47b7f882
dangling blob 69571e30b84e8639d620723ec917bb2a9bc53da5
dangling commit d4967c308e83189edd0b61661f0cb82e47b7f882
...... 还有200多条
复制代码

然后输入git show id,忽略dangling blob 的类型的记录,只找 dangling  commit 的记录, 比如git show d4967c308e83189edd0b61661f0cb82e47b7f882, 会显示本次的改动点记录,找到符合的id,使用git merge id就会把之前stash的内容合并进来

[bigham@DESKTOP-MKMH2OT /d/Work_Space/]$ git show d4967c308e83
commit d4967c308e83189edd0b61661f0cb82e47b7f882
Merge: bb2f1da 337d569
Author: bighamD <******2@qq.com>
Date:   Sun Sep 19 16:26:29 2021 +0800

    WIP on main: bb2f1da 修復ios機型刷新丟失vuex

diff --cc .postcssrc.js
index 81f1884,81f1884..3187c01
--- a/.postcssrc.js
+++ b/.postcssrc.js
....
复制代码

尝试了几次git show后发现这玩意根本不是按照时间排序的,感觉就是随机的,这两百多条记录根本找到过来,总不能一条条尝试。所以写了一个简单的nodejs脚本找出正确的stash id

revert-stash.js

const child_process = require('child_process');

/**
 * 
 * @returns [ "673a01f0feda0cb1bfffd80813637de1dd301d2c", "d4967c308e83189edd0b61661f0cb82e47b7f882"]
 */
function qryStashIds() {
    return new Promise( (resolve, reject) => {
        child_process.exec('git fsck --lost-found', {encoding: 'utf8'}, (err, stdout) => {
            if (err) {
                return reject(err);
            }
            // 筛选出dangling commit的id
            let matches = stdout.match(/commit\s+([^\s\r\n]+)/g);
            if (matches) {
                matches = matches.map(m => m.replace(/commit\s+/, ''));
                resolve(matches);
            }
        })
    })
}
function taskGenertor(date, id) {
    return new Promise((resolve) => {
        child_process.exec('git show ' + id, {encoding: 'utf8'}, (err, log) => {
            if (err) {
                return resolve();
            }
            // 经过观察每个log都会带有下面这种日期标识,我们只要根据 传入的日期,筛选出符合的即可
            // Author: bighamD <******2@qq.com>
            // Date:   Sun Sep 19 16:26:29 2021 +0800
            const match = log.match(/Date:\s+([^+\r\n]+)/);
            if (match) {
                const stashDate = match[1].trim();
                // 说明这个记录是符合
                if (new Date(stashDate) > date) {
                    resolve(id)
                }
            }
            resolve();
        })
    })
}
async function matchRevertStashId(date) {
    const stashIds = await qryStashIds();
    return (await Promise.all(stashIds.map(id => taskGenertor(date, id)))).filter(Boolean);
}

// 比如我是2021-9-19执行了stash save操作
let match = await matchRevertStashId(new Date('2021-9-19'));
console.log(match);
// ["673a01f0feda0cb1bfffd80813637de1dd301d2c"]

复制代码

在终端 node revert-stash.js后,从几百条中筛选出符合的只有一条,此时git merge 673a01f0feda0cb1bfffd80813637de1dd301d2c,嘿嘿,代码都回来了。

网上说idea编辑器自带stash恢复操作,vscode我是没发现,可能是有或者插件有这种功能,git-len和git-history没发现有

参考:

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享