Git&repo&grep操作技巧

本文提供了一系列Git的高级操作技巧,包括查找大文件、改写历史记录、查找分支分叉点、回退仓库到特定时间点等。此外还介绍了如何节省仓库空间、删除历史记录、重新拉取分支等实用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.查找仓库中的大文件

git rev-list --objects --all | grep -E `git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -10 | awk '{print$1}' | sed ':a;N;$!ba;s/\n/|/g'`

 或者

git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -15 | awk '{print$1}')"

2.改写历史,去除大文件

git filter-branch --tree-filter 'rm -f path/to/large/files' --tag-name-filter cat -- --all
git push origin --tags --force
git push origin --all --force

3.查找两个分支的分叉点:

git merge-base branch1 branch2

4.查找某个commit id所在分支:

git branch -a --contains $commitid

可以有多个:

第二种方式:

git name-rev 632116837dd4fb8cfbe41abf576e303c199e8a29

回退repo仓库到某个时间点:

repo forall -c 'commitID=`git log --before "2017-03-17 07:00" -1 --pretty=format:"%H"`; git reset --hard $commitID'
forall  操作分支中的所有仓库
-c  只操作当前分支
--before  早于指定时间点的提交记录
-1  只显示最近的1条记录(注意这是数字 1 ,如果要显示 2 条就写 2,以此类推)
"2017-03-17 07:00"  希望回退到的日期(时间点)
--pretty  以指定格式显示提交记录
%H  提交记录的hash值,即commit id(其它格式及更详细的信息可以使用命令git log --help打印帮助信息并查看“PRETTY FORMATS”小节)  

命令含义:
这条repo命令的实质就是在当前分支的每个仓库下执行git log命令,找出该仓库下符合时间条件的第一个提交记录,然后对该仓库执行git reset --hard操作。就这么简单。

如果节省仓库空间:

如下命令可以只下载最近的一份提交记录,而不会管之前的提交记录,这样可以有效减少仓库数据占用的空间大小,可以看到只有一条提交记录,符合我们的预期。

 git clone https://gitee.com/rtthread/rt-thread.git --depth=1

git clone 另外一个目录的仓库

git clone后面可以跟文件系统中的版本库路径,或者NFS挂载到本地的虚拟文件系统,GIT访问协议URL,SSH,HTTP/HTTPS等URI定位仓库等。

git clone /home/caozilong/Workspace/linux/linux-5.18.19
or
git clone /home/caozilong/Workspace/linux/linux-5.18.19/.git

删除历史记录:

$ git filter-branch --tree-filter 'rm README.md'

$ git push origin master --force

列出某个用户创建的所有分支

git for-each-ref --format='%(committerdate) %09 %(authorname) %09 %(refname)' | sort -k5n -k2M -k3n -k4n | grep caozilong

确认被删除文件的删除记录

git log -1 --diff-filter=D -- <file_path>

重新拉取GIT仓库分支

以下是通过git命令重新拉取分支的方法:

方法一:

1.首先删除本地已有的分支:git branch -D [branch-name]
2.然后重新克隆带有指定分支的代码:git clone -b [branch-name] [repo-url]
方法二:

1.删除本地已有的分支:git branch -D [branch-name]
2.获取远程仓库的所有分支信息:git fetch origin
3.将远程分支检出到本地:git checkout -b [branch-name] origin/[branch-name]
实践步骤:

git branch -D linux-5.4.y
git fetch origin
git checkout -b linux-5.4.y origin/linux-5.4.y 或者:
git branch -D linux-4.15.y
git clone -b linux-4.15.y git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
注意:在上述方法中,请将[branch-name]替换为你想要拉取的分支名,将[repo-url]替换为项目的Git仓库URL。

git diff的输出格式

寻找GIT仓库中所有分支,所有历史文件中的特定字符串:

$ git grep "module_init" $(git rev-list --all)

grep逆匹配

要使用grep命令来过滤日志文件中重要的条目,可以使用正则表达式或者其他搜索模式。如果你想要排除某些特定的条目,可以使用grep-v选项来实现。

例如,如果你想要从一个名为application.log的日志文件中排除包含“ERROR”的行,可以使用以下命令:

grep -v "ERROR" application.log

如果你有多个模式需要排除,可以重复使用-v选项,或者使用grep-E选项来指定多个模式:

grep -v -E "ERROR|WARN" application.log

这将会从日志中排除包含"ERROR"或"WARN"的行。比如如下命令将从dmesg LOG中过滤掉带有"logitec","usb","input", ...."systemd"字符的行。

grep -v -E "logitec|usb|input|Bluetooth|wlp|virbr0|audit|iwlwifi|pcicfg|snd|drm|80211|systemd" a.log

cherry-pick另一个分支上的连续多笔提交:

这会将从 <commit-hash1> 的父提交到 <commit-hash2> 之间的所有提交应用到当前分支

    git cherry-pick <commit-hash1>^..<commit-hash2>

    git学习之cherry-pick命令_cherrypick 多个提交-优快云博客

    如果你想将多个提交合并为一个新提交,可以使用 -squash 选项:

    git cherry-pick -squash <commit-hash1> <commit-hash2>

    如何在本地仓库拉取一个三方仓库的分支,并建立对这个分支的跟踪?

    git remote add origin_kmd https://gitlab.xxxxxx.com/software/xxx.git
    git fetch origin_xxx
    git checkout --track origin_xxx/develop_xxx
    git branch
    

    对git仓库的理解

    git仓库管理的是分支,而并非是是一个具体的“仓库”对象。

    比如,建立仓库A后,再remote add另一个三方仓库,git fetch这个三方仓库后,建立一个本地分支跟踪三方仓库远程某个分支。此时如果将仓库A推送到GITHUB(包括A的原始分支和后来创建的跟踪三方分支的本地分支),之后新建一个目录将仓库A拉下来,你会发现仓库A有两个分支,一个是仓库A的原始分支,另一个则是前面推送上去的跟踪三方仓库的本地分支,所以看上去,建立仓库A时候的原始本地分支并没有特殊性,后来引入的三方仓库的分支和仓库A的原始分支有同样的地位。

    可以用"git branch -vv"查看本地分支跟踪的远程仓库和分支:

    如果分支是本地的,则远程分支的地方是空白:

    git rebase的过程

    如何将本地分支推送到指定远程仓库的某个分支上?

    比如,本地仓库的分支关联两个远程仓库,分别是origin和upstream,如何将本地分支feature1上的内容推送到远程仓库upstream的feature2分支? 执行如下命令:

    git push upstream feature1:feature2 -f

    虽然本地分支可以关联某个远程分支,但是本地分支并不属于某个远程仓库,而是属于默认的本地仓库,所以命令中upstream修饰的是feature2, feature1是本地仓库的分支。

    本地仓库的名称通常由存放它的目录名称决定,远程仓库可以通过 git remote add <别名> <URL> 设置别名(如 origin)。

    commit id的生成逻辑

    commit id的生成和如下因素有关:

    • 提交的内容(文件快照)

    • 提交的元数据(作者、时间、提交信息)

    • 父提交的 COMMIT ID

    用公式表示就是:

    commitid = f(content, metadata, parent\ commitid)

    所以,当执行 rebase 时,提交会被重新应用到新的基准点,导致父提交改变,因此新的特性提交的COMMIT ID 必然改变。

    git reset --soft 和 git reset --mixed的区别

    Git如何快速比较两个分支的差异,排除新增文件

    在 Git 中,要快速比较两个分支的差异并排除新增文件(即只关注已有文件的修改和删除),可以使用 git diff 结合 --diff-filter 选项。以下是具体方法:

    git diff dev_br200_pre_rtld --diff-filter=MRD --name-status

    仅列出修改/删除的文件名(不显示内容)严格排除新增(A)和复制(C)的文件,确保结果只包含修改和删除。

    默认情况下,Git 可能将重命名识别为“删除旧文件 + 新增新文件”。若需包含重命名,filter中加入R项,R 表示重命名(需配合 --name-status 查看状态)。通过以上命令,你可以高效过滤出两个分支间非新增文件的变更。


    结束!

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    papaofdoudou

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值