Git 不要只会 pull 和 push,试试这 5 条提高效率的命令
上一篇:阿里为什么推荐使用LongAdder?而不是AtomicLong?
前言
使用 Git 作为代码版本管理,早已是现在开发工程师必备的技能。可大多数工程师还是只会最基本的保存、拉取、推送,遇到一些commit管理的问题就束手无策,或者用一些不优雅的方式解决。
本文分享我在开发工作中实践过的实用命令。这些都能够大大提高工作效率,还能解决不少疑难场景。下面会介绍命令,列出应用场景,手摸手教学使用,让同学们看完即学会。
![](https://filescdn.proginn.com/43777aa8f570fc23caf9df202e5d650d/2f317d9938c7374786627e8d6304649c.webp)
stash
描述
官方解释:当您想记录工作目录和索引的当前状态,但又想返回一个干净的工作目录时,请使用git stash。该命令将保存本地修改,并恢复工作目录以匹配头部提交。
应用场景
我猜你心里一定在想:为什么要变干净?
![](https://filescdn.proginn.com/d66d4bb4d8d7dd4d8fb2dc0db3620788/9897d252ff90bd069ba5317fafa41169.webp)
命令使用
如果你学会 stash,就不用那么狼狈了。你只需要:
git stash
复制代码
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
复制代码
$ git stash list
stash@{0}: WIP on ...
stash@{1}: WIP on ...
stash@{2}: On ...
复制代码
$ git stash apply stash@{1}
复制代码
vscode 集成
stash 代码
![](https://filescdn.proginn.com/7c3fddc4665b5716e1e2a0bad768f767/a1f9050297a52cd16caf4f582883bdf7.webp)
![](https://filescdn.proginn.com/1df410f3b4d34931f438cbcb770c3b4f/82096411cefa0c36632d3ce141528a24.webp)
![](https://filescdn.proginn.com/84645e1426787ba0eba07b44d9296782/e7ba3bdc3cc28743101da9591af12940.webp)
![](https://filescdn.proginn.com/2052479130e4eca2528c2b5d999bbb32/0b64ae01b8813f4371cc9c8dc0aa9d52.webp)
reset --soft
描述
完全不接触索引文件或工作树(但会像所有模式一样,将头部重置为)。这使您的所有更改的文件更改为“要提交的更改”。
git reset \--hard
会被提及的比较多,它能让 commit 记录强制回溯到某一个节点。而 git reset \--soft
的作用正如其名,--soft
(柔软的) 除了回溯节点外,还会保留节点的修改内容。应用场景
命令使用
学会 reset \--soft
之后,你只需要:
# 恢复最近一次 commit
git reset --soft HEAD^
复制代码
reset \--soft
相当于后悔药,给你重新改过的机会。对于上面的场景,就可以再次修改重新提交,保持干净的 commit 记录。
git push \-f
来覆盖被 reset 的 commit。reset \--soft
指定 commit 号时,会将该 commit 到最近一次 commit 的所有修改内容全部恢复,而不是只针对该 commit。![](https://filescdn.proginn.com/62d6aba59629e78c5444e19a6d23025c/61f9e9ae75ee9081c9c2e120848f8fb2.webp)
git reset --soft 1a900ac29eba73ce817bf959f82ffcb0bfa38f75
复制代码
此时的 HEAD 到了 a,而 b、c 的修改内容都回到了暂存区。
![](https://filescdn.proginn.com/90cd27d02edff0327f13b73b21e8bda9/8b81f68104c4a2935b85ce8356c529c1.webp)
cherry-pick
描述
给定一个或多个现有提交,应用每个提交引入的更改,为每个提交记录一个新的提交。这需要您的工作树清洁(没有从头提交的修改)。
应用场景
命令使用
复制单个
![](https://filescdn.proginn.com/cca4dd4650487ea638e57db61806400b/d2e135b6eb31f034baf5c669a4dd3ce1.webp)
![](https://filescdn.proginn.com/03a97b83610cd34629e19d07cb39c774/1d7c7a865dc0d1ab17d7329fb2046d1b.webp)
cherry-pick
把 b 应用到当前分支。![](https://filescdn.proginn.com/4ae650c0918f375001fe14859648322e/b3510604a7f1d0f9b9e537a058b1a540.webp)
复制多个
cherry-pick
多个 commit 要如何操作。一次转移多个提交:
git cherry-pick commit1 commit2
复制代码
多个连续的commit,也可区间复制:
git cherry-pick commit1^..commit2
复制代码
cherry-pick 代码冲突
cherry-pick
多个commit时,可能会遇到代码冲突,这时 cherry-pick
会停下来,让用户决定如何继续操作。下面看看怎么解决这种场景。![](https://filescdn.proginn.com/ba8a7dd01bc82953c201b3520d7b883d/9493e724bf161333fc97dc242a38e87e.webp)
![](https://filescdn.proginn.com/5927ba43543b8786940121f95a9ed1fb/f14c5c180504c6fa34310baa1e21924e.webp)
cherry-pick
。可以看到 c 被成功复制,当进行到 d 时,发现代码冲突,cherry-pick
中断了。这时需要解决代码冲突,重新提交到暂存区。![](https://filescdn.proginn.com/1840bf4c6eb1ece20c2ded34b57e63d7/e0ea32422a7a41147efdd85f2cef6e23.webp)
cherry-pick \--continue
让 cherry-pick
继续进行下去。最后 e 也被复制进来,整个流程就完成了。放弃
cherry-pick
:
gits cherry-pick --abort
复制代码
退出
cherry-pick
:
git cherry-pick --quit
复制代码
不回到操作前的样子。即保留已经 cherry-pick
成功的 commit,并退出 cherry-pick
流程。
revert
描述
给定一个或多个现有提交,恢复相关提交引入的更改,并记录一些这些更改的新提交。这就要求你的工作树是干净的(没有来自头部的修改)。
应用场景
命令使用
revert 普通提交
![](https://filescdn.proginn.com/a1a3060ef44a26fe6d5312f55d460645/8f7f20ae6dc749e0bc6f241db22d8110.webp)
git revert 21dcd937fe555f58841b17466a99118deb489212
复制代码
![](https://filescdn.proginn.com/3016be9bc3131f047e89c6fdd9823442/f360445392558bccc8f7bd4d8e1d894c.webp)
![](https://filescdn.proginn.com/945abf1568c2baff3decb2a5ac6bbe7e/ce510add3dc0d75919021cd3ebb9c97c.webp)
revert 合并提交
![](https://filescdn.proginn.com/5965517232d3a23fecdd175ebd9bacae/f6437bfbc93824fb8be3403fab6de765.webp)
![](https://filescdn.proginn.com/824478b2e55322f9f046a478f75f88b9/d79e2ad5d2e89a6910cf72fac372f8dc.webp)
通常无法 revert 合并,因为您不知道合并的哪一侧应被视为主线。此选项指定主线的父编号(从1开始),并允许 revert 反转相对于指定父编号的更改
git revert -m 1
复制代码
revert 合并提交后,再次合并分支会失效
![](https://filescdn.proginn.com/0be71ef4e9e0246904303f2d0979f25c/31fbb3deca309f97fefb9c612dd39fbd.webp)
![](https://filescdn.proginn.com/a78716d1c111decb12656a8e83e26259/a0769db087097267d1f35ae5171e156e.webp)
reflog
描述
此命令管理重录中记录的信息。
reset \--soft
是后悔药,那 reflog 就是强力后悔药。它记录了所有的 commit 操作记录,便于错误操作后找回记录。应用场景
应用场景:某天你眼花,发现自己在其他人分支提交了代码还推到远程分支,这时因为分支只有你的最新提交,就想着使用 reset \--hard
,结果紧张不小心记错了 commitHash,reset 过头,把同事的 commit 搞没了。没办法,reset \--hard
是强制回退的,找不到 commitHash 了,只能让同事从本地分支再推一次(同事瞬间拳头就硬了,怎么又是你)。于是,你的技术形象又一落千丈。
命令使用
![](https://filescdn.proginn.com/97929c90e912929b1a48ae831ee20d72/8a8ddb52d3a4e3c6657878d669e720a9.webp)
![](https://filescdn.proginn.com/306cdc9156153aac9f709436faa0396d/1c503581c8de47a455bf785048d27190.webp)
![](https://filescdn.proginn.com/eafc8e158d294a20aa6f68aefe0474f0/68148709fd1a7cde6ef63187fe6b3da0.webp)
git reflog
查看历史记录,把错误提交的那次 commitHash 记下。![](https://filescdn.proginn.com/0c160e2f58cf29ee9eff430a059fbd7c/f77157db73d46c517c7638ba01880dbf.webp)
设置 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
git cp
复制代码
总结
stash
:存储临时代码。reset --soft
:软回溯,回退 commit 的同时保留修改内容。cherry-pick
:复制 commit。revert
:撤销 commit 的修改内容。reflog
:记录了 commit 的历史操作。