共计 5212 个字符,预计需要花费 14 分钟才能阅读完成。
起源:juejin.cn/post/7071780876501123085
前言
应用 Git 作为代码版本治理,早已是当初开发工程师必备的技能。可大多数工程师还是只会最根本的保留、拉取、推送,遇到一些 commit 治理的问题就大刀阔斧,或者用一些不优雅的形式解决。
本文分享我在开发工作中实际过的实用命令。这些都可能大大提高工作效率,还能解决不少疑难场景。上面会介绍命令,列出利用场景,手摸手教学应用,让同学们看完即学会。
stash
形容
官网解释:当您想记录工作目录和索引的以后状态,但又想返回一个洁净的工作目录时,请应用 git stash。该命令将保留本地批改,并复原工作目录以匹配头部提交。
stash 命令可能将还未 commit 的代码存起来,让你的工作目录变得洁净。
利用场景
我猜你心里肯定在想:为什么要变洁净?
利用场景:某一天你正在 feature 分支开发新需要,忽然产品经理跑过来说线上有 bug,必须马上修复。而此时你的性能开发到一半,于是你急忙想切到 master 分支,而后你就会看到以下报错:
因为以后有文件更改了,须要提交 commit 放弃工作区洁净能力切分支。因为情况紧急,你只有急忙 commit 下来,commit 信息也轻易写了个“暂存代码”,于是该分支提交记录就留了一条黑历史…(真人真事,看过这种提交)
命令应用
如果你学会 stash,就不必那么狼狈了。你只须要:
git stash
就这么简略,代码就被存起来了。
当你修复完线上问题,切回 feature 分支,想复原代码也只须要:
git stash apply
相干命令
# 保留以后未 commit 的代码
git stash
# 保留以后未 commit 的代码并增加备注
git stash save "备注的内容"
# 列出 stash 的所有记录
git stash list
# 删除 stash 的所有记录
git stash clear
# 利用最近一次的 stash
git stash apply
# 利用最近一次的 stash,随后删除该记录
git stash pop
# 删除最近的一次 stash
git stash drop
当有多条 stash,能够指定操作 stash,首先应用 stash list 列出所有记录:
$ git stash list
stash@{0}: WIP on ...
stash@{1}: WIP on ...
stash@{2}: On ...
利用第二条记录:
$ git stash apply stash@{1}
pop,drop 同理。
vscode 集成
stash 代码
填写备注内容,也能够不填间接 Enter
在 STASHES 菜单中能够看到保留的 stash
先点击 stash 记录旁的小箭头,再点击 apply 或者 pop 都可复原 stash
reset –soft
形容
齐全不接触索引文件或工作树(但会像所有模式一样,将头部重置为)。这使您的所有更改的文件更改为“要提交的更改”。
回退你已提交的 commit,并将 commit 的批改内容放回到暂存区。
个别咱们在应用 reset 命令时,git reset --hard
会被提及的比拟多,它能让 commit 记录强制回溯到某一个节点。而 git reset --soft
的作用正如其名,--soft
(柔软的) 除了回溯节点外,还会保留节点的批改内容。
利用场景
回溯节点,为什么要保留批改内容?
利用场景 1:有时候手滑不小心把不该提交的内容 commit 了,这时想改回来,只能再 commit 一次,又多一条“黑历史”。
利用场景 2:标准些的团队,个别对于 commit 的内容要求职责明确,颗粒度要细,便于后续呈现问题排查。原本属于两块不同性能的批改,一起 commit 下来,这种就属于不标准。这次恰好又手滑了,一次性 commit 下来。
命令应用
学会 reset --soft
之后,你只须要:
# 复原最近一次 commit
git reset --soft HEAD^
reset --soft
相当于后悔药,给你从新改过的机会。对于下面的场景,就能够再次批改从新提交,放弃洁净的 commit 记录。
以上说的是还未 push 的 commit。对于曾经 push 的 commit,也能够应用该命令,不过再次 push 时,因为近程分支和本地分支有差别,须要强制推送 git push -f
来笼罩被 reset 的 commit。
还有一点须要留神,在 reset --soft
指定 commit 号时,会将该 commit 到最近一次 commit 的所有批改内容全副复原,而不是只针对该 commit。
举个例子:
commit 记录有 c、b、a。
reset 到 a。
git reset --soft 1a900ac29eba73ce817bf959f82ffcb0bfa38f75
此时的 HEAD 到了 a,而 b、c 的批改内容都回到了暂存区。
cherry-pick
形容
给定一个或多个现有提交,利用每个提交引入的更改,为每个提交记录一个新的提交。这须要您的工作树清洁(没有从头提交的批改)。
将曾经提交的 commit,复制出新的 commit 利用到分支里
利用场景
commit 都提交了,为什么还要复制新的进去?
利用场景 1:有时候版本的一些优化需要开发到一半,可能其中某一个开发完的需要要长期上,或者某些起因导致待开发的需要卡住了已开发实现的需要上线。这时候就须要把 commit 抽出来,独自解决。
利用场景 2:有时候开发分支中的代码记录被净化了,导致开发分支合到线上分支有问题,这时就须要拉一条洁净的开发分支,再从旧的开发分支中,把 commit 复制到新分支。
命令应用
复制单个
当初有一条 feature 分支,commit 记录如下:
须要把 b 复制到另一个分支,首先把 commitHash 复制下来,而后切到 master 分支。
以后 master 最新的记录是 a,应用 cherry-pick
把 b 利用到以后分支。
实现后看下最新的 log,b 曾经利用到 master,作为最新的 commit 了。能够看到 commitHash 和之前的不一样,然而提交工夫还是保留之前的。
复制多个
以上是单个 commit 的复制,上面再来看看 cherry-pick 多个 commit 要如何操作。
- 一次转移多个提交:
git cherry-pick commit1 commit2
下面的命令将 commit1 和 commit2 两个提交利用到以后分支。
- 多个间断的 commit,也可区间复制:
git cherry-pick commit1^..commit2
下面的命令将 commit1 到 commit2 这个区间的 commit 都利用到以后分支(蕴含 commit1、commit2),commit1 是最早的提交。
cherry-pick 代码抵触
在 cherry-pick
多个 commit 时,可能会遇到代码抵触,这时 cherry-pick
会停下来,让用户决定如何持续操作。上面看看怎么解决这种场景。
还是 feature 分支,当初须要把 c、d、e 都复制到 master 分支上。先把终点 c 和起点 e 的 commitHash 记下来。
切到 master 分支,应用区间的 cherry-pick
。能够看到 c 被胜利复制,当进行到 d 时,发现代码抵触,cherry-pick
中断了。这时须要解决代码抵触,从新提交到暂存区。
而后应用 cherry-pick --continue
让cherry-pick
持续进行上来。最初 e 也被复制进来,整个流程就实现了。
以上是残缺的流程,但有时候可能须要在代码抵触后,放弃或者退出流程:
- 放弃 cherry-pick:
git cherry-pick --abort
回到操作前的样子,就像什么都没产生过。
- 退出 cherry-pick:
git cherry-pick --quit
不回到操作前的样子。即保留曾经 cherry-pick
胜利的 commit,并退出 cherry-pick
流程。
revert
形容
给定一个或多个现有提交,复原相干提交引入的更改,并记录一些这些更改的新提交。这就要求你的工作树是洁净的(没有来自头部的批改)。
将现有的提交还原,复原提交的内容,并生成一条还原记录。
利用场景
利用场景:有一天测试忽然跟你说,你开发上线的性能有问题,须要马上撤回,否则会影响到零碎应用。这时可能会想到用 reset 回退,可是你看了看分支上最新的提交还有其余共事的代码,用 reset 会把这部分代码也撤回了。因为情况紧急,又想不到好办法,还是任性的应用 reset,而后再让共事把他的代码合一遍(共事听到想打人),于是你的技术形象在共事眼里一泻千里。
命令应用
revert 一般提交
学会 revert 之后,立马就能够援救这种难堪的状况。
当初 master 记录如下:
git revert 21dcd937fe555f58841b17466a99118deb489212
revert 掉本人提交的 commit。
因为 revert 会生成一条新的提交记录,这时会让你编辑提交信息,编辑完后 :wq 保留退出就好了。
再来看下最新的 log,生成了一条 revert 记录,尽管本人之前的提交记录还是会保留着,但你批改的代码内容曾经被撤回了。
revert 合并提交
在 git 的 commit 记录里,还有一种类型是合并提交,想要 revert 合并提交,应用上会有些不一样。
当初的 master 分支里多了条合并提交。
应用刚刚同样的 revert 办法,会发现命令行报错了。
为什么会这样?在官网文档中有解释。
通常无奈 revert 合并,因为您不晓得合并的哪一侧应被视为主线。此选项指定主线的父编号(从 1 开始),并容许 revert 反转绝对于指定父编号的更改
我的了解是因为合并提交是两条分支的交加节点,而 git 不晓得须要撤销的哪一条分支,须要增加参数 -m 指定主线分支,保留主线分支的代码,另一条则被撤销。
-m 前面要跟一个 parent number 标识出 ” 主线 ”,个别应用 1 保留主分支代码。
git revert -m 1 <commitHash>
revert 合并提交后,再次合并分支会生效
还是下面的场景,在 master 分支 revert 合并提交后,而后切到 feature 分支修复好 bug,再合并到 master 分支时,会发现之前被 revert 的批改内容没有从新合并进来。
因为应用 revert 后,feature 分支的 commit 还是会保留在 master 分支的记录中,当你再次合并进去时,git 判断有雷同的 commitHash,就疏忽了相干 commit 批改的内容。
这时就须要 revert 掉之前 revert 的合并提交,有点拗口,接下来看操作吧。
当初 master 的记录是这样的。
再次应用 revert,之前被 revert 的批改内容就又回来了。
reflog
形容
此命令治理重录中记录的信息。
如果说 reset --soft
是后悔药,那 reflog 就是强力后悔药。它记录了所有的 commit 操作记录,便于错误操作后找回记录。
利用场景
利用场景:某天你眼花,发现自己在其他人分支提交了代码还推到近程分支,这时因为分支只有你的最新提交,就想着应用reset --hard
,后果缓和不小心记错了 commitHash,reset 过头,把共事的 commit 搞没了。
没方法,reset --hard
是强制回退的,找不到 commitHash 了,只能让共事从本地分支再推一次(共事霎时拳头就硬了,怎么又是你)。于是,你的技术形象又一泻千里。
命令应用
分支记录如上,想要 reset 到 b。
误操作 reset 过头,b 没了,最新的只剩下 a。
这时用 git reflog
查看历史记录,把谬误提交的那次 commitHash 记下。
再次 reset 回去,就会发现 b 回来了。
设置 Git 短命令
对我这种喜爱敲命令而不必图形化工具的爱好者来说,设置短命令能够很好的提高效率。上面介绍两种设置短命令的形式。
形式一
git config --global alias.ps push
形式二
关上全局配置文件
vim ~/.gitconfig
写入内容
[alias]
co = checkout
ps = push
pl = pull
mer = merge --no-ff
cp = cherry-pick
应用
# 等同于 git cherry-pick <commitHash>
git cp <commitHash>
总结
本文次要分享了 5 个在开发中实用的 Git 命令和设置短命令的形式。
stash
:存储长期代码。reset --soft
:软回溯,回退 commit 的同时保留批改内容。cherry-pick
:复制 commit。revert
:撤销 commit 的批改内容。reflog
:记录了 commit 的历史操作。
文中列举的利用场景有局部不太失当,只是想便于同学们了解,最重要的是要了解命令的作用是什么,活学活用能力施展最大效用。
近期热文举荐:
1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)
2. 劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!
5.《Java 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!