git是分布式版本控制系統(tǒng),啥是分布式的呢,就是每一個用戶的主機上都有一個版本庫,可以在本地進(jìn)行版本管理。如果需要多人合作的時候,就再通過中央服務(wù)器進(jìn)行版本交換。和集中式的版本控制的區(qū)別就是,集中式的版本管理是只在遠(yuǎn)程,每一次commit都必須聯(lián)網(wǎng),這就有網(wǎng)絡(luò)的時延大大滴,而且當(dāng)中央服務(wù)器掛掉的時候所有人都掛了,因為完整倉庫只存在于服務(wù)器。
git版本庫
版本庫可以理解為Git倉庫,這個目錄下的所有文件都會被Git管理起來,每個文件的修改,刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻還原。
命令:
在一個目錄下,git init就可以把此目錄變成Git可以管理的目錄。

這里有幾個概念:
工作區(qū):電腦里能看到的目錄,嗯,就是單純的目錄
版本庫(Repository):Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區(qū),還有Git為我們自動創(chuàng)建的第一個分支master,以及指向master的一個指針叫HEAD。
把文件往Git版本庫里添加的時候,是分兩步執(zhí)行的:
第一步是用
git add file把文件添加進(jìn)去,實際上就是把文件修改添加到暫存區(qū);
同理rm 是刪除,git rm file是將文件在暫存區(qū)內(nèi)刪除第二步是用
git commit -m "commit message"提交更改,實際上就是把暫存區(qū)的所有內(nèi)容提交到當(dāng)前分支。
因為我們創(chuàng)建Git版本庫時,Git自動為我們創(chuàng)建了唯一一個master分支,所以,現(xiàn)在,git commit就是往master分支上提交更改。
你可以簡單理解為,需要提交的文件修改通通放到暫存區(qū),然后,一次性提交暫存區(qū)的所有修改。
如果有一些文件沒有add到暫存區(qū),那么這些文件也是commit不上去的哦~
但是難免會犯錯
- Case1:當(dāng)改亂了工作區(qū)的修改,想直接丟棄工作區(qū)的修改,回退到clean的狀態(tài),用命令
git checkout -- file - Case2:改亂了工作區(qū)的修改,并且add到暫存區(qū)了。首先,將暫存區(qū)的內(nèi)容回退到add前的版本
git reset HEAD file,其次丟棄工作區(qū)的修改git checkout -- file - Case3:已經(jīng)提交(add)了修改至?xí)捍鎱^(qū),并且commit到版本庫了,使用
git reset --hard commit_id回退到commit_id的版本。commit_id是怎樣獲得的呢,通過git log,git log --pretty=online,git reflog來查看。
git log與git reflog的區(qū)別是,git log當(dāng)回退到某個版本時,此版本之后的記錄都自動抹去了。git reflog是提交的完整的命令歷史,回退到某個版本,仍然可以查到位于此版本號以后的版本號。
遠(yuǎn)程倉庫
關(guān)聯(lián)遠(yuǎn)程倉庫:git remote add origin git@server-name:path/repo-name.git。
關(guān)聯(lián)后,使用命令git push -u origin master第一次推送master分支的所有內(nèi)容
以后每次本地提交后,都可以使用git push origin master推送最新修改
使用git clone從遠(yuǎn)程倉庫克隆至本地呀
git創(chuàng)建分支
git branch 查看當(dāng)前分支
git branch dev 創(chuàng)建dev分支
git checkout dev 切換至dev分支
git checkout -b dev 創(chuàng)建并切換至dev分支
git merge xxx 用于將指定分支的工作成果合并到當(dāng)前分支
git branch -d branchname
git解決沖突
當(dāng)兩個分支同時對一個文件進(jìn)行修改時,merge時會發(fā)生沖突,解決辦法是git status查看沖突文件,然后查看文件內(nèi)容,Git用<<<<<<<,=======,>>>>>>>標(biāo)記出不同分支的內(nèi)容。
例如:
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
然后手動修改沖突的內(nèi)容,解決沖突。
用git log可以查看分支歷史。git log --graph命令可以看到分支合并圖
git 分支管理策略
一般情況下,合并分支是采用的fast-forward,即當(dāng)前分支與要合并的分支指針指向同一處。
不使用fast-forward,命令為git merge --no-off dev,兩個分支的指針是指向不同位置的。
bug分支
存在的問題:當(dāng)前工作區(qū)在開發(fā)新功能,但是線上出了問題急需解決,需要一個干凈的工作區(qū)。
git提供了一個stash功能,git stash可以把當(dāng)前工作現(xiàn)場儲藏起來,拉過來一個干凈的工作現(xiàn)場,然后從master分支拉出來一個新的分支,修復(fù)完成后,切換到master分支并完成合并。
恢復(fù)工作現(xiàn)場時:
查看工作現(xiàn)場:git stash list
恢復(fù)工作現(xiàn)場:git stash apply
刪除工作現(xiàn)場:git stash drop
恢復(fù)&刪除工作現(xiàn)場:git stash pop
如果多次stash,恢復(fù)的時候先用git stash list查看,然后恢復(fù)指定的stash:git stash apply stash@{0}
開發(fā)新分支
開發(fā)一個新feature,最好新建一個分支
如果要丟棄一個沒有被合并過的分支,可以通過git branch -D <name>強行刪除。
多人合作
多人協(xié)作的工作模式通常是這樣:
- 首先,可以試圖用
git push origin branch-name推送自己的修改; - 如果推送失敗,則因為遠(yuǎn)程分支比你的本地更新,需要先用
git pull試圖合并; - 如果合并有沖突,則解決沖突,并在本地提交;
- 沒有沖突或者解決掉沖突后,再用
git push origin branch-name推送就能成功! - 查看遠(yuǎn)程庫信息,使用
git remote -v;
本地新建的分支如果不推送到遠(yuǎn)程,對其他人就是不可見的;
從本地推送分支,使用git push origin branch-name,如果推送失敗,先用git pull抓取遠(yuǎn)程的新提交;
在本地創(chuàng)建和遠(yuǎn)程分支對應(yīng)的分支,使用git checkout -b branch-name origin/branch-name,本地和遠(yuǎn)程分支的名稱最好一致;
從遠(yuǎn)程抓取分支,使用git pull,如果有沖突,要先處理沖突。
如果git pull提示“no tracking information”,則說明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒有創(chuàng)建,用命令git branch --set-upstream branch-name origin/branch-name。
標(biāo)簽
Git標(biāo)簽是版本庫的快照,其實是指向某個Commit的指針,是以一種容易記憶的方式設(shè)定的,一般可指定為版本號vx.x
打標(biāo)簽git tag v1.0
正常情況下,標(biāo)簽是打在此分支的最新提交的commit上的
git tag 查看標(biāo)簽
git show tagname 查看標(biāo)簽信息
git tag commit_id 為commit_id打標(biāo)簽
git tag -a v0.1 -m "version 0.1 released" 3628164 創(chuàng)建帶有說明的標(biāo)簽,-a指定標(biāo)簽名,-m指定說明文字
git push origin v0.1 推送標(biāo)簽到遠(yuǎn)程
git push origin --tags 一次性推送尚未推送到遠(yuǎn)程的本地標(biāo)簽
git tag -d v0.1 在本地刪除標(biāo)簽
git push origin :refs/tags/v0.9 刪除遠(yuǎn)程的標(biāo)簽
參考文獻(xiàn)
Git教程