如何修剪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分支.但如果连不上远程版本库或没有远程版本怎么办呢 ...
随机推荐
- 常用类.String类
package 常用类.String;import java.util.Arrays;import java.util.Locale;public class demo01 { public stat ...
- jQuery漏洞复现整理
jQuery DOM-based XSS 免责声明: 本文章仅供学习和研究使用,严禁使用该文章内容对互联网其他应用进行非法操作,若将其用于非法目的,所造成的后果由您自行承担,产生的一切风险与本文作者无 ...
- 高精度加法(Java)
题目描述 高精度加法,相当于 a+b problem,不用考虑负数. 输入格式 分两行输入. a , b ≤ 10^500 输出格式 输出只有一行,代表 a + b 的值. 思路 使用数组进行模拟, ...
- 2022春每日一题:Day 34
题目:lowbit求和 (没有找到哪个公开题库有这个题) 题意:求数组中任意一对数的异或和的lowbit的总和. 对于异或,二进制位中两个数相等则为0,反之为1,而且此题是要求lowbit,那我们利用 ...
- Inventor 2021保姆级安装教程
Inventor 2021 WIN10 64位安装步骤: 1.先使用"百度网盘客户端"下载INT21_CN_x64安装包到电脑磁盘里,并鼠标右击进行解压缩,安装前先断网,然后找到I ...
- 关于解决linux python3安装gattlib报错
1. 报错信息 /usr/bin/ld: cannot find -lboost_python36 collect2: error: ld returned 1 exit status error: ...
- SSH(四)控制层、业务层、dao层类的创建以及applicationcontext.xml和struts.xml配置
ssh框架的运作方式就是页面请求控制层,控制层调用dao层的方法,dao层完成对数据的操作的一个过程. 现在我们初步简单编写各层的class. action控制层: ActionSupport:实现了 ...
- 打印菱形-java
public class WeekendDemo01 { /** 打印菱形 * * * *** * ***** * *** * * */ public static void main(String[ ...
- Blazor和Vue对比学习(进阶.路由导航一):基本使用
Blazor和Vue都是单文件组件SPA,路由的实现逻辑非常相似,页面路径的改变都是组件的切换,但因为各自语言的特性,在实现方式上有较大差异. 一.安装 1.Vue:Router是Vue的一个插件.如 ...
- 缓存管理器CacheManager使用
缓存管理器CacheManager 一.背景 代码并发量因建行活动页上升,大量请求打到Mongo导致数据库cpu100%从而服务不可用,目前解决方案,使用编程式缓存,即对缓存的操作与业务代码耦合. ...