一个按键搞定日常git操作

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

作为开源世界最优秀的作品之一,Git已经成为目前进行项目版本控制的最佳方案,也逐渐成为程序员必备的基础技能。“迁个新分支开发”,“提交一下代码”,“合到QA分支进行提测”,“提个上线的MR”等等这些Git工作流成为我们日常工作的重要部分。

闲话少叙,开始git之旅吧!

我修改了哪些文件 git status

1
alias s='git status'

用于查看文件变更情况。

这里取 s 键,即 git status

切到某个分支 git checkout

1
alias c='git checkout'

用于切换分支。

这里取 c 键,即 git checkout

搞个新分支开始开发 git checkout -b

1
alias cb='git checkout -b'

这里取 cb 键,即 git checkout -b

其实也可以直接使用上条命令 c -b <branch>,但我迁新分支的频率比较高,所以就单独搞了一个命令嘿嘿

我们开发新功能时通常需要基于线上分支(一般是master)迁出一个新分支来开发。

提交我的修改 git commit

1
alias C='git commit'

修修改改终于做了一部分功能,提交一下自己修改的文件

这里取大写 C 键(因为小写 c 已经给 git checkout 啦),即 git commit

拉取最新的代码 git pull

1
alias q='git pull'

用于拉取最新代码,比如别人在你工作的分支上修改了代码并推到了远端,那么你在git push之前就得先把最新的代码拉下来跟你本地的代码合并。

这里取 q 键,而不是 p 键,完全是因为个人偏好😁,我想把按键都集中在键盘左半部分。而且qp很像鸭,并不会增加记忆难度。

git pull 其实等于先 git fetch 再 git merge,两步操作合成一步完成啦

把本地代码推到远端 git push

1
alias Q='git push'

你写了一段非常优美的代码,别人想欣赏一下。此时就需要推到远端。

这里取 Q 键,git pull 和 git push 是最常用的一对操作,绑到一个按键上是非常方便的(用大小写对应)。

如果是新建的分支第一次推到远端,会报 The current branch has no upstream branch错误

执行下 git push --set-upstream origin <branch> 就行啦

你还可以用这个命令删掉一个远端分支(–delete) Q -d origin <branch>,谨慎操作喔!

这里只是删掉了远端的分支,本地对应的分支还在哟,双重保险,不怕手误嘿嘿。

配合下面的 b -d <branch> 效果更佳哦~

把别的分支合到我的分支上来 git merge

1
alias m='git merge'

我们将个人开发分支的代码合到线上分支之前,往往需要把线上分支的最新代码先合到自己的个人开发分支,以确保没有冲突

这里取 m 键,即 git merge

合个分支谁曾想有100多个冲突🥴,特么不合了 m --abort

玩归玩,闹归闹,别拿冲突开玩笑,吐血解决了100多个冲突,接着合并 m --continue

假如有个文件冲突了1000多行,实在懒得看,直接用某个分支的文件就行啦 C <wantted-branch> -- the/path/of/file.js

-- 是为了隔开分支名和文件名,后面跟上文件路径就行啦

把我的分支合到别的分支上去? 🧐

git 只提供了 git merge 把别的分支合到我的分支上来,并没有提供把我的分支合到别的分支上的命令

通常为了把当前工作分支合到别的分支上去(比如提测需要合到测试分支,上线需要合到线上分支),需要依次进行以下几步:

1
2
3
4
5
6
# 比如说我正在my-branch分支工作,需要合到test分支进行提测
1. git checkout test # 先切到目标分支test
2. git pull # 拉取test最新的代码
3. git merge my-branch # 把我的分支合到test上
4. git push # 把test推到远端
5. git checkout my-branch # 切回我的分支继续工作

之后你解决了一个bug,又要重复一遍上面的5步操作。一天下来可能要重复 N 遍这枯燥且无聊的合并过程。

既然git没提供(我猜是出于安全考虑),那就撸起袖子自己搞一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function consoleLog(){
echo "\033[33;1m$1\033[0m"
}
function consoleError(){
echo "\033[31;1m$1\033[0m"
}

local error=0
function checkError(){
((error)) && consoleError "🚨 出现错误"
}
# 合并当前分支到指定分支
function mt() {
if (($#==0)) {
consoleError "缺少参数"
} else {
local source=$(current_branch)

consoleLog "🔦 git checkout $1"
git checkout $1; error=$?
{checkError} && return error

consoleLog "⬇️ git pull origin $1"
git pull; error=$?
{checkError} && return error

consoleLog "🔗 git merge $source --no-ff"
git merge $source --no-edit --no-ff; error=$?
{checkError} && return error

consoleLog "⬆️ git push origin $1"
git push; error=$?
{checkError} && return error

consoleLog "🔦 git checkout $source"
git checkout $source; error=$?
{checkError} && return error

consoleLog "🎉🎉🎉 done!"
}
}

上面是zsh语法。上面代码的主要作用是把上面的5个合并步骤串行执行,加了一些错误处理和进度提示。

这里取 mt,因为是merge to的缩写鸭

现在只需要执行

1
mt test

即可完成把当前工作分支合并至别的分支,合并完成后,你依然在当前的工作分支。

来体验一下这一键操作的畅快吧

上面gif动图里git pull和git push时的停顿是在我家访问github时的龟速网络导致的,不影响实际使用

温馨提示:上线时合到线上分支最好还是老老实实在GitLab上提merge request吧,安全起见二次确认一下文件变更🤓

看一下提交记录 git log

1
alias v='git log --pretty=format:"%C(auto)%h %s %C(italic dim white)%an[%ad]%Creset%C(auto)%d%Creset%n"'

辛辛苦苦忙了一天,看看自己今天提交了哪些commit

追查真凶:线上出bug啦,是这个文件导致的,看看谁改了这个文件

git log 后面那一大串 --pretty=format: 是为了美化log的输出格式

具体占位符含义可参考 git log pretty formats

这里取了 v 键,意为 view git log,而且 v 键的位置比较不错 😎

当前项目都有哪些分支 git branch

1
alias b='git branch'

用于显示本地有哪些分支

这里取 b键,即 git branch

也可以查看有哪些远程分支(–remotes) b -r

还可以列出本地和远程所有分支(–all) b -a

🎉功能开发完上线啦,本地分支可以删啦(–delete) b -d <branch>

尼玛手抖分支删错了肿么办,不要怕,这里只是删掉了本地分支,分支在远端还好好的呢

shit,合错代码了,我要回滚代码 git reset

1
alias r='git reset'

这里取 r 键,即 git reset

只见你十指在键盘上快速飞舞,修改代码,暂存,拉最新,提交一气呵成。看着git命令一行行执行,log日志随之在bash里闪烁跳动。趁这间隙,你随手拿起手边的养生水杯,嘴角开始微微上扬,准备补充一下生命的源泉。你似乎想起了什么,神情倏地变得紧张起来,你的手开始颤抖,杯具里的水也跟着泛起了水花,突然一拍脑门:我尼玛忘切分支了,全提到线上分支去了!

此时你可以 r @^

@ 是 HEAD 的缩写,指向最新的commit。^表示之前的一个commit,和 @ 连起来就是:上一个commit

git reset 只是重置了 HEAD 指向的位置,你的修改都还在,只是回到了未提交的状态,就像刚才你从没提交过一样!

然而在另一个阳光明媚的下午,你竟然一不小心又把测试分支合到线上分支啦,还特么推到远端了

不要慌,此时只需要 r --hard @^,就会回到合测试分支之前的commit节点,并且丢掉所有相关的修改(参数–hard的奇效)

但此时你是 git push 不了的,因为你的本地分支HEAD落后远端分支,git会提示你要先 git pull

不要理它,直接 Q -fQ 是git push 还记得么🤪),来个霸王硬推(–force),这样远端分支和本地分支就同步啦

看看这个项目谁提交的最多

1
git shortlog -sn

提交最多的不一定是最勤劳的,也可能只是个强迫症哟~

获取当前分支名称

1
git rev-parse --abbrev-ref HEAD

一般在编写git程序时会需要用到

撤销提交历史上的某次 commit

1
git rebase -i --onto <commit-ish>^ <commit-ish>

比如你前天不小心把测试分支合到了自己的分支上(实际上是万万不该滴),然而你当时并没有注意到。你又写呀写,提交呀提交,今天功能要上线了,和线上分支一比对,尼玛出现10000+个变更,这才反应过来。此时你需要把合test那次commit剔除,就像医生从中弹伤者体内取出子弹一样。如果你改动的文件在test上也被别人改动啦,那就像子弹在体内又爆炸成了碎片,只能说Good luck啦😄

查看自己的命令使用排行

1
zsh_stats

配置完上面这些一键操作后,最近一段时间我的命令行记录

最后的最后

临近春节,票还没抢到,北漂真心不易。最近又赶上租房的地方要拆迁,需要重新找地方。再看一下自己的现状,眼见年将三十,家未成,业未立,浑浑噩噩,庸庸碌碌,每想至此,既焦虑又迷茫。今年的一个目标就是能每周写一篇高质量文章,总结梳理自己的知识体系。虽然不知道转机何时出现,但不能停止努力鸭😊

希望2020年能有一些惊喜发生吧,加油!