Git系列之历史维护

前言

git的常规用法各位应该已经熟知了,这里讲的是使用git来维护历史。在漫长的开发过程中我们会面临各种情况,bug修改、打补丁等,这个时候仓库可能已经积累了上千上万条提交历史,这样会使得维护难度大大增加,所幸git提供了一些命令帮助我们进行历史维护。
需要注意的是,使用这些命令是 十分危险 的,可能导致其他开发者记录丢失,因为这些命令会改变提交历史的hash校验值,有些是部分提交,有些是整一条分支,还有些是所有分支,修改完只能强推到主仓,所以一定要慎用
文章只讲了我目前了解到的内容,后续再更新

git rebase

git rebase可以用于修改提交历史

有些是按Esc,再按:wq退出

git rebase也可以用于合并分支,和git merge有点像,网上搜到的大多是关于这方面的内容,这里就不赘述了,放个链接https://blog.csdn.net/weixin_42310154/article/details/119004977

git filter-branch

git filter-branch使用的时候会弹出下面的信息,这是因为这条命令有些坑,不好用,git官方建议使用git filter-repo来替代,所以能不用尽量不用。为了便于阅读,我会将条信息删除。

$ git filter-branch -f --msg-filter 'sed "s/add b/Hello world!/g"'
WARNING: git-filter-branch has a glut of gotchas generating mangled history
         rewrites.  Hit Ctrl-C before proceeding to abort, then use an
         alternative filtering tool such as 'git filter-repo'
         (https://github.com/newren/git-filter-repo/) instead.  See the
         filter-branch manual page for more details; to squelch this warning,
         set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...

git filter-branch修改的是整一个分支所有的历史,而不是单纯在当前提交记录或者某个记录做出修改。
在使用过git filter-branch时,git会备份修改之前的历史,如果你想要再执行命令时会失败,需要使用 -f 参数
如果你想全分支修改,也就是同时修改本地仓里所有的分支,可以使用-- -all参数

filter

在匹配到filter后会去执行其后的command命令,相当于执行了eval命令。
若command返回值为非0,则,整个操作(branch ?filter? )会被中止
注意,如果修改commit成功,commit ID会发生变化
如果没有指定filter,commit会被重新提交但通常不会改变

–msg-filter

–msg-filter用于修改提交记录的文字说明内容,也就是git commit -m "文字说明"里双引号的内容
示例如下

$ git log --oneline		#修改前的log
e0acc4f (HEAD -> master) add c
90a9a50 add b
e0b2c25 add a
$ git filter-branch -f --msg-filter 'sed "s/add b/Hello world!/g"'		#修改命令
Rewrite e0acc4fe16ac6f96acdb8f5b60a0a23bbffa43e3 (3/3) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/master' was rewritten
$ git log --oneline		#修改后的log
12aab45 (HEAD -> master) add c
9df7123 Hello world!
e0b2c25 add a

在这里–msg-filter后面跟的是linux指令sed,其作用替换文本内容。整一条git filter-branch命令会查找当前分支所有提交信息,将add b替换成Hello World。
注意修改之后commit ID发生了变化。

–env-filter

用于修改作者/提交者的姓名、邮箱、时间等环境变量
git提供的环境变量如下
GIT_COMMIT,
GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE,
GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE

如果你想用作者的信息来隐藏提交者的日期、姓名和邮箱可用以下命令。需要注意的是,提交者的信息只有在git主仓才能看到,使用git log是看不到的。

git filter-branch --env-filter '
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"' 

–tree-filter

–tree-filter用于重写tree,也可以理解成修改历史里的文件
示例:

$ ls								#查看仓库文件
a  b  c
$ git log --oneline					#查看log
12aab45 (HEAD -> master) add c
9df7123 Hello world!
e0b2c25 add a
$ git filter-branch -f --tree-filter 'touch newfile' HEAD		#新增一个文件newfile
$ ls								#查看仓库文件变化,多了newfile
a  b  c  newfile
$ git status						#查看仓库状态,无变化
On branch master
nothing to commit, working tree clean
$ git log --oneline					#查看log变化,ID变了
19f0c57 (HEAD -> master) add c
4299bac Hello world!
633f6cc add a
zetao.zhang@ott13366:~/test$ git checkout HEAD^					#切换到上一个提交记录
zetao.zhang@ott13366:~/test$ ls		#查看文件变化,c消失了,newfile还在
a  b  newfile
$ git status						#查看仓库状态,newfile无变化
HEAD detached at 4299bac
nothing to commit, working tree clean

–index-filter

–index-filter的功能和–tree-filter一样,但比–tree-filter更快,除此之外暂未找到其他的区别。

–prune-empty

–prune-empty会清除那些空的失去联系的历史记录

$ git log --oneline				#查看log
19f0c57 (HEAD -> master) add c
4299bac Hello world!
633f6cc add a
$ ls							#查看文件
a  b  c  newfile
$ git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch c'		#删除c不带--prune-empty
$ ls							#查看文件,少了c
a  b  newfile
$ git log --oneline				#查看log,ID变了
21e7f3a (HEAD -> master) add c
4299bac Hello world!
633f6cc add a
$ git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch c' --prune-empty	#带上--prune-empty再删一次
$ git log --oneline				#查看log,只剩下两条
4299bac (HEAD -> master) Hello world!
633f6cc add a

git filter-repo

使用git filter-repo命令需要自行下载该工具,默认是不提供的

–replace-text

–replace-text参数用于替换文件里的内容,使用方式如下。
由于该命令会修改所有历史里的所有文件,所以在修改时请确保修改内容唯一

git filter-repo --replace-text <(echo "查找内容==>替换内容") --force

示例:

$ git log --oneline				#查看log
e7780c7 (HEAD -> master) update a
4299bac Hello world!
633f6cc add a
$ cat a							#查看a内容
add something in a
$ git filter-repo --replace-text <(echo "add something in a==>something changed") --force	#修改文件内容
$ cat a							#查看a内容,改变了
something changed
$ git log --oneline
4cd8a5a (HEAD -> master) update a
4299bac Hello world!
633f6cc add a

参考资料

git-filter-branch 英文手册 https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-branch.html
git-filter-repo 英文手册 https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值