实用的Git技巧
使用git已经有四年了,但是发现自己大多数的时候都只会使用add, commit, push, pull, checkout这几个指令,不愿意去学习新的命令。但其实git是个宝藏,里面充满着大佬们几十年编程经验中对版本管理,工作流悟出来的智慧。于是我整理下自己发现的好用的git技巧,以便经常查阅使用。
常规
clone
clone并更名为linux:
git clone https://github.com/openeuler-mirror/kernel.git linux
branch
列出所有分支(本地和远程)
git branch -a
add
分块添加进暂存区,而不是添加整个文件
git add -p
pull
仅仅pull最近的一个commit:
git pull origin master --depth=1
commit
增加签名:
gc --signoff
commit为fixup!, 在rebase squash中将被合并
gc --fixup SHA1
reset
重置到某个commit,不保留之后的修改
git reset --hard SHA1
重置到某个commit,保留之后的修改到工作区
git reset --soft SHA1
cherry-pick
挑选某个commit到当前分支
git cherry-pick SHA1
rebase
通过rebase可以非常方便的修改已经commit的代码, 比如要修改commit HEAD^^,可以通过
git rebase -i HEAD^^^
在rebase的编辑界面,将目标commit从pick改成edit,即可修改
此外能够在编辑界面修改keyword实现删除某个commit,合并commit,更改commit message
rebase非常好用,我经常使用的指令还有这个:
git rebase -i --autosquash master
它能合并需要被squash的commit, 需要与git commit --fixup搭配使用
通过rebase还能够为commit添加签名,比如为最近的四个commit增加签名
git rebase --signoff HEAD~4
revert
更加安全的删除某个commit, 目标commit仍存在,只是新增加一个revert commit删除目标commit添加的代码:
git revert SHA1
stash
贮藏脏工作区的修改
git stash
恢复脏工作区的修改
git stash pop
diff
查看与某个commit对比的overview
git diff SHA1 --stat
查看已经添加到工作区的修改
git diff --staged
log
git log --oneline
bitsect
二分查找来发现引入bug的commit
git bisect
submodules
添加submodule
git submodule add --depth 1 https://github.com/iaGuoZhi/linux kernel
选择submodule分支
cd kernel
git fetch origin shm_kernel_driver:shm_kernel_driver --depth=10
git checkout shm_kernel_driver
更新所有的submodule
git submodule update --init --recursive
help
git最常见的用法示例
git help everyday
与 Patch 相关
commit 规范
- commit信息不能够每一行不能够过长也不能够过短,在vim中选中后按g,w自动format commit信息
- 在patch新版本对上一个版本增加了修改可以在commit中直接标记, 例如
---
v3:
- Use C style comment
format-patch
使用最近的4个commit制作版本为1的4个patch,并且添加签名, 添加patch来介绍这个series
git format-patch --cover-letter -s -v 1 -4
checkpatch
使用checkpatch.pl来检查最近一个commit是否有style上面的问题
./scripts/checkpatch.pl -g --strict HEAD~1..HEAD
send-email
通过email发送patch的一个例子:
git send-email 0001-acpi-processor_idle.c-Fix-kernel-pointer-leak.patch --to rafael@kernel.org,lenb@kernel.org --cc linux-acpi@vger.kernel.org,linux-kernel@vger.kernel.org
发送邮件来提交patch, 但是查找邮件的发送对象很麻烦,而且还需要抄写,难免会出现错误,可以使用这个技巧来自动填充email 首先在gitconfig中设置:
[sendemail.linux]
tocmd ="`pwd`/scripts/get_maintainer.pl --nogit --nogit-fallback --norolestats --nol"
cccmd ="`pwd`/scripts/get_maintainer.pl --nogit --nogit-fallback --norolestats --nom"
然后在项目Linux的根目录使用以下命令发送patch
# 自动填充email
git send-email --identity=linux ***.patch
publish
一个内核大佬们写的工具,能够帮助自动整理并发送patch(自动化patch以及cover letter生成,patch的版本管理,邮件管理),发送patch只需要一个命令即可,非常方便:
https://github.com/stefanha/git-publish
apply
合并邮箱中的patch:
git apply xxx.patch
与 Vim 相关
vim-fugitive
通过Gdiffsplit和diffput在vim中添加修改
vim-gitgutter
diff 当前chunk很方便,而且能够用快捷键在chunk之间跳转
参考
https://fle.github.io/git-tip-keep-your-branch-clean-with-fixup-and-autosquash.html