十分钟了解 git 那些 “不常用” 命令
??點(diǎn)擊上方?好好學(xué)java?,選擇?星標(biāo)?公眾號(hào)
重磅資訊、干貨,第一時(shí)間送達(dá) 今日推薦:Java實(shí)現(xiàn)QQ登錄和微博登錄個(gè)人原創(chuàng)+1博客:點(diǎn)擊前往,查看更多 鏈接:https://segmentfault.com/a/1190000022107836本文主要是介紹git不常用初期不太會(huì)用的命令,希望你看了能理解這些命令的使用,并在平時(shí)使用過(guò)程中一點(diǎn)點(diǎn)地刻意進(jìn)行練習(xí),逐步熟練并知道何時(shí)需要用到這些命令去解決你的問(wèn)題。( 我也在不斷熟練中:D
基礎(chǔ)命令
如果你還是剛剛接觸git命令,還不清楚 倉(cāng)庫(kù) 、工作流、分支、提交 的童鞋可以先看下 git使用簡(jiǎn)易指南,這個(gè)應(yīng)該是我初學(xué)git看的第一份且收藏至今的指南了~ 圖解很清晰易懂,真10分鐘入門的資料:D
然后你會(huì)發(fā)現(xiàn)如下基礎(chǔ)命令將會(huì)成為你之后幾乎每天都要用到的80%的命令:
git clone git@github.com:nohosts/nohost.git 克隆遠(yuǎn)程倉(cāng)庫(kù)的內(nèi)容到本地
git pull origin master 獲取遠(yuǎn)程分支master并merge到當(dāng)前分支
git branch -a 查看全部分支(遠(yuǎn)程+本地)
git checkout -b bugFix新建bugFix,并切換到到此分支。(如果分支已存在則去掉-b即可)
git status 查看當(dāng)前~~~~版本狀態(tài)(是否修改)
git add . 增加當(dāng)前子目錄~~~~下所有文件更改至?xí)捍鎱^(qū)
git commit -m 'xxx' 提交暫存區(qū)的修改至本地的版本庫(kù), 修改備注為xxx
git push 將本地版本推送到遠(yuǎn)程分支
git tag v1.0 dfb02e6e4f2f7b573337763e5c0013802e392818 增加v1.0的tag到某個(gè)提交上
git merge testBranch 合并testBranch分支至當(dāng)前分支`
git stash 暫存本地的當(dāng)前修改,將本地代碼重置為HEAD狀態(tài)。(如果需要取出修改,命令后加一個(gè)pop即可)
git log 顯示提交日志(如果想每個(gè)提交信息顯示在一行,可以加上--pretty=oneline)
git show dfb02e6e4f2f7b573337763e5c0013802e392818顯示某個(gè)提交的詳細(xì)內(nèi)容
git reset --hard HEAD 將當(dāng)前版本重置為HEAD
注意這兩個(gè)命令的區(qū)別:
git pull = fetch + mergegit pull --rebase = fetch + rebase“不常用”命令
一、git rebase 變基
在 Git 中整合來(lái)自不同分支的修改主要有兩種方法:merge 以及 rebase。在本節(jié)中我們將學(xué)習(xí)什么是“變基”,怎樣使用“變基”,并將展示該操作的驚艷之處,以及指出在何種情況下你應(yīng)避免使用它。——[git-scm變基]:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA
說(shuō)明:后面的舉例每個(gè) 分支 都有不同的顏色,*前綴 表示現(xiàn)在所處的分支,而 commitid 都由C0、C1、C2代替每一個(gè)提交的哈希值,箭頭 表示分支的繼承
我們之前整合分支用的最多的就是merge了,那merge和rebase有什么區(qū)別呢?
1. merge
★merge 合并兩個(gè)分支時(shí)會(huì)產(chǎn)生一個(gè)特殊的提交記錄,它有兩個(gè)父節(jié)點(diǎn)。簡(jiǎn)單說(shuō)就是:“我要把這兩個(gè)父節(jié)點(diǎn)本身及它們所有的祖先都包含進(jìn)來(lái)。”
”git checkout master; git merge bugFix下圖中左、右兩張圖分別是執(zhí)行如下代碼前后的樣子:
merge-1可以看出來(lái),紅色圈圈是最主要的改變—— merge 合并分支后,會(huì)在master分支上 新增一個(gè)C4提交 ,而C4提交里面有master和bugFix代碼庫(kù)所有的修改。
此時(shí)的bugFix代碼還沒(méi)和master 同步(顏色不同),我們還需要執(zhí)行如下代碼:
git checkout bugFix; git merge master merge-22. rebase
★rebase 實(shí)際上就是取出一系列的提交記錄,“復(fù)制”它們,然后在另外一個(gè)地方逐個(gè)的放下去。它的優(yōu)勢(shì)就是可以創(chuàng)造更線性的提交歷史。
”git checkout bugFix; git rebase master下圖中左、右兩張圖分別是執(zhí)行代碼前后的樣子:
變基-1bugFix 分支里的內(nèi)容通過(guò) rebase 直接 復(fù)制 到 master 分支上。現(xiàn)在 bugFix 分支上的工作在 master 的最頂端,同時(shí)我們也得到了一個(gè)更 線性 的提交序列。
注意:提交記錄 C3 依然存在(樹(shù)上那個(gè)半透明的節(jié)點(diǎn)),而 C3' 是我們 rebase 到 master 分支上的 C3 的 副本(內(nèi)容是一樣的,只是commitid更新了)。
但是,此時(shí)master還沒(méi)有和bugFix 同步(顏色不同),我們還需要執(zhí)行如下代碼:
git checkout master; git rebase bugFix 變基-2.png由于bugFix繼承自master,所以 Git 只是簡(jiǎn)單的把master分支的引用向前移動(dòng)了一下而已。
3. rebase的延伸用法
3.1 省去切換分支即可rebase
git rebase targetBranch originBranch表示切換到originBranch,然后執(zhí)行g(shù)it rebase targetBranch
3.2 修改某幾次提交
git rebase -i commitid如上圖標(biāo)注的,傳的commitid為你想修改的提交的 前一個(gè)commitid。執(zhí)行命令后進(jìn)入vi模式,會(huì)提示你一些操作命令(p、r、e...)你只需要在最上方修改默認(rèn)的pick為你想要的操作,然后退出并wq保存即可生效。
具體操作:
pick 使用(啥也沒(méi)變)
reword 使用并修改commit msg, 改后commit id也會(huì)更新
edit 使用并編輯commit時(shí)的文件 編輯后git add . 然后git commit —amend還可以更新最新的commit msg。git rebase —continue 把后面的內(nèi)容加進(jìn)來(lái)并解決沖突, 最后提交。最新的commit id也更新
squash 合并commit 選擇最新的commit去合并,然后continue發(fā)現(xiàn)這一次和上一次的commit msg都有,你可以刪除只留下想要的也可以進(jìn)行修改 然后 continue和push。如果你不刪的話會(huì)發(fā)現(xiàn)全部文本行都組成了一個(gè)多行的commit msg 如果commit再往前已經(jīng)沒(méi)有了 就不能再squash,否則會(huì)報(bào)錯(cuò)( error: cannot 'squash' without a previous commit )。然后 git rebase --edit-todo 可以繼續(xù)vi編輯
fixup 合并commit到前面而且commit,commit msg也沒(méi)了
drop 刪除某個(gè)commit
注意:如果想要恢復(fù)這一次rebase操作,則可以執(zhí)行 git rebase —abort。如果想完全恢復(fù)本地分支到遠(yuǎn)程的狀態(tài),可以執(zhí)行 git reset --hard origin/bugFix ,或者你可以 git reflog 找到對(duì)應(yīng)提交記錄回滾,但是有點(diǎn)麻煩
4. rebase需要謹(jǐn)慎使用
當(dāng)你要改寫的commit history還沒(méi)有被提交到遠(yuǎn)倉(cāng)庫(kù)的時(shí)候,也就是說(shuō),還沒(méi)有與他人共享之前,commit history是你私人所有的,那么想怎么改寫都可以。
而一旦被提交到遠(yuǎn)程后,這時(shí)如果再改寫history,那么勢(shì)必和他人的history長(zhǎng)的就不一樣了。git push 的時(shí)候,git會(huì)比較commit history,如果不一致,commit動(dòng)作會(huì)被拒絕,唯一的辦法就是帶上 -f 參數(shù),強(qiáng)制要求commit,這時(shí)git會(huì)以committer的history覆寫遠(yuǎn)程分支,從而完成代碼的提交。雖然代碼提交上去了,但是這樣可能會(huì)造成別人工作成果的丟失,所以使用 -f 參數(shù)要慎重。
所以,在不用 -f 的前提下,想維持樹(shù)的整潔,方法就是:在 git push 之前,先 git fetch,再 git rebase。
4. 總結(jié)
無(wú)論是通過(guò)變基,還是通過(guò)三方合并,整合的最終結(jié)果所指向的快照始終是一樣的,只不過(guò)提交歷史不同罷了。變基是將一系列提交按照原有次序依次應(yīng)用到另一分支上,而合并是把最終結(jié)果合在一起。
在你自己的分支(非他人共享)的分支進(jìn)行rebase是可以的,但是如果在公共分支rebase修改提交需要謹(jǐn)慎——最好是先 fetch、再 rebase、最后 push。
二、git cherry-pick 選擇
★cherry-pick 可以將提交樹(shù)上任何地方的提交記錄取過(guò)來(lái)追加到 HEAD 上(只要不是 HEAD 上游的提交就沒(méi)問(wèn)題)。`
”git checkout master; git cherry-pick C2下圖中左、右兩張圖分別是執(zhí)行代碼前后的樣子:是不是有點(diǎn)眼熟:D 沒(méi)錯(cuò) 這個(gè)和rebase的效果蠻像的,這兩個(gè)命令都可以實(shí)現(xiàn)復(fù)制提交~
cherry-pick.png三、git reset VS revert 回滾
★git revert HEAD是用一次新的commit來(lái)回滾之前的commit,git reset 是直接向上移動(dòng)分支,刪除一些commit看上去像從未提交一樣。這兩者看似達(dá)到的效果是一樣的,其實(shí)完全不同。
”git reset HEAD~1 git revert HEAD如下所見(jiàn),圖1是初始狀態(tài)(需要撤回 C2 提交),圖2和3 是從圖1分別執(zhí)行 reset 和 revert 后的結(jié)果:
reset執(zhí)行后,master 分支移回到了 C1;現(xiàn)在我們的本地代碼庫(kù)根本就不知道有 C2 這個(gè)提交了
revert執(zhí)行后,在我們要撤銷的提交記錄 C2 后面多了一個(gè)新提交C2',而C2'引入了更改—— 這些更改是用來(lái)撤銷C2這個(gè)提交的。也就是說(shuō)C2'的狀態(tài)與C1是相同的。
注意:
如果你已經(jīng)push到線上代碼庫(kù), reset 刪除指定commit以后, 你git push可能導(dǎo)致很多沖突.但是revert 并不會(huì)。
如果此回退的分支合并主干分支時(shí),reset 恢復(fù)部分的代碼依然會(huì)出現(xiàn)在歷史分支里,但是revert 方向提交的commit 并不會(huì)出現(xiàn)在歷史分支里。
四、HEAD^n 和 HEAD~n 相對(duì)引用
★HEAD 是一個(gè)對(duì)當(dāng)前檢出記錄的符號(hào)引用 —— 也就是指向你正在其基礎(chǔ)上進(jìn)行工作的提交記錄。HEAD 總是指向當(dāng)前分支上最近一次提交記錄 (如果想看 HEAD 指向,可以通過(guò) cat .git/HEAD 查看, 如果 HEAD 指向的是一個(gè)引用,還可以用 git symbolic-ref HEAD 查看它的指向。)
”1. 基礎(chǔ)使用:
使用 ^ 表示向上移動(dòng) 1 個(gè)提交記錄。n表示第n個(gè)父提交,不填默認(rèn)是1(正上方)
使用 ~<num> 向上移動(dòng)多個(gè)提交記錄 如 ~3
注意:操作符還支持鏈?zhǔn)讲?#xff0c;如HEAD^2~3^
2. 延伸用法:移動(dòng)分支可以直接使用 -f 選項(xiàng)讓分支指向另一個(gè)提交。例如下面的命令會(huì)將 master 分支強(qiáng)制指向 HEAD 的第 3 級(jí)父提交。
git branch -f master HEAD~3這次主要就總結(jié)了這幾種“不常用”git命令,希望大家和我都可以多多練習(xí),讓他變成你需要時(shí)就可以自如使用的“常用”命令!:D
墻裂推薦一個(gè)[可視化的git練習(xí)網(wǎng)站]:https://learngitbranching.js.org/,很易懂好用~
總結(jié)
以上是生活随笔為你收集整理的十分钟了解 git 那些 “不常用” 命令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java SPI 源码解析及 demo
- 下一篇: JDK 13 的最新垃圾回收器ZGC,你