
2017/3/4 ?更新fetch、pull、rebase相關的命令,長期不定時更新必要的git命令。
準備工作:
根據(jù)自己的情況,下載安裝Git(我這里是windows 10)。Git的使用可以通過命令行或者圖形界面使用,這里推薦命令行并且只討論通過命令行的方式使用。
安裝好后,在文件系統(tǒng)的任意位置(比如桌面)右擊鼠標,你會看到有個Git Bash Here,這個就是我們要的。

找到你需要使用git的項目文件夾,然后在該文件夾下右擊鼠標,打開git bash(或者先打開git bash然后切換到目標文件夾),接著就可以開始使用git了:
注:按照日常使用git的順序來羅列
git init —— 將當前所在的文件夾變成git倉庫,也就是初始化一個git倉庫。
add和commit
git add filename.txt —— 修改文件后,請求將filename.txt放入git暫存區(qū),這條語句可以多次實施
git add ./ —— 請求將當前目錄所有更改的文件放入git暫存區(qū),這條語句可以多次實施。
git commit -m "add file success" —— 提交修改請求,將暫存區(qū)內(nèi)容提交到版本庫,更新版本庫最新版本(不管之前add了幾次,全部一次提交),-m后面是本次提交的文字說明
查看、撤銷和回退
git status —— 查看倉庫當前狀態(tài),查看有沒有add和commit等信息
git log—— 查看最近幾個commit的詳細歷史記錄,會得到每一個commit的類似如下的信息:
commit a9ca35f38c7bbd0e91af5e05dc7a88bc5f76a00d
Author: DongHui
Date: ?Sun Nov 20 18:14:17 2016 +0800
first
第二行的一串數(shù)字字母是commit id,最后的first是該commit的說明
git log --pretty=oneline?—— 查看所有commit的簡易歷史記錄。顧名思義,只用一行顯示每個commit信息
git show 1234567 —— 查看commit id 為1234567...的詳細信息
git diff —— 查看當前工作區(qū)(也就是你最新的修改了但還沒有add的項目文件)和暫存區(qū)的不同。
git diff filename.txt —— 和git diff一樣,不過是查看具體文件。
git diff HEAD —— 查看當前工作區(qū),和git版本庫里最新版本的不同
git diff HEAD -- filename.txt —— 和git diff HEAD一樣,不過是查看具體文件
git checkout -- filename.txt —— 撤銷filename.txt當前工作區(qū)的修改,不管現(xiàn)在工作區(qū)暫存區(qū)版本庫是什么狀態(tài),這條語句的本質是:暫存區(qū)內(nèi)容覆蓋工作區(qū)內(nèi)容。如果之前并沒有任何add操作,那么執(zhí)行這條語句后,filename.txt的工作區(qū)、暫存區(qū)和版本庫應該是一致的。
git checkout ./ —— 撤銷當前工作區(qū)全部文件的修改。本質同上。
git diff --cached或者git diff --staged —— 查看當前暫存區(qū)和git版本庫里最新版本的不同
git reset HEAD -- filename.txt —— 撤銷暫存區(qū)的修改,這條語句的本質是:版本庫最新版本覆蓋暫存區(qū),工作區(qū)不受影響。
git reset HEAD 或者 git reset —— 撤銷暫存區(qū)的修改。本質同上。
git reset --hard HEAD^ —— 回退到上一個版本,其中HEAD表示當前版本,HEAD^表示上一個版本
git reset --hard HEAD^^ —— 回退到上上個版本
git reset --hard HEAD~100 —— 回退到往上100個版本
git reset --hard 1234567 —— 轉到commit id為1234567......的那個版本,commit id很長且唯一,只要寫出前幾位(7位足夠了)git會自動識別是哪一個commit,使用這條命令不僅可以回退到某個歷史版本,也可以定位到比較新的版本。
但是怎么查看commit id呢?
git reflog —— 列出所有命令記錄
git rm filename.txt —— 從版本庫中刪除filename.txt
關于遠程庫的命令
以github為例,新建好github倉庫(配置過程不贅述)
git remote add origin git@github.com:DongHui44/myfirstrepository.git —— 使用SSH的方式關聯(lián)遠程庫(配置SSH方法另行查詢)其中DongHui44是我的github賬號,myfirstrepository是我的遠程倉庫。
git remote add origin https://github.com/DongHui44/myfirstrepository.git —— 使用https的方式關聯(lián)遠程庫
推薦SSH的方式關聯(lián),關聯(lián)后,遠程倉庫的默認名稱為origin,想改也可以改。
git push -u origin master —— 第一次推送master分支的所有內(nèi)容
git push origin master —— 推送到遠程倉庫的master的分支,在這之前要先commit。這里的master也可以是其他分支
git clone git@github.com:DongHui44/myfirstrepository.git —— 在合適的地方將遠程的倉庫克隆到本地,在此之前,同樣要配置SSH。在克隆的時候,git自動把遠程庫的master分支和本地的master分支對應起來,遠程庫的默認名稱為origin
git remote —— 查看遠程倉庫的信息
git remote -v —— 查看遠程倉庫的詳細信息
git push --set-upstream origin newFunction —— 遠程庫沒有本地的分支的話,第一次push要使用這條語句,那么遠程庫也會創(chuàng)建一個名為newFunction的分支倉庫與之對應,同時上傳本地內(nèi)容
git fetch origin —— 獲取遠程庫的所有分支最新版本到本地
git fetch origin remoteBranch —— 獲取遠程庫分支remoteBranch最新版本到本地,這個時候本地代碼未受到影響,可以將兩者進行對比等操作
git pull origin remoteBranch —— 相當于git fetch origin remoteBranch和git merge origin/remoteBranch兩步操作
創(chuàng)建、切換、合并分支
git checkout -b newFunction —— 創(chuàng)建分支newFunction并切換到newFunction
上面一句相當于以下兩句命令:
git branch newFunction —— 創(chuàng)建分支newFunction
git checkout newFunction —— 切換到newFunction
git branch —— 查看所有分支,其中當前所在分支的前面會標注星號*
git checkout master —— 在newFunction下修改文件A并add、commit后,切換到master分支
git merge newFuction —— 把newFunction的修改合并到master中,不推薦使用這條語句,因為有時候merge會處于Fast forward模式,這種模式下,合并分支后,newFunction分支相關信息會被刪除。建議合并時采用下面的語句,禁用Fast forward模式
git merge --no-ff -m "merge info" newFunction —— 合并newFunction的修改到master中,合并后newFunction依然存在,需要刪除時手動刪除即可。
注意:如果newFunction和master各自修改了同樣的地方,產(chǎn)生了沖突,那么git merge會失敗,git會給出提示,將沖突的地方修改好即可再次merge
接下來講rebase,rebase和merge很類似,都是合并分支,但是一般情況下不建議用rebase,為什么呢?下面會講
git rebase newFunction —— 合并newFunction到master
下面看看rebase和merge的區(qū)別,它們的過程如下圖所示

說明1:master是主分支,branch是另一個分支,master0,master1,branch0這些都是commit記錄
說明2:merge采用git merge --no-ff -m "merge info" branch name這條語句,所以會有master4
我們假設merge和rebase的過程一帆風順,當要把branch合并到master時,merge是形成一個新的提交master4,而branch中的commit也會按照時間先后插入到master的commit記錄。而rebase的情況就和上圖一樣,rebase后master的commit記錄一定是這樣的:master0->master1->branch0->branch1->branch2->master2->master3,而原來的branch不受影響,是不是突然理解了為什么叫rebase了?
使用rebase表面上看起來和merge是一樣的,但實際git在背后的操作完全不一樣。merge的commit記錄是嚴格按照時間顯示的,分支上commit在通過merge合并到主分支后,其commit記錄也按照時間的前后合并到主分支,而rebase不是這樣。結論:rebase和merge很像,但是有一個壞處:讓你commit記錄變得混亂。
注意:如果newFunction和master各自修改了同樣的地方,產(chǎn)生了沖突,那么git rebase會失敗,先解決沖突,然后執(zhí)行下面的命令:
git rebase --continue —— 運行這條語句繼續(xù)rebase,這里要注意,執(zhí)行這條語句前要先執(zhí)行git add
git branch -d newFunction —— 刪除分支newFunction
stash、tag的使用
git stash —— 將當前未提交(但是還不能提交)的工作現(xiàn)場儲藏起來。有的時候要立刻停止當前工作,創(chuàng)建分支,解決問題,合并分支,然后接著原來的工作,這個時候就要用到這條命令。這條語句可以多次使用。
git stash list —— 查看儲藏起來的工作現(xiàn)場
git stash apply —— 恢復工作現(xiàn)場,此時,儲藏的工作現(xiàn)場并沒有刪除
git stash drop —— 刪除儲藏的工作現(xiàn)場
git stash pop —— 恢復工作現(xiàn)場,同時把儲藏的工作現(xiàn)場刪除
git tag v1.0 —— 在最新commit的基礎上,給當前分支打一個標簽,可以表示版本號等等,這里的標簽是:v1.0
git tag —— 查看所有標簽,標簽是按字母排列的
git tag v0.1 123456 —— 給commit id是123456開頭的commit打標簽,標簽為:v0.1
git show v1.0 —— 查看標簽為v1.0的commit的詳細信息
git tag -d v1.0 —— 刪除標簽v1.0
git push origin v0.1 —— 推送標簽v0.1到遠程倉庫
git push origin --tags ——推送所有標簽到遠程倉庫
git push origin :refs/tags/v0.1 —— 刪除遠程倉庫里的v0.1標簽,在這條命令前要確保之前已經(jīng)在本地刪除了v0.1標簽
其他常用命令
git config --global color.ui true —— 配置ui的顏色
在實際應用git時,有一些文件不能也沒有必要被push到遠程倉庫,git提供了解決方案。
在git工作區(qū)的根目錄下新建一個.gitignore文件,在里面配置想要git忽略推到遠程倉庫的文件類型。(作為安卓開發(fā)者,額外提一句:Android Studio好像自動幫我們創(chuàng)建了.gitignore文件,其他軟件不清楚)
工作區(qū)內(nèi)容不同,配置也相應不同,具體可參考:https://github.com/github/gitignore該github項目提供了各種工作內(nèi)容需要配置的忽略文件。
git add -f example.class —— 強制add某個文件,不管這個文件有沒有被忽略,這里是example.class。
如果git add失敗并被系統(tǒng)提示已經(jīng)進入忽略名單,那么可以使用以下命令查看忽略詳情
git check-ignore -v example.class —— 查看example.class被忽略的詳情
回車后,系統(tǒng)會返回信息,例如:
.gitignore:3:*.class ? ?example.class
意思是.gitignore文件的第三行的*.class導致的忽略。
git可以給系統(tǒng)指令改別名
git config --global alias.st status —— 意思是用st代替status,以后每次要查看狀態(tài)(git status)只需要git st就行了,--global意思是該用戶下全局生效。
再舉例子:
git config --global alias.co checkout —— 用co代替checkout
注1:git命令繁多,本文沒有提到的可以自己查詢或者看注2本文所參考的教程,英文好的可以直接去官網(wǎng)看看。
注2:參考資料:廖雪峰的git教程
2017/2/23