因?yàn)槭褂肎ithub,OSChina管理自己項(xiàng)目的時(shí)候,使用git終端命令不是特熟悉,所以特地特地把公司之前買(mǎi)的Git 版本控制管理(第二版)給看了一遍,再結(jié)合自己實(shí)際操作,對(duì)Git的使用和理解還是提升的不少;所以就寫(xiě)一篇博文來(lái)記錄自己的學(xué)習(xí)Git之旅,有誤之處歡迎大家指正。
- Git的簡(jiǎn)單介紹
- Git和SVN的對(duì)比
- Git使用的快速入門(mén)
- Github、OSchina的使用
對(duì)于前兩部分的內(nèi)容,大家可以初略看下,有個(gè)印象知道一些名詞概念就好,重點(diǎn)還是得多練習(xí)、多操作,也就是第三部分內(nèi)容需要實(shí)際操作;
Git的簡(jiǎn)單介紹
1. Git是什么?
Git是一款免費(fèi)、開(kāi)源的分布式版本控制系統(tǒng);
是由Linux之父Linus開(kāi)發(fā),開(kāi)發(fā)緣由自己可以上網(wǎng)查看下或者下載我在百度云盤(pán)分享的Git權(quán)威指南,Linus確實(shí)很牛逼,不得不佩服人家,花了一個(gè)月的時(shí)間就開(kāi)發(fā)成功了!
與Git對(duì)應(yīng)的集中式版本控制有CVS、SVN(集中式版本庫(kù)控制的集大成者)。
2. Git讀音:
有必要先說(shuō)一下Git的讀音,音標(biāo):[g?t],字母G的發(fā)音與Gives、Gift的發(fā)音一樣,所以發(fā)音聽(tīng)起來(lái)像是“歌易特”;我之前的讀法和聽(tīng)到很多人的讀法一直都是錯(cuò)誤的:“計(jì)易特”;
3. Git 工作原理
有必要介紹下幾個(gè)名詞:
工作區(qū)(Working Directory):倉(cāng)庫(kù)文件夾里除.git目錄以外的目錄;
版本庫(kù)(Repository):位于工作區(qū)根目錄下.git目錄中,用于存儲(chǔ)記錄版本信息,.git是一個(gè)隱藏文件夾,在終端中輸入這條命令defaults write com.apple.finder AppleShowAllFiles -bool true就可以顯示隱藏文件(隱藏Mac隱藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool false);
- 暫緩區(qū)(stage)
- 分支(master):git自動(dòng)創(chuàng)建的第一個(gè)分支
- HEAD指針:用于指向當(dāng)前分支

4. Git的工作流程

Git和SVN的對(duì)比
1. 集中式版本控制和分布式版本控制的對(duì)比
從下面兩個(gè)圖可以看出這二者之間的區(qū)別:
- 分布式下開(kāi)發(fā)者可以本地提交代碼,集中式必須聯(lián)網(wǎng)才能提交;
-
分布式下開(kāi)發(fā)者的電腦就是一個(gè)完整的版本庫(kù),擁有本地的代碼倉(cāng)庫(kù)。
集中式版本控制.png
分布式版本控制.png
2. Git和SVN的對(duì)比
1、 速度:Git比SVN快;
2、結(jié)構(gòu):Git是分布式管理,SVN是集中式管理;
3、其他:Git支持本地版本控制工作,SVN必須聯(lián)網(wǎng)才能;Git擁有更強(qiáng)大的分支管理;Git只會(huì)在根目錄擁有一個(gè).git,舊版本的svn會(huì)在的每個(gè)目錄放一個(gè).svn等等。
Git使用的快速入門(mén)
-
使用
git init創(chuàng)建初始版本庫(kù);
gitinit.png
打開(kāi)GitDemo文件夾可以看到新增了個(gè).git隱藏文件夾,所有的版本數(shù)據(jù)庫(kù)數(shù)據(jù)都將存放在.git的隱藏子目錄中;
git文件.png -
使用
git clone [remoteURL]從遠(yuǎn)程服務(wù)器克隆一份代碼到本機(jī);
在公司中,經(jīng)常是團(tuán)隊(duì)開(kāi)發(fā),先從服務(wù)器把項(xiàng)目給clone到自己電腦
C27D1E0B-539F-4417-9D5C-45B8822DDE48.png -
使用
git add [xxx]將文件添加到暫緩區(qū)
我們都知道Mac 電腦的Xcode已經(jīng)完美的集成了Git,如下圖,當(dāng)我在GitDemo中新建一個(gè)項(xiàng)目是勾選框?qū)榛疑?br>step2.png
如圖:此時(shí)項(xiàng)目的文件有個(gè)狀態(tài)為A、M和“?”(剛開(kāi)始可能全是“?”當(dāng)重新打開(kāi)后就變?yōu)橄聢D的狀態(tài)了)
DC031738-AD7E-41A0-A56C-1CBB649710AE.png
此時(shí)用在終端中輸入命令git status查看你的文件在工作目錄與緩存的狀態(tài)
3C4B6864-7F8A-4B2D-A622-603C5E71C91D.png
上圖顯示的紅色字體表示:新添加的文件或者修改的文件在工作區(qū)沒(méi)有添加到暫緩區(qū)如果此時(shí)用git add .命令將會(huì)把工作區(qū)的所有文件添加到暫緩區(qū)中; -
使用
git commit把暫緩區(qū)的所有內(nèi)容提交到當(dāng)前分支(master分支)
使用終端輸入git status查看,都變?yōu)榫G色了,這就表示工作區(qū)的代碼已經(jīng)添加到暫緩區(qū)中,可以提交到本地代碼倉(cāng)庫(kù)了
81AD2BAB-1E28-4F56-BD06-383A4FA00172.png
終端輸入命令git commit -m"初始化版本倉(cāng)庫(kù)",Xcode項(xiàng)目的各個(gè)文件右邊的A和M都消失了,說(shuō)明納入版本控制成功 添加.gitignore文件(.git 同一級(jí)目錄下)
我之前分享的使用oschina托管自己項(xiàng)目第三大點(diǎn)有說(shuō)過(guò)在GitHub下載gitignore文件,因?yàn)槲业捻?xiàng)目是Objective-C語(yǔ)言編寫(xiě)的所以我要添加的是Objective-C.gitignore,在終端中如下命令:
cp /Users/xcq/Downloads/gitignore-master/Objective-C.gitignore .gitignore
git add .gitignore
git commit -m"添加gitignore文件"
可以看到當(dāng)前目錄多了一個(gè).gitignore

添加.gitignore文件步驟很重要、很重要、很重要,重要的事情說(shuō)三遍;添加.gitignore文件的步驟操作最好在git init步驟之后,也就是創(chuàng)建初始版本庫(kù)之后就在工做根目錄(也就是與.git同一層及目錄)下添加.gitignore文件,然后再用Xcode新建一個(gè)項(xiàng)目,這樣做才會(huì)真正的把所有不需要納入版本控制的文件忽略;我之前的操作正好相反,是先新建了一個(gè)CQActionView的項(xiàng)目,然后才添加的.gitignore文件,這樣做的后果是UserInterfaceState.xcuserstate并沒(méi)有忽略,每一次command + 編譯都會(huì)產(chǎn)生

用Xcode自帶Git的Commit也能看到,項(xiàng)目沒(méi)有做任何修改,但是一編譯就會(huì)有一些用戶緩存數(shù)據(jù)

還有種情況是我們已經(jīng)寫(xiě)好的項(xiàng)目需要用Git管理,然后才添加的.gitignore文件,這也會(huì)出現(xiàn)上述問(wèn)題,
解決方案如下:(其中:CQActionView/CQActionView.xcodeproj/project.xcworkspace/xcuserdata/xcq.xcuserdatad/UserInterfaceState.xcuserstate 是上面第二張圖紅色的那個(gè)路徑,直接copy過(guò)來(lái)就行;
git rm --cached [xxx]會(huì)將文件從緩存區(qū)刪除,但是工作目錄中還存有該文件 )
git rm --cached CQActionView/CQActionView.xcodeproj/project.xcworkspace/xcuserdata/xcq.xcuserdatad/UserInterfaceState.xcuserstate
git commit -m"Removed file that shouldn't be tracked"
-
使用
git branch [xxx]創(chuàng)建分支,git branch查看在本地的分支,git branch -va可以查看本地+遠(yuǎn)程分支列表
FB743F3E-EBAD-4D6B-BE53-96EB6F16C683.png
如圖,我們新建了一個(gè)“branch1”分支。如果你在master分支做了變更并且更新提交, 然后切換到了“ branch1”分支,Git 將還原你的工作目錄到你創(chuàng)建分支時(shí)候的樣子; -
工作實(shí)例:如下圖,公司的遠(yuǎn)程倉(cāng)庫(kù)有有兩個(gè)分支:master和feature_react_native。
branch.png
老大要求我在feature_react_native分支上進(jìn)行功能開(kāi)發(fā),但是我clone到本地的代碼對(duì)應(yīng)的是遠(yuǎn)程的master分支,此時(shí)我就需要修改這種映射關(guān)系。如下圖,通過(guò)git branch -vv查看本地分支和遠(yuǎn)程分支的跟蹤關(guān)聯(lián)關(guān)系:為本地的master和react_native分支都是對(duì)應(yīng)遠(yuǎn)程的origin/master分支,這是導(dǎo)致的結(jié)果是,你完成修改代碼然后push到的是遠(yuǎn)程的master分支,這是不符合要求的,
branch2.png
通過(guò)git branch --set-upstream react_native origin/feature_react_native讓本地分支react_native與遠(yuǎn)程分支origin/feature_react_native關(guān)聯(lián),這樣你以后提交的代碼就不會(huì)提交到遠(yuǎn)程master分支了
branch3.png -
使用
git checkout [xxx]切換分支,Git 會(huì)用該分支的最后提交的快照替換你的工作目錄的內(nèi)容, 所以多個(gè)分支不需要多個(gè)目錄
EB7E27E4-04A7-44D2-9FFF-A8D5377690AE.png
如圖,我在master分支,修改了ViewController.m文件并且提交,當(dāng)我們切換到“branch1”分支的時(shí)候,ViewController.m又重新回到修改前的模樣 -
使用
git checkout -b [branchname]創(chuàng)建新的分支,并立即切換到它,也就是6和7步可以合并到這一步;git checkout -b develop master基于主分支創(chuàng)建develop分支;
B9049A64-0179-47F6-975C-F3F34E0719C1.png
與此同時(shí)你打開(kāi)Xcode的Sourse Control也可以看到有三個(gè)分支:
sourse Control.png
sourse Control2.png -
git branch -d [branchname]刪除本地分支,git push origin --delete [branchname]刪除遠(yuǎn)程分支
F820C15A-32EF-42C3-841D-85E28E1AFB42.png 使用
git merge [branchname]來(lái)合并分支
我在“ branch1”分支中編寫(xiě)了一段代碼,完成了一段功能,并且想合并到master分支中,此時(shí)我需要先切換到master分支中,然后執(zhí)行git merge branch1新建的本地倉(cāng)庫(kù)與遠(yuǎn)程倉(cāng)庫(kù)進(jìn)行關(guān)聯(lián),在本地倉(cāng)庫(kù).git文件目錄下執(zhí)行
git remote add origin [remoteURL],origin是遠(yuǎn)程倉(cāng)庫(kù)的名字。然后本地倉(cāng)庫(kù)的內(nèi)容推送到遠(yuǎn)程倉(cāng)庫(kù)git push -u origin master;如果失敗則執(zhí)行git pull origin master [--allow-unrelated-histories],如果提示失敗信息:fatal: refusing to merge unrelated histories,則上面中括號(hào)的參數(shù)需要添加。
以下是一些其他Git命令,我就沒(méi)做例子,大家可以操作練習(xí)
給git起個(gè)別名
git config alias.[別名] “status”查看歷史版本
git log
50163165822d3141742f4d4aece0e5c222ef156e
git reflog // 查看分支引用記錄
git 版本號(hào)是有SHA1機(jī)密算法生成的一個(gè)40位的哈希值版本回退
# 回到當(dāng)前版本,放棄所有沒(méi)有提交的修改
git reset --hard HEAD
# 回到上一個(gè)版本
git reset --hard HEAD^
# 回到之前第10個(gè)修訂版本
git reset --hard HEAD~10
# 回到指定版本號(hào)的版本
$ git reset --hard [版本號(hào)前七位]
- 添加標(biāo)簽(又叫添加里程碑)
git tag -a v1.0 -m 'version 1.0',其中v1.0代表tagname,version 1.0代表標(biāo)簽的說(shuō)明信息;
git push origin v1.3:v1.3,將標(biāo)簽推送到遠(yuǎn)程倉(cāng)庫(kù),v1.3:v1.3代表將本地v1.3推送到遠(yuǎn)程倉(cāng)庫(kù)的v1.3;
git tag查看本地的標(biāo)簽;
git tag -d 1.0刪除本地的標(biāo)簽,1.0代表標(biāo)簽的版本;
git push origin :v1.2刪除遠(yuǎn)程的標(biāo)簽,這種情況發(fā)生在推送到遠(yuǎn)程的標(biāo)簽版本有錯(cuò)誤,為了防止其他人獲取到錯(cuò)誤的標(biāo)簽,應(yīng)該盡快的刪除標(biāo)簽。
掌握以上的git內(nèi)容,就能勝任平時(shí)90%開(kāi)發(fā)的任務(wù)。最后,關(guān)于Git 分支的練習(xí),我這有個(gè)好的練習(xí)網(wǎng)址:Learn Git Branching ,也是一個(gè)同事分享給我的,他的Git命令使用的溜溜的;很不錯(cuò)的一個(gè)練習(xí)Git分支操作的網(wǎng)址,大家點(diǎn)擊進(jìn)去之后可能什么內(nèi)容都沒(méi)有,不要急,稍等片刻就會(huì)出來(lái)。

Github、OSchina的使用
從Github上clone代碼,push,pull的操作大家可以下載GitHub Desktop 圖形化界面進(jìn)行操作,
OSchina就可以使用Xcode集成的Git,大家可以添加遠(yuǎn)程倉(cāng)庫(kù)地址,在Preferences(common + ,)--》Account -->左下角有個(gè)加號(hào)--》Add Repository;然后就可以提交到遠(yuǎn)程中了。
終于寫(xiě)完了,不容易啊,太困了,最后的內(nèi)容寫(xiě)的有點(diǎn)粗糙啊,見(jiàn)諒。。。??????

















