實(shí)戰(zhàn)必備:Git 入門(mén)級(jí)教程
- 帶你快速理解git
- 介紹一下Git 的由來(lái)
- 集中式和分布式版本控制系統(tǒng)區(qū)別
- 安裝git
- 一次完整的git使用過(guò)程
- 分支管理
帶你快速理解git
學(xué)完后能立刻上手的Git教程!圖片有沒(méi)有想過(guò)把每次修改的代碼內(nèi)容都記錄下來(lái),防止改錯(cuò)了需要回退,也方便查看每次修改了什么;有沒(méi)有想過(guò)一個(gè)代碼需要多人操作,多人切換修改后能立刻生成一份新的代碼,讓開(kāi)發(fā)效率更高。那就一起來(lái)了解一下git吧,讓你不再手動(dòng)管理文檔了!
版本控制系統(tǒng)有很多,但是git最出名,為什么呢?像CVS和SVN這種集中式的版本控制系統(tǒng),它們不但速度慢,而且必須聯(lián)網(wǎng)才能使用。
介紹一下Git 的由來(lái)
隨著Linux的不斷壯大,其代碼的管理遇到了難題,于是,Linux的締造者 Linus Torvalds,選用了分布式版本控制系統(tǒng) BitKeeper 來(lái)管理和維護(hù)代碼。但是,后來(lái)由于一些不太美好的原因,開(kāi)發(fā) BitKeeper 的商業(yè)公司同 Linux 內(nèi)核開(kāi)源社區(qū)的合作關(guān)系結(jié)束,他們收回了 Linux 內(nèi)核社區(qū)BitKeeper 的權(quán)力。Linux 開(kāi)源社區(qū)(特別是 Linux 的締造者 Linus Torvalds)基于使用 BitKeeper 時(shí)的經(jīng)驗(yàn)教訓(xùn),使用C開(kāi)發(fā)出了自己的分布式版本系統(tǒng)git,而且做了很多改進(jìn)。不得不說(shuō)很牛!!
集中式和分布式版本控制系統(tǒng)區(qū)別
集中式版本控制系統(tǒng),版本庫(kù)是集中存放在中央服務(wù)器的,而干活的時(shí)候,用的都是自己的電腦,所以要先從中央服務(wù)器取得最新的版本,然后開(kāi)始干活,干完活了,再把自己的活推送給中央服務(wù)器。
分布式版本控制系統(tǒng)實(shí)質(zhì)上是根本沒(méi)有“中央服務(wù)器”這一說(shuō)的,每個(gè)人的電腦上都是一個(gè)完整的版本庫(kù)(可以稱(chēng)為本地倉(cāng)庫(kù)),這樣,你工作的時(shí)候,就不需要聯(lián)網(wǎng)了,因?yàn)榘姹編?kù)就在你自己的電腦上。分布式版本控制系統(tǒng)通常也有一臺(tái)充當(dāng)“中央服務(wù)器”的電腦(這里其實(shí)就是遠(yuǎn)程倉(cāng)庫(kù)),但這個(gè)服務(wù)器的作用僅僅是用來(lái)方便“交換”大家的修改,沒(méi)有它大家也一樣干活,只是交換修改不方便而已。
安裝git
Linux上安裝:
兩種方法
一是采用yum來(lái)安裝git,可以參考下面的步驟:
1.安裝yum
- yum install git
若出現(xiàn)是否下載,點(diǎn)擊yes
2.驗(yàn)證安裝是否成功
- git --version
出現(xiàn)版本號(hào),說(shuō)明安裝成功 git是默認(rèn)安裝在/usr/libexec/git-core目錄下,可輸入cd指令來(lái)查看安裝的信息
二是采用源碼編譯的方式安裝,這種安裝方法的好處就是方便控制安裝的版本
1.先從https://github.com/git/git/releases上下載源碼,在這里我們可以找到所有g(shù)it已發(fā)布的版本,我們選擇最新版的tar.gz包。
最近最新的版本是v2.30.0
下載命令為:
- wget https://github.com/git/git/archive/v2.30.0.tar.gz
解壓
- tar -zxvf git-2.22.0.tar.gz
使用cd命令進(jìn)入解壓后的文件夾
安裝編譯所需要的依賴(lài)
- yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker
耐心等待安裝完成,中途出現(xiàn)提示的時(shí)候輸入y并按回車(chē)。
安裝編譯源碼所需依賴(lài)的時(shí)候,yum自動(dòng)幫你安裝了git,這時(shí)候你需要先卸載這個(gè)舊版的git。
- yum -y remove git
編譯git源碼
- make prefix=/usr/local/git all
安裝git至/usr/local/git路徑
- make prefix=/usr/local/git install
配置環(huán)境變量
- vi /etc/profile
- 在底部加上
- export PATH=$PATH:/usr/local/git/bin
( 輸入 :wq! 保存修改)
刷新環(huán)境變量
- source /etc/profile
查看Git是否安裝完成
- git --version
Mac上安裝:
兩種方法
一是安裝homebrew,然后通過(guò)homebrew安裝Git,具體方法請(qǐng)參考homebrew的文檔:http://brew.sh/。
第二種方法更簡(jiǎn)單,也是推薦的方法,就是直接從AppStore安裝Xcode,Xcode集成了Git,不過(guò)默認(rèn)沒(méi)有安裝,你需要運(yùn)行Xcode,選擇菜單“Xcode”->“Preferences”,在彈出窗口中找到“Downloads”,選擇“Command Line Tools”,點(diǎn)“Install”就可以完成安裝了。
Windows上安裝:
從Git官網(wǎng)直接下載安裝程序,然后按默認(rèn)選項(xiàng)安裝即可。
安裝完成后,在開(kāi)始菜單里找到“Git”->“Git Bash”,蹦出一個(gè)類(lèi)似命令行窗口的東西,就說(shuō)明Git安裝成功!或者是右擊看到下面這幾個(gè)圖標(biāo):
圖片
一般習(xí)慣于用git bash here
最后一步設(shè)置標(biāo)識(shí),輸入下面的命令:
- $ git config --global user.name "Your Name"
- $ git config --global user.email "email@example.com"
注意git config --global參數(shù),有了這個(gè)參數(shù),表示你這臺(tái)機(jī)器上所有的Git倉(cāng)庫(kù)都會(huì)使用這個(gè)配置,當(dāng)然你也可以對(duì)某個(gè)倉(cāng)庫(kù)指定的不同的用戶(hù)名和郵箱。
現(xiàn)在,Git可以在Linux、Unix、Mac和Windows這幾大平臺(tái)上正常運(yùn)行了。
先來(lái)理解幾個(gè)基本概念
上面這幅圖中展示了git的基本使用流程,大致可以分為以下四個(gè)區(qū)域:
workspace:工作區(qū)
平時(shí)開(kāi)發(fā)時(shí),改動(dòng)代碼的地方,也就是每次有新的需求下來(lái),直接在該區(qū)域修改代碼,該區(qū)域的代碼最新。
index/stage:暫存區(qū)
工作區(qū)有一個(gè)隱藏目錄.git,這個(gè)不算工作區(qū),而是 Git 的版本庫(kù)(包括暫存區(qū)和對(duì)象區(qū))。
當(dāng)你完成某個(gè)需求或功能后需要提交到遠(yuǎn)程倉(cāng)庫(kù),那么第一步就是通過(guò)git add先提交到暫存區(qū),被git管理。
.git目錄下的暫存區(qū)(index文件)會(huì)記錄git add添加文件的相關(guān)信息(文件名、大小、timestamp...),不保存文件實(shí)體, 通過(guò)id指向每個(gè)文件實(shí)體。暫存區(qū)標(biāo)記了你當(dāng)前工作區(qū)中,哪些內(nèi)容是被git管理的。
repository:本地倉(cāng)庫(kù)
git commit可以同步index中的內(nèi)容到本地倉(cāng)庫(kù)。
本地倉(cāng)庫(kù)保存了對(duì)象被提交過(guò)的各個(gè)版本,比起工作區(qū)和暫存區(qū)的內(nèi)容,它要更舊一些。
remote:遠(yuǎn)程倉(cāng)庫(kù)
git push 可以同步本地倉(cāng)庫(kù)中的內(nèi)容到遠(yuǎn)程倉(cāng)庫(kù)。
一次完整的git使用過(guò)程
1、創(chuàng)建或獲取版本庫(kù)
- 創(chuàng)建版本庫(kù)
選擇一個(gè)文件目錄,然后右擊打開(kāi)git bash命令行窗口,執(zhí)行下述命令初始化一個(gè)本地倉(cāng)庫(kù):
- git init
該命令將創(chuàng)建一個(gè)名為 .git 的目錄,這個(gè)目錄是git來(lái)跟蹤管理版本的,沒(méi)事千萬(wàn)不要手動(dòng)亂改這個(gè)目錄里面的文件,否則,會(huì)把git倉(cāng)庫(kù)給破壞了。
- 獲取遠(yuǎn)程倉(cāng)庫(kù)至本地倉(cāng)庫(kù)
ps:遠(yuǎn)程倉(cāng)庫(kù)的建立會(huì)再補(bǔ)充的 選擇一個(gè)文件目錄,然后右擊打開(kāi)git bash命令行窗口,從一個(gè)服務(wù)器上克隆一個(gè)git遠(yuǎn)程倉(cāng)庫(kù):
- git clone [url]
2、記錄每次更新到版本庫(kù)
如果是創(chuàng)建的版本庫(kù),此時(shí),工作區(qū)中還是沒(méi)有文件的,可以直接在工作區(qū)中新增并修改;如果是獲取的版本庫(kù),直接修改在工作區(qū)的內(nèi)容就好了。
改動(dòng)好之后,可執(zhí)行下述幾個(gè)命令:
檢測(cè)當(dāng)前文件狀態(tài) :
- $ git status
- On branch master
- Changes not staged for commit:
- (use "git add <file>..." to update what will be committed)
- (use "git checkout -- <file>..." to discard changes in working directory)
- modified: readme.txt
- no changes added to commit (use "git add" and/or "git commit -a")
”Changes not staged for commit“說(shuō)明該文件 readme.txt被修改了但并不在暫存區(qū)。
把更改的內(nèi)容添加到暫存區(qū):
- git add [filename](針對(duì)特定文件)
- git add *(所有文件)
- git add *.txt(支持通配符,所有 .txt 文件)
此時(shí),暫存區(qū)的內(nèi)容和工作區(qū)的內(nèi)容一致。
忽略文件:
執(zhí)行add操作時(shí),有些文件是不想要放到暫存區(qū),就可以使用下面的方法忽略掉:
- 使用命令:touch .gitignore 創(chuàng)建.gitignore文件
- 在文件中寫(xiě)入需要忽略的文件
- 例如,寫(xiě)入appName/src/test/* 表示忽略掉了appName項(xiàng)目下的test文件夾下的所有文件
提交更新:
現(xiàn)在最新的代碼在暫存區(qū),現(xiàn)在需要將其放到本地倉(cāng)庫(kù)中,采用下述的命令:
- git commit -m "代碼提交信息"
注意:每次準(zhǔn)備提交前,先用 git status 看下,是不是都已暫存起來(lái)了,然后再運(yùn)行提交命令。
跳過(guò)使用暫存區(qū)域提交更新的方式:
仔細(xì)想一想,修改的內(nèi)容在暫存區(qū)中,我們好像也沒(méi)有做過(guò)什么操作,那為什么不選擇直接提交到本地倉(cāng)庫(kù)呢?稍后解答~,先說(shuō)一下跳過(guò)使用暫存區(qū)域而提交更新的命令:
- git commit -a -m "代碼提交信息"。
git commit 加上 -a 選項(xiàng),git 就會(huì)自動(dòng)把所有已經(jīng)跟蹤過(guò)的文件暫存起來(lái)一并提交,從而跳過(guò) git add 步驟。
git暫存區(qū)存在的意義:
會(huì)有這個(gè)疑惑的,請(qǐng)先問(wèn)問(wèn)自己,使用git時(shí)候是否是所有的修改一次全部提交,根本沒(méi)有考慮到修改的多個(gè)內(nèi)容是和多個(gè)功能有關(guān)的,而每一個(gè)功能應(yīng)該單獨(dú)做成一次提交,這樣可以保證提交歷史的清晰。否則,當(dāng)你想要回滾歷史的時(shí)候,你會(huì)無(wú)所適從,根本分不清每個(gè)版本包含了哪些功能,修復(fù)了哪些bug。
而暫存區(qū)的作用就是為了可以選擇性提交,比如你在開(kāi)發(fā)B功能的時(shí)候,發(fā)現(xiàn)A功能還存在Bug,這時(shí)候就需要先修復(fù)A中的Bug,然后先提交A中的Bug修復(fù)后的內(nèi)容,然后再提交B的。這樣就可以使提交版本歷史記錄的更清晰,方便回滾。而提交是原子性操作,文件的選擇就交于暫存區(qū)去做,每一次提交都是一個(gè)完整的功能開(kāi)發(fā),保證commit的干凈,降低commit的粒度。
查看工作區(qū)和版本庫(kù)里面最新版本的區(qū)別:
- git diff HEAD -- [filename]
移除文件:
有時(shí)候需要先從暫存區(qū)移除某文件,然后提交更新本地倉(cāng)庫(kù)。移除命令如下:
- git rm [filename]
對(duì)文件重命名:
- git mv README.*** README
- (這個(gè)命令相當(dāng)于 mv README.*** README、git rm README.***、git add README 這三條命令的集合)
(這個(gè)命令相當(dāng)于 mv README.*** README、git rm README.***、git add README 這三條命令的集合)
查看提交歷史:
在提交了若干更新,又或者克隆了某個(gè)項(xiàng)目之后,也許想回顧下提交歷史。完成這個(gè)任務(wù)最簡(jiǎn)單而又有效的工具是 git log 命令。git log 會(huì)按提交時(shí)間列出所有的更新,最近的更新排在最上面。加上--pretty=oneline后輸出的信息就不會(huì)那么多。
- $ git log
- commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
- Author: Michael Liao <askxuefeng@gmail.com>
- Date: Fri May 18 21:06:15 2018 +0800
- append GPL
- commit e475afc93c209a690c39c13a46716e8fa000c366
- Author: Michael Liao <askxuefeng@gmail.com>
- Date: Fri May 18 21:03:36 2018 +0800
- add distributed
- commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
- Author: Michael Liao <askxuefeng@gmail.com>
- Date: Fri May 18 20:59:18 2018 +0800
- wrote a readme file
- $ git log --pretty=oneline
- 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
- e475afc93c209a690c39c13a46716e8fa000c366 add distributed
- eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file
版本回退:
- git reset --hard HEAD^ 回退到上一版本
- git reset --hard HEAD^^ 回退到上上版本
- git reset --hard HEAD~100 回退到前100個(gè)版本
- git reset --hard [版本號(hào)] 回退到固定版本號(hào)
- git reflog 記錄每一次的命令(可以查看版本號(hào))
推送本地的改動(dòng)到遠(yuǎn)程倉(cāng)庫(kù),使本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)一致
如果還沒(méi)有克隆現(xiàn)有倉(cāng)庫(kù),并欲將你的倉(cāng)庫(kù)連接到某個(gè)遠(yuǎn)程服務(wù)器,你可以使用如下命令添加:
- ·git remote add origin <url>
如果已經(jīng)關(guān)聯(lián)了遠(yuǎn)程倉(cāng)庫(kù),可以使用下述命令看一下遠(yuǎn)程倉(cāng)庫(kù)是哪個(gè):
- git remote -v
然后將本地的改動(dòng)提交到遠(yuǎn)程倉(cāng)庫(kù):
- git push origin [分支]
如此你就能夠?qū)⒛愕母膭?dòng)推送到所添加的服務(wù)器上去了。
分支管理
分支是用來(lái)將特性開(kāi)發(fā)絕緣開(kāi)來(lái)的。在你創(chuàng)建倉(cāng)庫(kù)的時(shí)候,master 是“默認(rèn)的”分支。在其他分支上進(jìn)行開(kāi)發(fā),完成后再將它們合并到主分支上。我們通常在開(kāi)發(fā)新功能、修復(fù)一個(gè)緊急 bug 等時(shí)候會(huì)選擇創(chuàng)建分支。單分支開(kāi)發(fā)好還是多分支開(kāi)發(fā)好,還是要看具體場(chǎng)景來(lái)說(shuō)。
一開(kāi)始的時(shí)候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當(dāng)前分支,以及當(dāng)前分支的提交點(diǎn):
每次提交,master分支都會(huì)向前移動(dòng)一步,這樣,隨著你不斷提交,master分支的線也越來(lái)越長(zhǎng)。
- 創(chuàng)建一個(gè)分支dev
- git branch dev
- git branch 后面不加分支的名字就是查看當(dāng)前的分支
- 切換當(dāng)前分支到 dev
- git checkout dev
- 創(chuàng)建并切換分支
- git checkout -b dev (兩條命令的合寫(xiě))
- 切換到主分支
- git checkout master
- 合并dev分支到master(可能會(huì)有沖突)
- git merge dev
那沖突該怎么解決呢?
首先通過(guò)git status命令查看一下沖突的文件,然后使用cat [文件名]查看該文件內(nèi)是那幾行的代碼出現(xiàn)了沖突,git是用<<<<<<<,=======,>>>>>>>標(biāo)記出不同分支的內(nèi)容,其中<<
- 把剛新建的分支刪掉
- git branch -d dev
- 將分支推送到遠(yuǎn)端倉(cāng)庫(kù)(推送成功后其他人可見(jiàn)):
- git push origin [分支名]
這里可能會(huì)存在push失敗的情況,那很可能就是因?yàn)槟愕牧硪粋€(gè)小伙伴和你修改了同一個(gè)文件的代碼并且他push完成了,而你本次push的文件與遠(yuǎn)程倉(cāng)庫(kù)中現(xiàn)有的該文件產(chǎn)生了沖突,那需要先pull一下,再push:
- git pull
- ps: 如果失敗了,根據(jù)提示,執(zhí)行 git pull --set-upstream-to=origin/<branch> <branch>
- 就是說(shuō)讓你指定本地分支和遠(yuǎn)程分支的鏈接