您好,登錄后才能下訂單哦!
Git 的誕生
很多人都知道, Linus 在 1991 年創建了開源的 Linux,從此, Linux 系統不斷發展,已經成為最大的服務器系統軟件了。Linus雖然創建了Linux,但Linux的壯大是靠全世界熱心的志愿者參與的,這么多人在世界各地為Linux編寫代碼,那 Linux 的代碼是如何管理的呢?
事實是,在 2002 年以前,世界各地的志愿者把源代碼文件通過 diff 的方式發給 Linus,然后由 Linus本人通過手工方式合并代碼!
你也許會想,為什么 Linus 不把 Linux 代碼放到版本控制系統里呢?不是有 CVS、 SVN 這些免費的版本控制系統嗎?因為 Linus 堅定地反對 CVS 和 SVN,這些集中式的版本控制系統不但速度慢,而且必須聯網才能使用。有一些商用的版本控制系統,雖然比 CVS、 SVN 好用,但那是付費的,和 Linux 的開源精神不符。
不過,到了 2002 年, Linux 系統已經發展了十年了,代碼庫之大讓 Linus 很難繼續通過手工方式管理了,社區的弟兄們也對這種方式表達了強烈不滿,于是 Linus 選擇了一個商業的版本控制系統 BitKeeper,
BitKeeper 的東家 BitMover 公司出于人道主義精神,授權 Linux 社區免費使用這個版本控制系統。安定團結的大好局面在 2005 年就被打破了,原因是 Linux 社區牛人聚集,不免沾染了一些梁山好漢的江湖習氣。開發 Samba 的 Andrew 試圖破解 BitKeeper 的協議(這么干的其實也不只他一個),被BitMover 公司發現了(監控工作做得不錯!),于是 BitMover 公司怒了,要收回 Linux 社區的免費使
用權。
Linus 可以向 BitMover 公司道個歉,保證以后嚴格管教弟兄們,嗯,這是不可能的。實際情況是這樣的:Linus 花了兩周時間自己用 C 寫了一個分布式版本控制系統,這就是 Git!一個月之內, Linux 系統的
源碼已經由 Git 管理了!牛是怎么定義的呢?大家可以體會一下。Git 迅速成為最流行的分布式版本控制系統,尤其是 2008 年, GitHub 網站上線了,它為開源項目免費提供 Git 存儲,無數開源項目開始遷移至 GitHub,包括 jQuery, PHP, Ruby 等等。
歷史就是這么偶然,如果不是當年 BitMover 公司威脅 Linux 社區,可能現在我們就沒有免費而超級好用的 Git 了。
集中式 vs 分布式
Linus 一直痛恨的 CVS 及 SVN 都是集中式的版本控制系統,而 Git 是分布式版本控制系統,集中式和分布式版本控制系統有什么區別呢?
先說集中式版本控制系統,版本庫是集中存放在中央服務器的,而干活的時候,用的都是自己的電腦,所以要先從中央服務器取得最新的版本,然后開始干活,干完活了,再把自己的活推送給中央服務器。中央服務器就好比是一個圖書館,你要改一本書,必須先從圖書館借出來,然后回到家自己改,改完了,再放回圖書館
集中式版本控制系統最大的毛病就是必須聯網才能工作,如果在局域網內還好,帶寬夠大,速度夠快,可如果在互聯網上,遇到網速慢的話,可能提交一個 10M 的文件就需要 5 分鐘,這還不得把人給憋死啊。
那分布式版本控制系統與集中式版本控制系統有何不同呢?首先,分布式版本控制系統根本沒有“中央服務器”,每個人的電腦上都是一個完整的版本庫,這樣,你工作的時候,就不需要聯網了,因為版本庫就在你自己的電腦上。既然每個人電腦上都有一個完整的版本庫,那多個人如何協作呢?比方說你在自己電腦上改了文件 A,你的同事也在他的電腦上改了文件 A,這時,你們倆之間只需把各自的修改推送給對方,就可以互相看到對方的修改了。和集中式版本控制系統相比,分布式版本控制系統的安全性要高很多,因為每個人電腦里都有完整的版本庫,某一個人的電腦壞掉了不要緊,隨便從其他人那里復制一個就可以了。而集中式版本控制系統的中央服務器要是出了問題,所有人都沒法干活了。
在實際使用分布式版本控制系統的時候,其實很少在兩人之間的電腦上推送版本庫的修改,因為可能你們倆不在一個局域網內,兩臺電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。因此,分布式版本控制系統通常也有一臺充當“中央服務器”的電腦,但這個務器的作用僅僅是用來方便“交換”大家的修改, 沒有它大家也一樣干活,只是交換修改不方便而已。
當然, Git 的優勢不單是不必聯網這么簡單,后面我們還會看到 Git 極其強大的分支管理,把 SVN 等
遠遠拋在了后面。
CVS 作為最早的開源而且免費的集中式版本控制系統,直到現在還有不少人在用。由于 CVS 自身設
計的問題,會造成提交文件不完整,版本庫莫名其妙損壞的情況。同樣是開源而且免費的 SVN 修正了
CVS 的一些穩定性問題,是目前用得最多的集中式版本庫控制系統。
除了免費的外,還有收費的集中式版本控制系統,比如 IBM 的 ClearCase(以前是 Rational 公司的,
被 IBM 收購了),特點是安裝比 Windows 還大,運行比蝸牛還慢,能用 ClearCase 的一般是世界 500
強,他們有個共同的特點是財大氣粗,或者人傻錢多。
微軟自己也有一個集中式版本控制系統叫 VSS,集成在 Visual Studio 中。由于其反人類的設計,連微
軟自己都不好意思用了。
分布式版本控制系統除了 Git 以及促使 Git 誕生的 BitKeeper 外,還有類似 Git 的 Mercurial 和 Bazaar
等。這些分布式版本控制系統各有特點,但最快、最簡單也最流行的依然是 Git!
最早 Git 是在 Linux 上開發的,很長一段時間內, Git 也只能在 Linux 和 Unix 系統上跑。不過,慢慢地有人把它移植
到了 Windows 上。現在, Git 可以在 Linux、 Unix、 Mac 和 Windows 這幾大平臺上正常運行了。
在 Linux 上安裝 Git
yum -y install git
20 mkdir /xgp 創建所需目錄
21 git init git初始化
創建用戶名郵箱
26 git config --global user.name "admin"
27 git config --global user.email "admin@admin"
把文件添加到版本庫
現在我們編寫三個xgp.txt 文件,內容如下
23 vim xgp1.txt #xgp1
24 vim xgp2.txt #xgp2
25 vim xgp3.txt #xgp3
第一步,用命令 git add 告訴 Git,把文件添加到倉庫:
28 git add xgp1.txt xgp2.txt xgp3.txt
第二步,用命令 git commit 告訴 Git,把文件提交到倉庫:
29 git commit -m "第一次提交"
查看提交信息
52 cd ./git
53 ls -a
57 cat logs/refs/heads/master
58 cat HEAD
小結
現在總結一下今天學的兩點內容:
初始化一個 Git 倉庫,使用 git init 命令。
添加文件到 Git 倉庫,分兩步:
? 第一步,使用命令 git add <file>,注意,可反復多次使用,添加多個文件;
? 第二步,使用命令 git commit,完成。
我們已經成功地添加并提交了一個 readme.txt 文件,現在,是時候繼續工作了,于是,我們繼續修改 xgp.txt 文件,改成如下內容:
xgp1
回退測試
現在,運行 git status 命令看看結果:
git status 命令可以讓我們時刻掌握倉庫當前的狀態,上面的命令告訴我們, readme.txt 被修改過了,但還沒有準備提交的修改
雖然 Git 告訴我們 xgp1.txt 被修改了,但如果能看看具體修改了什么內容,自然是很好的。比如你休假兩周從國外回來,第一天上班時,已經記不清上次怎么修改的 readme.txt,所以,需要用 git diff 這個命令看看:
git diff 顧名思義就是查看 difference,顯示的格式正是 Unix 通用的 diff 格式,可以從上面的命令輸出看到,我們第一行添加了一個”回退測試”
知道了對 readme.txt 作了什么修改后,再把它提交到倉庫就放心多了,提交修改和提交新文件是一樣的兩步,第一步是 git add:
git add xgp1.txt
同樣沒有任何輸出。在執行第二步 git commit 之前,我們再運行 git status 看看當前倉庫的狀態:
git status 告訴我們,將要被提交的修改包括 xgp.txt,下一步,就可以放心地提交了:
git commit -m "第二次提交"
提交后,我們再用 git status 命令看看倉庫的當前狀態:
小結
要隨時掌握工作區的狀態,使用 git status 命令。
如果 git status 告訴你有文件被修改過,用 git diff 可以查看修改內容。
為什么說 Git 管理的是修改,而不是文件呢?我們還是做實驗。第一步,對 xgp1.txt 做一個修改,比如加一行內容:
[root@localhost xgp]# cat xgp1.txt
xgp1
回退測試
xgp666
xgpniubi
然后,添加:
93 git add xgp1.txt
94 git status
然后,再修改 readme.txt:
[root@localhost xgp]# cat xgp1.txt
xgp1
回退測試
xgp666
xgpniubi
1
提交:
[root@localhost xgp]# git commit -m "第四次提交"
[master 31cb090] 第四次提交
1 file changed, 1 insertion(+)
提交后,再看看狀態:
咦,怎么第二次的修改沒有被提交?
別激動,我們回顧一下操作過程:
第一次修改 -> git add -> 第二次修改 -> git commit
你看,我們前面講了, Git 管理的是修改,當你用 git add 命令后,在工作區的第一次修改被放入暫存區, 準備提交,
但是,在工作區的第二次修改并沒有放入暫存區,所以, git commit 只負責把暫存區的修改提交了,也就是第一次的
修改被提交了,第二次的修改不會被提交。
提交后,用 git diff HEAD -- readme.txt 命令可以查看工作區和版本庫里面最新版本的區別:
可見,第二次修改確實沒有被提交。
那怎么提交第二次修改呢?你可以繼續 git add 再 git commit,也可以別著急提交第一次修改,先 git add 第二次修
改,再 git commit,就相當于把兩次修改合并后一塊提交了:
第一次修改 -> git add -> 第二次修改 -> git add -> git commit
好,現在,把第二次修改提交了,然后開始小結。
小結
現在,你又理解了 Git 是如何跟蹤修改的,每次修改,如果不 add 到暫存區,那就不會加入到 commit 中。
自然,你是不會犯錯的。不過現在是凌晨兩點,你正在趕一份工作報告,你在 readme.txt 中添加了一行:
[root@localhost xgp]# cat xgp1.txt
xgp1
回退測試
xgp666
xgpniubi
1
22222
在你準備提交前,一杯咖啡起了作用,你猛然發現了“stupid boss”可能會讓你丟掉這個月的獎金!既然錯誤發現得很及時,就可以很容易地糾正它。你可以刪掉最后一行,手動把文件恢復到上一個版本的狀態。如果
用 git status 查看一下:
你可以發現, Git 會告訴你, git checkout -- file 可以丟棄工作區的修改:
git checkout -- xgp1.txt
[root@localhost xgp]# cat xgp1.txt
xgp1
回退測試
xgp666
xgpniubi
1
慶幸的是,在 commit 之前,你發現了這個問題。用 git status 查看一下,修改只是添加到了暫存區,還沒有提交:
Git 同樣告訴我們,用命令 git reset HEAD file 可以把暫存區的修改撤銷掉(unstage),重新放回工作區:
[root@localhost xgp]# git reset HEAD xgp1.txt
重置后撤出暫存區的變更:
M xgp1.txt
git reset 命令既可以回退版本,也可以把暫存區的修改回退到工作區。當我們用 HEAD 時,表示最新的版本。
再用 git status 查看一下,現在暫存區是干凈的,工作區有修改:
還記得如何丟棄工作區的修改嗎?
整個世界終于清靜了!
現在,假設你不但改錯了東西,還從暫存區提交到了版本庫,怎么辦呢?還記得版本回退一節嗎? 可以回退到上一個版本。不過,這是有條件的,就是你還沒有把自己的本地版本庫推送到遠程。還記得 Git 是分布式版本控制系統嗎?我們后面會講到遠程版本庫,一旦你把“stupid boss”提交推送到遠程版本庫,你就真的慘了……
小結
又到了小結時間。
場景 1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令 git checkout -- file。
場景 2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令 git reset
HEAD file,就回到了場景 1, 第二步按場景 1 操作。
場景 3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠程
庫。
在 Git 中,刪除也是一個修改操作,我們實戰一下,先添加一個新文件 test.txt 到 Git 并且提交:
[root@localhost xgp]# vim test.txt
[root@localhost xgp]# cat test.txt
qqqqqqqqqqqq
[root@localhost xgp]# git add test.txt
[root@localhost xgp]# git commit -m "第一次"
[master f9688d7] 第一次
1 file changed, 1 insertion(+)
create mode 100644 test.txt
一般情況下,你通常直接在文件管理器中把沒用的文件刪了,或者用 rm 命令刪了:
這個時候, Git 知道你刪除了文件,因此,工作區和版本庫就不一致了, git status 命令會立刻告訴你哪些文件被刪除了:
現在你有兩個選擇,一是確實要從版本庫中刪除該文件,那就用命令 git rm 刪掉,并且 git commit:
現在,文件就從版本庫中被刪除了。
另一種情況是刪錯了,因為版本庫里還有呢,所以可以很輕松地把誤刪的文件恢復到最新版本:
$ git checkout -- test.txt
git checkout 其實是用版本庫里的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”。
小結
命令 git rm 用于刪除一個文件。如果一個文件已經被提交到版本庫,那么你永遠不用擔心誤刪,但是要小心,你只
能恢復文件到最新版本,你會丟失最近一次提交后你修改的內容。
第1步:創建SSH Key。在用戶主目錄下,看看有沒有.ssh目錄,如果有,再看看這個目錄下有沒有 id_rsa 和 id_rsa.pub 這兩個文件, 如果已經有了,可直接跳到下一步。如果沒有,打開 Shell (Windows 下打開 Git Bash),創建 SSH Key:
ssh-keygen -t rsa -C 2877364346@qq.com
你需要把郵件地址換成你自己的郵件地址,然后一路回車,使用默認值即可,由于這個 Key 也不是用于軍事目的,
所以也無需設置密碼。
如果一切順利的話,可以在用戶主目錄里找到.ssh 目錄,里面有 id_rsa 和 id_rsa.pub 兩個文件,這兩個就是 SSH Key
的秘鑰對, id_rsa 是私鑰,不能泄露出去, id_rsa.pub 是公鑰,可以放心地告訴任何人。
第 2 步:登陸 GitHub,打開“Account settings”, “SSH Keys”頁面:
然后,點“Add SSH Key”,填上任意 Title,在 Key 文本框里粘貼 id_rsa.pub 文件的內容:
為什么 GitHub 需要 SSH Key 呢?因為 GitHub 需要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git 支持 SSH 協議,所以, GitHub 只要知道了你的公鑰,就可以確認只有你自己才能推送。
從遠程庫克隆
現在的情景是,你已經在本地創建了一個 Git 倉庫后,又想在 GitHub 創建一個 Git 倉庫,并且讓這兩個倉庫進行遠程同步,這樣, GitHub 上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作,真是一舉多得。
首先,登陸 GitHub,然后,在右上角找到“Create a new repo”按鈕,創建一個新的倉庫
目前,在 GitHub 上的這個 learngit 倉庫還是空的, GitHub 告訴我們,可以從這個倉庫克隆出新的倉庫,也可以把一個已有的本地倉庫與之關聯,然后,把本地倉庫的內容推送到 GitHub 倉庫。
現在,遠程庫已經準備好了,下一步是用命令 git clone 克隆一個本地庫:
git clone git@github.com:xgp666/xgp.git
注意把 Git 庫的地址換成你自己的,然后進入 gitskills 目錄看看,已經有 README.md 文件了。
如果有多個人協作開發,那么每個人各自從遠程克隆一份就可以了。
你也許還注意到, GitHub 給出的地址不止一個,還可以用 https://github.com/michaelliao/gitskills.git 這樣的地
址。實際上, Git 支持多種協議,默認的 git://使用 ssh,但也可以使用 https 等其他協議。
使用 https 除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令,但是在某些只開放 http 端口的公司內
部就無法使用 ssh 協議而只能用 https。
測試:在遠程庫創建一個文件
[root@localhost xgp]# vim index.html
[root@localhost xgp]# cat index.html
Qqqqq
[root@localhost xgp]# git add index.html
[root@localhost xgp]# git commit -m "123"
[master 65e2ec7] 123
1 file changed, 1 insertion(+)
create mode 100644 index.html
[root@localhost xgp]# git push origin master (默認是master)
瀏覽器查看
小結
要克隆一個倉庫,首先必須知道倉庫的地址,然后使用 git clone 命令克隆。
Git 支持多種協議,包括 https,但通過 ssh 支持的原生 git 協議速度最快。
現在的情景是,你已經在本地創建了一個 Git 倉庫后,又想在 GitHub 創建一個 Git 倉庫,并且讓這兩個倉庫進行遠
程同步,這樣, GitHub 上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作,真是一舉多得。
目前,在 GitHub 上的這個 learngit 倉庫還是空的, GitHub 告訴我們,可以從這個倉庫克隆出新的倉庫,也可以把一個已有的本地倉庫與之關聯,然后,把本地倉庫的內容推送到 GitHub 倉庫。
現在,我們根據 GitHub 的提示,在本地的 learngit 倉庫下運行命令:
git remote add origin git@github.com:xgp666/xgp.git
下一步,就可以把本地庫的所有內容推送到遠程庫上:
1.git branch --set-upstream-to=origin/master master
2.git fetch
3.再次執行git branch --set-upstream-to=origin/master master
4.git push origin master
5.git pull
6.
[root@localhost xhp]# vim aa.txt
[root@localhost xhp]# git add *
[root@localhost xhp]# git commit -m "4"
[master 2f77003] 4
[root@localhost xhp]# git status
! 位于分支 master
! 您的分支領先 'origin/master' 共 3 個提交。
! (使用 "git push" 來發布您的本地提交)
!
無文件要提交,干凈的工作區
7.git push origin master
瀏覽器查看
從現在起,只要本地作了提交,就可以通過命令:
$ git push origin master
把本地 master 分支的最新修改推送至 GitHub,現在,你就擁有了真正的分布式版本庫!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。