本文主要是介紹git不經常使用初期不太會用的命令,但願你看了能理解這些命令的使用,並在平時使用過程當中一點點地刻意進行練習,逐步熟練並知道什麼時候須要用到這些命令去解決你的問題。
( 我也在不斷熟練中:D
若是你仍是剛剛接觸git命令,還不清楚 倉庫
、工做流
、分支
、提交
的童鞋能夠先看下 git使用簡易指南,這個應該是我初學git看的第一份且收藏至今的指南了~ 圖解很清晰易懂,真10分鐘入門的資料:Dcss
而後你會發現以下基礎命令將會成爲你以後幾乎天天都要用到的80%的命令:git
git clone git@github.com:nohosts/nohost.git
克隆遠程倉庫的內容到本地git pull origin master
獲取遠程分支master並merge到當前分支git branch -a
查看所有分支(遠程+本地)git checkout -b bugFix
新建bugFix,並切換到到此分支。(若是分支已存在則去掉-b便可)git status
查看當前~~~~版本狀態(是否修改)git add .
增長當前子目錄~~~~下全部文件更改至暫存區git commit -m 'xxx'
提交暫存區的修改至本地的版本庫, 修改備註爲xxxgit push
將本地版本推送到遠程分支git tag v1.0 dfb02e6e4f2f7b573337763e5c0013802e392818
增長v1.0的tag到某個提交上git merge testBranch
合併testBranch分支至當前分支`git stash
暫存本地的當前修改,將本地代碼重置爲HEAD狀態。(若是須要取出修改,命令後加一個pop便可)git log
顯示提交日誌(若是想每一個提交信息顯示在一行,能夠加上--pretty=oneline)git show dfb02e6e4f2f7b573337763e5c0013802e392818
顯示某個提交的詳細內容git reset --hard HEAD
將當前版本重置爲HEAD注意這兩個命令的區別:github
git pull = fetch + merge git pull --rebase = fetch + rebase
在 Git 中整合來自不一樣分支的修改主要有兩種方法:merge
以及rebase
。 在本節中咱們將學習什麼是「變基」,怎樣使用「變基」,並將展現該操做的驚豔之處,以及指出在何種狀況下你應避免使用它。—— git-scm變基
說明:後面的舉例每一個 分支
都有不一樣的顏色,*前綴
表示如今所處的分支,而 commitid
都由C0、C一、C2代替每個提交的哈希值,箭頭
表示分支的繼承ide
咱們以前整合分支用的最多的就是merge了,那merge和rebase有什麼區別呢?學習
merge
合併兩個分支時會產生一個特殊的提交記錄,它有兩個父節點。簡單說就是:「我要把這兩個父節點自己及它們全部的祖先都包含進來。」
git checkout master; git merge bugFix
下圖中左、右兩張圖分別是執行以下代碼先後的樣子:fetch
能夠看出來,紅色圈圈是最主要的改變—— merge
合併分支後,會在master分支上 新增一個C4提交
,而C4提交裏面有master和bugFix代碼庫全部的修改。網站
此時的bugFix代碼還沒和master 同步
(顏色不一樣),咱們還須要執行以下代碼:ui
git checkout bugFix; git merge master
rebase
實際上就是取出一系列的提交記錄,「複製」它們,而後在另一個地方逐個的放下去。它的優點就是能夠創造更線性的提交歷史。
git checkout bugFix; git rebase master
下圖中左、右兩張圖分別是執行代碼先後的樣子:spa
bugFix 分支裏的內容經過 rebase
直接 複製
到 master 分支上。如今 bugFix 分支上的工做在 master 的最頂端,同時咱們也獲得了一個更 線性
的提交序列。日誌
注意:提交記錄 C3 依然存在(樹上那個半透明的節點),而 C3' 是咱們 rebase
到 master 分支上的 C3 的 副本
(內容是同樣的,只是commitid更新了)。
可是,此時master尚未和bugFix 同步
(顏色不一樣),咱們還須要執行以下代碼:
git checkout master; git rebase bugFix
因爲bugFix繼承自master,因此 Git 只是簡單的把master分支的引用向前移動了一下而已。
git rebase targetBranch originBranch
表示切換到originBranch,而後執行git rebase targetBranch
git rebase -i commitid
如上圖標註的,傳的commitid爲你想修改的提交的 前一個commitid
。執行命令後進入vi模式,會提示你一些操做命令(p、r、e...)
你只須要在最上方修改默認的pick爲你想要的操做,而後退出並wq保存便可生效。
具體操做:
error: cannot 'squash' without a previous commit
)。而後 git rebase --edit-todo
能夠繼續vi編輯注意:
若是想要恢復這一次rebase操做,則能夠執行 git rebase —abort
。
若是想徹底恢復本地分支到遠程的狀態,能夠執行 git reset --hard origin/bugFix
,或者你能夠 git reflog
找到對應提交記錄回滾,可是有點麻煩
當你要改寫的commit history尚未被提交到遠倉庫的時候,也就是說,尚未與他人共享以前,commit history是你私人全部的,那麼想怎麼改寫均可以。
而一旦被提交到遠程後,這時若是再改寫history,那麼勢必和他人的history長的就不同了。git push
的時候,git會比較commit history,若是不一致,commit動做會被拒絕,惟一的辦法就是帶上 -f
參數,強制要求commit,這時git會以committer的history覆寫遠程分支,從而完成代碼的提交。雖然代碼提交上去了,可是這樣可能會形成別人工做成果的丟失,因此使用 -f
參數要慎重。
因此,在不用 -f
的前提下,想維持樹的整潔,方法就是:在 git push
以前,先 git fetch
,再 git rebase
。
fetch
、再 rebase
、最後 push
。cherry-pick
能夠將提交樹上任何地方的提交記錄取過來追加到HEAD
上(只要不是 HEAD 上游的提交就沒問題)。`
git checkout master; git cherry-pick C2
下圖中左、右兩張圖分別是執行代碼先後的樣子:
是否是有點眼熟:D 沒錯 這個和rebase的效果蠻像的,這兩個命令均可以實現複製提交~
git revert HEAD
是用一次新的commit來回滾以前的commit,git reset
是直接向上移動分支,刪除一些commit看上去像從未提交同樣。這二者看似達到的效果是同樣的,其實徹底不一樣。
git reset HEAD~1
git revert HEAD
以下所見,圖1是初始狀態(須要撤回 C2
提交),圖2和3 是從圖1分別執行 reset
和 revert
後的結果:
reset
C1
;如今咱們的本地代碼庫根本就不知道有 C2
這個提交了revert
C2
後面多了一個新提交C2'
,而C2'
引入了更改—— 這些更改是用來撤銷C2
這個提交的。也就是說C2'
的狀態與C1
是相同的。注意:
# 事例 reset後的123 merge了12345 仍是12345 revert後的12345(-3) merge了12345 是12345(-3)
HEAD
是一個對當前檢出記錄的符號引用 —— 也就是指向你正在其基礎上進行工做的提交記錄。HEAD
老是指向當前分支上最近一次提交記錄
(若是想看 HEAD 指向,能夠經過cat .git/HEAD
查看, 若是 HEAD 指向的是一個引用,還能夠用git symbolic-ref HEAD
查看它的指向。)
1. 基礎使用:
^
表示向上移動 1 個提交記錄。~<num>
向上移動多個提交記錄注意:操做符還支持鏈式操,如HEAD^2~3^
2. 延伸用法:
移動分支
能夠直接使用 -f 選項讓分支指向另外一個提交。例以下面的命令會將 master 分支強制指向 HEAD 的第 3 級父提交。
git branch -f master HEAD~3
此次主要就總結了這幾種「不經常使用」git命令,但願你們和我均可以多多練習,讓他變成你須要時就能夠自如使用的「經常使用」命令!:D
牆裂推薦一個可視化的git練習網站,很易懂好用~
推薦git系列文章