如何修剪git reflog历史
背景:
vscode插件git-graph可以方便查看git-commit-graph,效果很好,关键是交互性很好。
点选任意commit即可预览提交内容,实在是太方便了,比我之前用命令行上git log --graph --oneline强太多了。
但同时带来的困扰是能看到的信息(commit历史)太多了,让我眼花缭绕。
例如,为了修复一个issue,前后进行了10次git commit --amend。也就是一共11次提及历史记录。
git graph大概长这样

初衷:
实际上当我合并这次的修改之后,我只想保留最后一次的记录在reflog里,其他的10次提交历史都不要了。这就涉及到了git reflog修剪了。
实现:
首先,git 是通过HEAD找commit hash ID,然后每个commit都有parent commit,如此组成一条链式结构。
commit是描绘git-graph的主要依据,其实只要删掉一个commit就能改变git-graph的结果。
每一次提交都会在.git/objects目录下生成至少一个commit类型的文件,其完整的文件路径为.git/objects/12/34567xx... (这里假设这个commit hash id 是1234567xx...)
git cat-file -t可以查看.git/objects目录下的文件是tree、commit还是blob类型。
例如:
注意:不能删除当前分支上可达的commit,不然链就断了,git就无法正常工作了。前面提到的"其他的10次提交历史" 因为在当前分支已经不可达,所以可以删除
例如我想从git-graph删除一个hash为 1234567的commit
那么步骤为:
- 找到.git/objects/12/34567xx...
- 删除或者移动它 (建议移动到一个目录下,万一想要查看的时候还能还原)
因为git commit hash有缩写形式、引用形式、完整形式,但是.git/objects/下的文件名都是完整形式,这种事情当然要写个脚本来一劳永逸了。
#!/bin/bash
function zlipd() {
printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - $@ | gzip - dc 2> /dev/null
}
function move_intermediate_obj() {
local dst_path
dst_path=$1; shift
while [ -n "$1" ]; do
if [ -f .git /objects/ "${1:0:2}" / "${1:2}" ]; then
mv - v .git /objects/ "${1:0:2}" / "${1:2}" "$dst_path/$1"
fi
shift
done
}
# function migrate_intermediate_obj() {
# [ ! -d ./.git ] && { echo ".git dir not exist"; return; }
# [ ! -d ./intermediate_obj ] && mkdir -p intermediate_obj
# for f in $(git rev-list -n "${2:-1}" "${1:?params not enough}")
# do
# # echo "$f"
# move_intermediate_obj "$f"
# done
# }
migrate_intermediate_obj ()
{
[ ! -d ./.git ] && {
echo ".git dir not exist" ;
return
};
local dst_dir
[ -d . /output ] && dst_dir=. /output/intermediate_obj ;
[ -z $dst_dir ] && dst_dir=. /intermediate_obj ;
mkdir -p $dst_dir
if [ $ # -eq 1 ]
then
move_intermediate_obj $dst_dir "$1" ;
elif expr $2 + 0 > /dev/null 2>&1 # test $2 whether is number otherwise $? neq 0/1 if $2 non-integer argument
then
for f in $(git rev-list -n "${2:-1}" "${1:?params not enough}" );
do
move_intermediate_obj $dst_dir "$f" ;
done
else
move_intermediate_obj $dst_dir "$@" ;
fi
}
脚本使用方法:
source script.sh
migrate_intermediate_obj 1234567
脚本将会在当前目录下创建一个文件intermediate_obj,并将commit文件移动进去。
PS:在git gc的时候有些commit会被打包到.git/objects/pack文件夹下的pack后缀的文件里,这样的话在.git/objects/下就找不到这些commit文件了。
解决办法是使用git unpack-objects < .git/*.pack文件解压出来。(pack文件和index文件要事先从.git/objects/pack移出去该命令才会有效果)
PS2:git verify-pack -v .git/objects/pack/pack-xx.pack可以查看哪个pack文件包含你要的commit
如何修剪git reflog历史的更多相关文章
- Git清空历史,清空历史删除的文件,降低.git 文件大小
执行以下步骤之前 请做好源码备份 本操作用来清理github上面的历史删除文件,减少库的体积. 第一步骤 下载JDK环境和JAR包 https://rtyley.github.io/bfg-repo- ...
- Git reflog 引用日志使用详解
本章节主要介绍 git reflog 命令. Git 使用一种称为引用日志或"reflogs"的机制来跟踪分支顶端的更新. 许多 Git 命令接受用于指定引用或"ref& ...
- [译]git reflog
用法 git reflog 显示整个本地仓储的commit, 包括所有branch的commit, 甚至包括已经撤销的commit, 只要HEAD发生了变化, 就会在reflog里面看得到. git ...
- git reflog 和git log :no branch git 提交方式
git reflog 和git log的区别,外加git cherry-pick的一种用法 git reflog 可以查看所有分支的所有操作记录(包括(包括commit和reset的操作),包括已经被 ...
- Git相关二三事(git reflog 和彩色branch)【转】
转自:https://www.jianshu.com/p/3622ed542c3b 背景 git太常用了,虽然,用起来不难,但也有很多小技巧的东西... 1. 后悔药 哪天不小心,写完代码,没comm ...
- git 修改历史提交信息
当你不小心,写错了提交的注视/信息,该如何处理呢.理论上,SCM是不应该修改历史的信息的,提交的注释也是. 不过在git中,其commit提供了一个--amend参数,可以修改最后一次提交的信息. ...
- Git log和git reflog
1.git log log命令可以显示所有提交过的版本信息.显示信息如下: $ git log commit e1bdff6e4830e09383078c860f45334d03771b03 (HE ...
- git log 与 git reflog 的 区别
git log: commit 的版本日志 包含提交的版本 操作者 日期 (方便查看commit的版本,但是版本回退后,使用git log 看不到回退版本号之后的版本记录) commit ce0d69 ...
- git删除历史
Git如何永久删除文件(包括历史记录) 有些时候不小心上传了一些敏感文件(例如密码), 或者不想上传的文件(没及时或忘了加到.gitignore里的), 而且上传的文件又特别大的时候, 这将导致别 ...
- 利用git reflog找回错误的重置
在开发中经常需要reset分支,如果在reset前没有记住分支指向的提交ID,想要重置回原来的提交恐怕大多数开发者是重新拉取远程版本库,再rebase分支.但如果连不上远程版本库或没有远程版本怎么办呢 ...
随机推荐
- Day16自定义异常
package com.exception.demo02;//自定义的异常类public class MyException extends Exception{ //传递数字>10抛出异常 p ...
- 学习ASP.NET Core Blazor编程系列十——路由(上)
学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...
- 本人常用的sed命令用法
如果使用sed命令修改文件,需要为sed命令指定[-i]选项(i,insert表示插入指令),下面是本人常用到的几种场景: 1. 在文件最后一行的下一行添加配置 如:在配置文件/etc/profile ...
- SpringCloud(七) - 微信支付
1.开发文档 微信开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 安全规范:https://pay.weixin.q ...
- php自定义分页类
<?php class Paging { private $totalStrip; //总条数 private $pageStrip; //每页条数 private $totalPages; / ...
- windows10熄屏断网问题解决
以前用windowsserver的操作系统可以随时随地的远程,最近因工作需要安装了一个windows10的远程设备,发现windows10系统长时间未使用便连不上了,远程不了,ping不通,本地连接断 ...
- 老板:你为什么要选择 Vue?
大家好,我是 Kagol,Vue DevUI 开源组件库和 EditorX 富文本编辑器创建者,专注于前端组件库建设和开源社区运营. 假如你是团队的前端负责人,现在老板要拓展新业务,需要开发一个 We ...
- 2.10:数据加工与展示-pandas清洗、Matplotlib绘制
〇.目标 1. 使用pandas完成基本的数据清洗加工处理: 2. 使用Matplotlib进行简单的数据图形化展示. 一.用pandas清洗处理数据 1.判断是否存在空值 数据缺失在很多数据中存在, ...
- 【Zookeeper】结构、应用、安装部署与参数、客户端命令行操作、API应用、内部原理(选举机制、写数据、监听器)
一.Zookeeper入门 1.概述 分布式服务管理框架(存储和管理数据) Zookeeper=文件系统+通知机制 2.特点 主从集群 半数以上,正常工作 请求顺序执行 数据更新具有原子性 3.数据结 ...
- 【大数据面试】sqoop:空值、数据一致性、列式存储导出、数据量、数据倾斜
一.有没有遇到过问题,怎么进行解决的 1.空值问题 本质:hive底层存储空数据使用\n<==>MySQL存储空数据使用null 解决:双向导入均分别使用两个参数☆,之前讲过 2.数据一致 ...