Git 是用C寫的一個分佈式版本控制系統。
集中式 VS 分佈式
集中式版本控制系統必須聯網才能工作。
分佈式版本控制系統根本沒有「中央服務器」,每個人的電腦上都是一個完整的版本庫。
多個人如何協作只需把各自的修改推送給對方,就可以互相看到對方的修改了。
和集中式版本控制系統相比,分佈式版本控制系統的安全性要高很多。Git的優勢不單是不必聯網還有極其強大的分支管理,把SVN等遠遠拋在了後面。
GIT 的組成部分:工作區、版本庫、儲藏區、暫存區;
版本回退
- HEAD指向的版本就是當前版本,使用命令切換不同版本git reset --hard commit_id。
- 用git log可以查看提交歷史,以便確定要回退到哪個版本。
- 用git reflog查看命令歷史,以便確定要回到較新的版本。
工作區和暫存區
把文件往Git版本庫裏添加的時候,是分兩步執行的:
第一步是用
git add
把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用
git commit
提交更改,實際上就是把暫存區的所有內容提交到當前分支。
如果沒有add ,commit 時是不會將變動提交到版本庫的,需注意。
撤銷修改
場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令
git checkout -- file
。
場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令
git reset HEAD file
,就回到了場景1,第二步按場景1操作。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考
版本回退
,不過前提是沒有推送到遠程庫。
刪除文件
命令
git rm
用於刪除一個文件。如果一個文件已經被提交到版本庫,那麼你永遠不用擔心誤刪,但是要小心,你只能恢復文件到最新版本,你會丟失
最近一次提交後你修改的內容
。
遠程倉庫
關聯後,使用命令
git push -u origin master
第一次推送master分支的所有內容;
此後,每次本地提交後,只要有必要,就可以使用命令
git push origin master
推送最新修改;
分佈式版本系統的最大好處之一是在本地工作完全不需要考慮遠程庫的存在,也就是有沒有聯網都可以正常工作
遠程倉庫克隆
要克隆一個倉庫,首先必須知道倉庫的地址,然後使用
git clone
命令克隆。
Git支持多種協議,包括
https
,但通過
ssh
支持的原生
git
協議速度最快。
創建與合併分支
Git鼓勵大量使用分支:
查看分支:
git branch
創建分支:
git branch <name>
切換分支:
git checkout <name>
創建+切換分支:
git checkout -b <name>
合併某分支到當前分支:
git merge <name>
刪除分支:
git branch -d <name>
合併分支
git merge dev
將dev 分支合併到當前分支
用帶參數的
git log
也可以看到分支的合併情況:
git log --graph --pretty=oneline --abbrev-commit
當Git無法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併完成。
用
git log --graph
命令可以看到分支合併圖。
分支管理策略
合併分支時,如果可能,Git會用
Fast forward
模式,但這種模式下,刪除分支後,會丟掉分支信息。
如果要強制禁用
Fast forward
模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。
下面我們實戰一下
--no-ff
方式的
git merge
:
準備合併
dev
分支,請注意
--no-ff
參數,表示禁用
Fast forward
:
$
git merge --no-ff -m
"merge with no-ff"
dev
把commit描述寫進去。
合併後,我們用
git log
看看分支歷史:
$ git log --graph --pretty=oneline --abbrev-commit*
7825
a50 merge
with
no-ff|\| *
6224937
add merge|/*
59
bc1cb conflict fixed...
可以看到,不使用
Fast forward
模式,merge後就像這樣:
分支策略
在實際開發中,我們應該按照幾個基本原則進行分支管理:
首先,
master
分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面幹活;
那在哪幹活呢?幹活都在
dev
分支上,也就是說,
dev
分支是不穩定的,到某個時候,比如1.0版本發佈時,再把
dev
分支合併到
master
上,在
master
分支發佈1.0版本;
你和你的小夥伴們每個人都在
dev
分支上幹活,每個人都有自己的分支,時不時地往
dev
分支上合併就可以了。
所以,團隊合作的分支看起來就像這樣:
合併分支時,加上
--no-ff
參數就可以用普通模式合併,合併後的歷史有分支,能看出來曾經做過合併,而
fast forward
合併就看不出來曾經做過合併。
Bug分支
bug都可以通過一個新的臨時分支來修復,修復後,合併分支,然後將臨時分支刪除。
當你接到一個修復bug的任務時,很自然地,你想創建一個分支來修復它,但是,當前正在
dev
上進行的工作還沒有提交:
$
git status
怎麼辦?
Git還提供了一個
stash
功能,可以把當前工作現場「儲藏」起來,等以後恢復現場後繼續工作:
$
git stash
修復完成後,並完成合並,最後刪除
issue-101
分支:
$
git checkout dev
Switched
to branch
'dev'
$
git status
用
git stash list
命令恢復儲藏內容:
需要恢復一下,有兩個辦法:
一是用
git stash apply
恢復,但是恢復後,stash內容並不刪除,你需要用
git stash drop
來刪除;
另一種方式是用
git stash pop
,恢復的同時把stash內容也刪了:
$
git stash pop
再用
git stash list
查看,就看不到任何stash內容了:
$
git stash list
你可以多次stash,恢復的時候,先用
git stash list
查看,然後恢復指定的stash,用命令:
修復bug時,我們會通過創建新的bug分支進行修復,然後合併,最後刪除;
當手頭工作沒有完成時,先把工作現場
git stash
一下,然後去修復bug,修復後,再
git stash pop
,回到工作現場。
Feature分支
開發一個新feature,最好新建一個分支;
如果要丟棄一個沒有被合併過的分支,可以通過
git branch -D <name>
強行刪除。
多人協作
- 查看遠程庫信息,使用git remote -v;
- 本地新建的分支如果不推送到遠程,對其他人就是不可見的;
- 從本地推送分支,使用git push origin branch-name,如果推送失敗,先用git pull抓取遠程的新提交;
- 在本地創建和遠程分支對應的分支,使用git checkout -b branch-name origin/branch-name,本地和遠程分支的名稱最好一致;
- 建立本地分支和遠程分支的關聯,使用git branch --set-upstream branch-name origin/branch-name;
- 從遠程抓取分支,使用git pull,如果有衝突,要先處理衝突。
標籤管理
- 命令git tag <name>用於新建一個標籤,默認爲HEAD,也可以指定一個commit id;
- git tag -a <tagname> -m "blablabla..."可以指定標籤信息;
- git tag -s <tagname> -m "blablabla..."可以用PGP簽名標籤;
- 命令giit tag可以查看所有標籤。
- 命令git push origin <tagname>可以推送一個本地標籤;
- 命令git push origin --tags可以推送全部未推送過的本地標籤;
- 命令git tag -d <tagname>可以刪除一個本地標籤;
- 命令git push origin :refs/tags/<tagname>可以刪除一個遠程標籤。
使用GitHub
- 在GitHub上,可以任意Fork開源倉庫;
- 自己擁有Fork後的倉庫的讀寫權限;
- 可以推送pull request給官方倉庫來貢獻代碼。
使用碼雲
使用GitHub時,國內的用戶經常遇到的問題是訪問速度太慢,有時候還會出現無法連接的情況(原因你懂的)。
和GitHub相比,碼雲也提供免費的Git倉庫。此外,還集成了代碼質量檢測、項目演示等功能。對於團隊協作開發,碼雲還提供了項目管理、代碼託管、文檔管理的服務,5人以下小團隊免費。
本地庫關聯碼雲和github
本地庫關聯遠程庫時需要注意遠程庫名稱 不能都叫 origin
用
git remote -v
查看遠程庫信息:
刪除已有的遠程庫:
git remote rm origin
git本身是分佈式版本控制系統,可以同步到另外一個遠程庫,當然也可以同步到另外兩個遠程庫。
使用多個遠程庫時,我們要注意,git給遠程庫起的默認名稱是
origin
,如果有多個遠程庫,我們需要用不同的名稱來標識不同的遠程庫。
git remote add github git
@github
.
com:
michaelliao/learngit.git
注意,遠程庫的名稱叫
github
,不叫
origin
了。
接着,再關聯碼雲的遠程庫:
git remote add gitee git
@gitee
.
com:
360linker/360linker.git
同樣注意,遠程庫的名稱叫
gitee
,不叫
origin
。
現在,我們用
git remote -v
查看遠程庫信息,可以看到兩個遠程庫:
git remote -vgitee git
@gitee
.
com:
360linker/learngit.git (fetch)gitee git
@gitee
.
com:
360linker/learngit.git (push)github git
@github
.
com:
360linker/learngit.git (fetch)github git
@github
.
com:
360linker/learngit.git (push)
如果要推送到GitHub,使用命令:
git push github master
如果要推送到碼雲,使用命令:
git push gitee master
這樣一來,我們的本地庫就可以同時與多個遠程庫互相同步:
忽略文件
- 忽略某些文件時,需要編寫.gitignore;
- .gitignore文件本身要放到版本庫裏,並且可以對.gitignore做版本管理
、配置別名、搭建git 服務器等需要深入瞭解的小夥伴自行學習。
=================================END===========================
360linker是一個分享IT 圈內 市場、技術、產品、運營 等信息的技術社區。在技術更新換代如此之快的當前,達到高效的的技能的提升,歡迎更多的小夥伴加入。掃描下方二維碼或者添加微信 li_360linker,備註IT。