玩转Git

687 阅读6分钟

玩转Git

前言


本文不是向大家介绍git怎么安装,怎么关联远程仓库,不对比SVN等不同版本管理器之间的差异,不罗列如git pull, git push, git commit 等使用git的基本姿势。结合个人平时在使用git中的一些经验,给大家分享一些我们在版本管理当中经常会遇到的场景及可以使用的git操作。

可能你会说,我在ide当中安装git插件,想怎么用就怎么用,想什么姿势就什么姿势,还需要知道这些繁琐的指令码?

当你熟悉命令行操作之后,你会发现它远比插件控件操作快速许多,并且会让你对git的了解更深一层。


Git仓库结构



要使用git,首先我们需要简单了解一个git仓库的基本结构。当将我们的项目初始化为一个git工程后,我们可以简单的将本地仓库分成三部分:


  1. git管理的整个工程被称为工作区(workspace)。
  2. 当我们使用git add后,我们选择的改动文件会被添加到暂存区,(stage)以备后续进行提交。
  3. 当我们使用git commit后,一个新的版本(version)就生成了,git版本线又向前推进了一步。


分支交互


对于分支(branch)的一切操作,我们可以简化为四个分支之间的交互。


IMG_20191203_194948.jpg


版本交互的第一原则是分支交互之间的清晰,拒绝进行本地和远程分支之间的交叉行为,如本地分支 A 拉取远程分支 B 此种操作,如此会导致分支之间内容混乱。


指令

git stash 


当你正在火热的做一个新Feature时,邮件中收到了提醒,又有讨厌的Bug来烦人了,此时需要切换到hotfix分支改Bug,但是新功能做了一半又不适合提交新版本,该怎么办?


git stash 可以帮助你把当前的修改存入到单独的空间当中,使工作区干干净净,然后就可以切换分支做其他操作了。

git stash list  查看stash空间被存储的内容

git stash pop 应用stash空间的第一条内容,即上一次stash的内容

git stash apply 应用stash空间的某一条存储记录

git stash save 可以为你的stash添加备注,标明stash的内容

git stash clear 清空stash空间的全部内容。(使用前确认,误用追悔莫及)


git log 

使用git log查看历史修改时候,是不是很头疼内容太多,找不到我们要看的重点? 不用担心,可以使用加强版。


git log --patch 【commitid】 查看某一个commit版本的修改内容,一次定位。

git log --graph  查看git版本线,commit的历史记录,及分支间合并情况

git log --oneline   如果嫌弃graph内容太多,交叉线看到头晕,oneline 可以让信息更精简

git log --grep  记得很久前我改过这个Bug,但是太久找不到了,只记得commit备注。没关系,可以使用grep搜索到具体的commit,you won't miss it。


git diff


打算提交前,我想看看我都改了些什么,万一改了不该改的地方怎么办?


git diff  查看改动内容, 当然要在git add之前使用


git revert


我想要回滚到历史的某个commit版本,该咋办? 可以使用温柔的revert,加上commitid , 它不会影响你历史的提交,只是将历史的某个commit再次应用一遍。但是这样操作太累赘,我想让版本线干净一点怎么办?往下看


git reset


提交了好几个版本,但是现在我要回滚,这咋办?


git reset 【commitid】 将版本回滚到某个历史commit,这个版本之后的所有改动依然保留。


git reset  【commitid】 --hard   干干净净的回滚到commitid版本,后面的改动我都不要了(用前请确认哦)。


git reset 会将当前版本回滚到某个指定版本,此后的提交都将会看不到。


git checkout


这里不是说怎么切分支!我对几个文件做了一些改动,后来又想撤销,怎么办?reset会全部撤销的,可是我只想撤销几个文件的改动。


git checkout 【filename】 撤销对于文件的更改,并且可以同时撤销多个文件更改。


git checkout .  加个点,但是更厉害,会将当前更改的文件全部撤销,相当于git reset HEAD --hard ,用前确认。


git rebase 


每次我合完代码,发现都会多一个commit,但是这个commit什么改动内容都没有,我的提交历史就像是长了一个疙瘩,难受死强迫症。


git rebase 变基操作,和git merge同样的使用方式,让你的版本线不长疙瘩,但是两个分支差异过大,rebase起来可能要比对的内容会有点多哦。


git rebase -i


同样是rebase,为什么你可以另起一行,只因为你真的太NP了。交互式变基操作,听名字就很厉害。我发现很久前的一个commit不太合适,我想把它删掉,怎么办?之前commit的message不合适,我想改下?


git rebase -i  修整你的版本历史,就行修剪花丛的剪刀,有了它,你可以花式优化提交历史。(当然,不建议对历史提交做大的改动)


git reflog


我发现自己回滚了错误的内容,还是用的reset,之后的版本都找不到了,oh my god ?  不要慌,reflog 值得拥有,使用它,可以查看到在当前工程所做的所有历史操作,找到回滚前的版本commit,将回滚再回滚(有点绕),终于复原了。


git cherry-pick 


我想把hotfix分支改Bug的几个commit合到dev分支,merge会长疙瘩,rebase操作起来要处理冲突,好麻烦。


git cherry-pick  可以将工程当中,任何分支的任何commit拿(pick)当前分支。


git branch


git branch 查看本地分支

git branch  -r 查看远程全部分支

git branch -a  查看本地和远程的所有分支

git branch -vv  查看当前分支的来源 


git push origin -D


git push origin -D [originbranch]  删除远程分支,如果需要清理远程分支,建议还是在远程仓库中手动操作,从而方便确认。


git bisect


项目出现了问题,但是代码中不好确定范围,可以尝试 bisect ,使用二分法快速定位错误。  


git bisect start 【结束版本】 【起始版本】   找到一个肯定不会有错的历史版本作为起始版本,结束版本可以使用HEAD(当前版本)

git bisect good  认为当前版本没有复现问题

git bisect bad  发现当前版本存在了问题

git bisect reset 退出bisect过程


阮老师详细讲解篇


结语


文中没有对每个指令的原理做详细说明,旨在分享一些常用场景中可用的解决办法。