Git 基本概念及主要操作
Git

基本概念
Git 是什么?
Git 是目前世界上最先進(jìn)的分布式版本控制系統(tǒng)
Git 近乎所有操作都是本地執(zhí)行
優(yōu)點(diǎn)
版本庫本地化,本地倉庫是服務(wù)器倉庫的完整克隆,包括標(biāo)簽分支、版本記錄等
支持離線提交,適合跨地域協(xié)同開發(fā)
分支切換快速高效、創(chuàng)建和銷毀分支簡單容易
由于Git在本地磁盤上就有項目的完整歷史,所以在Git中絕大多數(shù)操作只需要訪問本地文件和資源,不需要實時的與代碼服務(wù)器連接
Git 文件狀態(tài)
文件的三種狀態(tài)
已修改
修改后的 git 倉庫中的文件(新增文件、被修改的文件或被刪除的文件)
已暫存
git add ‘已修改’ 文件
已提交
git commit ‘已暫存’ 文件,本地的代碼同步到遠(yuǎn)程:git push
主要操作
Git 配置
查看 Git 版本
git --version
配置用戶名和Email
git config --global user.name yourname
git config --global user.email name@mail.com
查看配置信息
git config -l
傳輸方式配置
HTTPS 配置
git config --global credential.helper “cache”
SSH 配置
生成 ssh-key ssh-keygen(根據(jù)ssh-keygen命令,會在本地產(chǎn)生一對秘鑰,公鑰是以.pub為后綴的文件,把公鑰中的內(nèi)容粘貼到服務(wù)器中,就可以使用SSH進(jìn)行通信了)
將 public key 添加到 remote 倉庫
添加 ssh 配置(~/.ssh/config)
格式
權(quán)限 600
配置忽略文件
.gitignore 文件的位置
可以配置在代碼倉庫的任意目錄,但是下面規(guī)則是以 .gitignore 所在目錄為根目錄
初始化倉庫
創(chuàng)建第一個代碼庫
git init
從遠(yuǎn)端克隆倉庫到本地
git clone ssh/httpsurl
遠(yuǎn)程倉庫管理
查看所有的遠(yuǎn)程倉庫
git remote -v
添加遠(yuǎn)程倉庫
git remote add remote-name remote_url
修改遠(yuǎn)程倉庫命名
git remote rename old-remote-name new-remote-name
刪除遠(yuǎn)程倉庫
git remote remove remote-name
分支管理
查看所有分支
git branch
-v 查看分支的最新的提交
-a 查看所有分支包括遠(yuǎn)程分支
切換分支
git checkout branch_name
創(chuàng)建新的分支
git checkout -b new_branch
git branch new_branch --track remote-name/remote-branch(基于遠(yuǎn)程倉庫的分支創(chuàng)建新的分支)
刪除分支
git branch -d branch_name
Git 分支(指針)
分支
本質(zhì)上是個指向 commit 對象的可變指針
分支的默認(rèn)名字為 master
每次提交的時候都會自動向前移動
作用:從某個提交對象往回看的歷史
新建分支
示例:新建一個 testing 分支
git branch testing
如何識別當(dāng)前分支
HEAD 指針(可以理解為當(dāng)前分支的別名)
示例:切換到當(dāng)前分支
git checkout testing
在 testing 分支上做一次提交操作
vim test.rb
git commit -a -m ‘made a change’
每次提交后 HEAD 隨著分支一起向前移動
現(xiàn)在,我們切換回 master 分支
git checkout master
現(xiàn)在做修改的話,相當(dāng)于處于一個舊的版本(即忽略 testing 分支所作的修改)
我們在 master 分支上也做一次提交
vim test.rb
git commit -a -m ‘made other changes’
我們可以看到項目的提交歷史已經(jīng)發(fā)生了分岔
Git 分支(合并)
分支合并:把一個分支中的修改整合到當(dāng)前分支
快進(jìn)式合并(fastforward)
順著一個分支走下去可以到達(dá)另一個分支的合并過程
下圖中,hotfix 比 master 多了一個 c4 的提交,master 分支向前走一步就可以到達(dá) hotfix 分支,完成了從 hotfix 向 master 分支的合并
非快進(jìn)式合并(non-fast forward)(三方合并)
使用兩個分支的末端以及它們的共同祖先進(jìn)行一次簡單的三方合并計算的合并過程
三方 在下圖中指的是 master 分支中的 c4,iss53 分支中的 c5,以及它們兩個之間的共同的父節(jié)點(diǎn) c2
和之前將分支指針向前推進(jìn)所不同的是,git 將此次三方合并的結(jié)果做了一個新的快照,并且自動創(chuàng)建了一個新的提交指向它,這個被稱作是一次合并提交。其特別之處在于,不只有一個父的提交,需要指出的是,git 會自行決定選取哪一個提交作為最優(yōu)的共同祖先,并以此作為合并的基礎(chǔ)(cvs / svn1.5之前版本需要用戶自己選擇最佳的合并基礎(chǔ))
衍合原理:先將 master 分支上新增的節(jié)點(diǎn)以補(bǔ)丁的形式保存在 .git rebase 目錄中,然后同步 hotfix 分支的最新代碼,在 git 中,這種操作叫做 變基
可以使用 rebase 命令,將提交到某一分支上的所有修改都移交到另一分支(就像重新播放一樣)
merge 和 rebase 的最終代碼沒有任何區(qū)別,但是變基使得提交歷史更加整潔
變基合并的提交歷史是一條直線,使用變基一般是為了確保在向遠(yuǎn)程分支推送時,能保持歷史提交的一個整潔
例如我們向某個人維護(hù)的項目貢獻(xiàn)代碼時,在這種情況下,首先在自己的分支里進(jìn)行開發(fā),當(dāng)開發(fā)完成時,需要先將自己的代碼變基的合并到自己的遠(yuǎn)程倉庫master分支上,然后再向主項目提交合并請求。這樣的話,該項目的維護(hù)者就不需要再進(jìn)行整合工作,只需要快進(jìn)合并即可
無論是通過變基還是通過三方合并,整合的最終結(jié)果所指向的快照始終是一樣的,只不過提交歷史不同罷了
變基 是將一系列提交按照原有次序,依次應(yīng)用到另一分支上
合并 是把最終結(jié)果合在一起,分支合并容易產(chǎn)生沖突
合并沖突
類型1:修改了同一文件的同一行
解決方法:確認(rèn)正確的修改
示例:命令行解決
類型2:文件被重命名為不同的名字(樹沖突)
解決方法:確認(rèn)哪個名字是正確的,刪除錯誤的
示例:命令行解決
同步遠(yuǎn)程代碼
Merge 方式同步遠(yuǎn)程代碼
git pull remote-name remote-branch
將遠(yuǎn)程代碼的 master 分支同步到本地的 feature 分支,merge 是一個合并操作,會將兩個分支的修改合并在一起,默認(rèn)操作的情況下,會提交合并中修改的內(nèi)容
merge 的提交歷史,真實的記錄了實際發(fā)生過什么,關(guān)注點(diǎn)在真實的提交歷史上面
Rebase 方式同步遠(yuǎn)程代碼
git pull -r remote-name remote-branch
將遠(yuǎn)程代碼的 master 分支同步到本地的 feature 分支,rebase 提取了遠(yuǎn)程倉庫 maser 分支的修改,將其復(fù)制在了本地 feature 分支的最新提交的后面
rebase 的提交歷史反映了項目過程中發(fā)生了什么,關(guān)注點(diǎn)在開發(fā)過程上面
那么這兩種方式哪一種更好呢?
我們不妨退后一步,想一下提交歷史到底意味著什么?
有一種觀點(diǎn)認(rèn)為,倉庫的提交歷史即記錄實際發(fā)生過什么,它是針對歷史的文檔,本身就有價值,不能亂改。從這個角度來看,改變提交歷史是一種適度,你使用謊言掩蓋的實際發(fā)生過的事情,如果由合并產(chǎn)生的提交歷史是一團(tuán)糟怎么辦?既然就是如此,那么這些痕跡就應(yīng)該被保留下來,讓后人查閱
但是另一種觀點(diǎn)正好相反,然們認(rèn)為提交歷史是項目過程中發(fā)生的故事,沒有人會去出版一本書的第1批草稿,軟件維護(hù)手冊頁是需要反復(fù)修訂才能方便使用,持這一觀點(diǎn)的人會使用 rebase,怎么方便后邊的讀者就怎么寫
現(xiàn)在讓我們回到之前問題上來,到底是 rebase 變基好還是直接的 merge 好,這并沒有簡單的答案,git 是一個非常強(qiáng)大的工具,它允許你對提交歷史做許多事情,但每個團(tuán)隊每個項目對此的需求并不相同,既然我們已經(jīng)學(xué)習(xí)了兩者的用法和原理,相信我們以后在日后的開發(fā)中能做出明智的選擇
跟蹤文件
查看文件狀態(tài)
git status
提交文件
git commit -m “提交一個新的文件”
git commit --amend(加上 amend 參數(shù)可以對上一次提交追加修改,不單可以追加一些代碼的修改,也可以對上一次提交的 message 信息進(jìn)行修改)
提交代碼到遠(yuǎn)程倉庫
git push remote-name remote-branch
查看提交記錄
查看提交記錄
git log
搜索歷史記錄
根據(jù) commiter 搜索
git log --author=“xxx”
根據(jù)提交信息進(jìn)行查找
git log --grep=“xxx”
根據(jù) tag 信息查找
git tag -f
Git 最佳實踐
我們先講一下 fork 的功能,在最早以前在 GitHub 上 fork 是一個貶義詞,它指的是某個人使開源項目向不同的方向發(fā)展,或者說他創(chuàng)建了一個競爭項目,使得原項目的貢獻(xiàn)者變得分裂。后來(也就是現(xiàn)在的意思) fork 的意思是指在遠(yuǎn)程服務(wù)器創(chuàng)建一個完全屬于開發(fā)者自己的項目副本,并且對其有推送權(quán)限。如果我們想?yún)⑴c某個項目,但是并沒有推送權(quán)限,這時我們可以對這個項目進(jìn)行 fork
在下圖的實踐中,通過 fork 這種方式,項目的管理者不需要在忙著把這些用戶添加到項目中,給他們賦予推送權(quán)限。開發(fā)人員可以 fork 這個項目,將代碼項目推送到 fork 項目副本中
左側(cè)是遠(yuǎn)端倉庫,一個是交付代碼倉庫,還有兩個是開發(fā)人員 fork 出的個人遠(yuǎn)程倉庫,這兩個個人遠(yuǎn)程倉庫,包含了原來上游交付倉庫中的所有內(nèi)容,如分支、tag、提交等等。
開發(fā)人員將代碼拉取到本地進(jìn)行開發(fā),開發(fā)完成后 push 到個人遠(yuǎn)程倉庫,此時再向交付倉庫發(fā)起 pull request 的請求
項目架構(gòu)師 / 項目管理者負(fù)責(zé)審核把關(guān)代碼的質(zhì)量,審核通過的代碼,最終才會進(jìn)入到交付代碼倉庫,通過這種方式有效地保證了生產(chǎn)環(huán)境代碼的質(zhì)量
Git ssh
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。