您好,登錄后才能下訂單哦!
? 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了。
(此種安裝的1.8,版本太老,可以學習用,生成環境建議用第二種方式):
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/a69f1d7dde72520efa39cd829ebc424d.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/07456582b5f33002e870c1b7d493006a.png)
(3)安裝成功后,運行如下命令:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/f6db1580572213aa6f925902a1dba10c.png)
新建目錄git_test,在git_test目錄下創建一個版本庫,命令:git init
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/4722f206b798e103d3025b2e141c0e7e.png)
可以看到在git_test目錄下創建了一個.git隱藏目錄,這就是版本庫目錄。
① 在版本庫中創建文件的時候,就有了文件的第一個版本,于此同時會生成一個指針指向這個版本
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/6b88e8ed7860db0b26ed20dc7f7deda8.png)
② 當修改了code.txt中的內容以后,就生成了第二個版本,但是這個版本是依賴上一個版本的,在這個版本中僅僅會記錄文件發生了那些修改。在有了一個新版本之后,這個指針會指向最新的版本。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/6df42071833e9d06ac2e29311a3137c5.png)
③ 通過修改指針的位置可以實現回退到某個版本,表示方式有兩種,一種是用^,一種使用~,如下
l HEAD^ 或者 HEAD~1:表示上一個版本
l HEAD^^ 或者 HEAD~2:表示上兩個版本
通過上面的方式回退到第一個版本之后,指針就指向了版本1
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/12f0ad0473c03b018e670f66adb80859.png)
(1) 在git_test目錄下創建一個文件code.txt,寫入一行內容如下:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/52eed22d940b2c0dd28dafdbc44b0a82.png)
(2) 使用如下兩條命令可以創建一個版本,創建版本需要兩步:
① git add code.txt
② git commit –m '版本1'
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/0b245c928d82cb17440a199fca4a106a.png)
(3) 查看版本記錄,命令是git log:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/1928a9c46af9b1e0d5fba3d223e11e6d.png)
(4) 繼續編輯code.txt,在里面增加一行。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/a8b00e15d20927d2e0f221c9f85ea374.png)
(5) 使用如下命令再創建一個版本并查看版本記錄:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/19ec9f94aa928236749a533ab7273fc1.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/59b8e34134704ae7ffad891986cdce40.png)
(6) 現在若想回到某一個版本,可以使用如下命令:
git reset --hard HEAD^
其中HEAD表示當前最新版本,HEAD^表示當前版本的前一個版本,HEAD^^表示當前版本的前前個版本,也可以使用HEAD~1表示當前版本的前一個版本,HEAD~100表示當前版本的前100版本。
現在若覺得想回到版本1,可以使用如下命令:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/622cf2c65767930b0336720086b396a4.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/bf209a7e8a84c9561660f3d2c832fc3d.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/293e0ee75ade3c7407946616e7e174e7.png)
執行命令后使用git log查看版本記錄,發現現在只能看到版本1的記錄,cat code.txt查看文件內容,現在只有一行,也就是第一個版本中code.txt的內容。
(7) 假如我們現在又想回到版本2,這個時候怎么辦?
可以使用如下命令:
git reset --hard 版本號
從上面可以看到版本2的版本號為:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/d9f54d5442caa834c55f89d961d12ef2.png)
(8) 根據查詢到的序號進行版本選擇:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/43688f6a851ed6184b10b9eb4b36ea66.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/ddc8fb3d31b0b1f58f126f93928438a4.png)
現在發現版本2有回來了。可以cat code.txt查看其里面的內容如下:
(9) 假如說上面的終端已經關了改怎么回退版本。
我們在執行如下命令將版本回退到版本1。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/adc54a2e15245ecf6ac2032952b54ee5.png)
下面把終端關了,然后再打開終端,發現之前版本2的版本號看不到了。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/2d945896a80dc6303c56dd357abfd91d.png)
那么怎么再回到版本2呢?git reflog命令可以查看我們的操作記錄。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/1856351329cd92321260f41e3d11a073.png)
可以看到版本2的版本號,我們再使用如下命令進行版本回退,版本重新回到了版本2。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/675df08acb21bd8dfe60ed15a5af6fe7.png)
電腦中的目錄,比如我們的git_test,就是一個工作區。
l 工作區有一個隱藏目錄.git,這個不是工作區,而是git的版本庫。
l git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區,還有git為我們自動創建的第一個分支master,以及指向master的一個指針叫HEAD。
l 因為我們創建git版本庫時,git自動為我們創建了唯一一個master分支,所以,現在,git commit就是往master分支上提交更改。
l 你可以簡單理解為,需要提交的文件修改通通放到暫存區,然后,一次性提交暫存區的所有修改。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/9d04da9025130069684dc44c5cf6925b.png)
前面講了我們把文件往git版本庫里添加的時候,是分兩步執行的:
第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用git commit提交更改,實際上就是把暫存區的所有內容提交到當前分支。
(1) 下面在git_test目錄下再創建一文件code2.txt,然后編輯內容如下:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/83ee9f6032ae0bb75f2f08cc9d9c315e.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/ef7e51dcf1ef925e187405bec12ff783.png)
(2) 然后再次編輯code.txt內容,在其中加入一行,編輯后內容如下:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/97dc419986fac449458333fb110a7d22.png)
(3) 使用如下命令查看當前工作樹的狀態:
git status
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/cfb1eb0f1fe49ade9363f35ce4bb992b.png)
上面提示我們code.txt被修改,而code2.txt沒有被跟蹤。
(4) 我們使用如下命令把code.txt和code2.txt加入到暫存區,然后再執行git status命令,結果如下:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/06847424b8663028ecab6fecdde05e7b.png)
所有git add命令是把所有提交的修改存放到暫存區。
(5) 然后,執行git commit就可以一次性把暫存區的所有修改提交到分支創建一個版本。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/80b3bb11d8d8644dcd211cbbfad30a0c.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/85d569a429786cce0694f26a4df4d1f1.png)
(6) 一旦提交后,如果你又沒有對工作區做任何修改,那么工作區就是“干凈”的。執行如下命令可以發現:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/1a39201a621e16067b015747128700ea.png)
git管理的文件的修改,它只會提交暫存區的修改來創建版本。
(1) 編輯code.txt,并使用git add 命令將其添加到暫存區中。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/4fa2426cd28b21364efc4b55f4aa36be.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/8424cedf040abd54acf8cca269290b8f.png)
添加到緩存區
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/57b57dfcc86e2556bd1c3f1bb474a88d.png)
再添加一行
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/f865de8037b69aff355f1603f06fab93.png)
(2) git commit創建一個版本,
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/f566cad50cca22c4a19fe3b993667c6f.png)
此時并使用git status查看,發現狀態不是clean
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/87ede3cfb11ed956cee55c026ea0ef82.png)
這是因為第二次修改code.txt內容之后,并沒有將其添加的工作區,所以創建版本的時候并沒有被提交。
(1) 繼續上面的操作,提示我們可以使用格式來撤銷操作,也就是丟棄工作區中你的修改:
git checkout -- <文件>
執行如下命令,
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/355890b389e820c43d12d5e6a440856e.png)
發現工作區干凈了,
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/19fbdc3cd4e7f4d36298f6d2fed0582b.png)
第二次的改動內容也沒了。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/b8d1df6711d8a61f8704c4da411da7e6.png)
(1) 前面所演示的是尚未添加到暫存區中的內容進行回滾,其實,即使加入到了暫存區,也是開始可以回滾的。
我們繼續編輯code.txt,并在其中添加如下內容 ![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/ba216e8d1d4fdee2a99d4381557af131.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/e66b86628c924d16fa519cec7411b916.png)
并將其添加的暫存區
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/762edae36f9b9aa5787e9933e9c02dac.png)
(3)git同樣告訴我們,用命令git reset [選項] HEAD file可以把暫存區的修改撤銷掉,重新放回工作區。
選項有三個
l --hard:緩存區和工作目錄中的內容都回滾到指定的那個版本狀態
l --mixed:默認選項,緩存區和你指定的提交同步,但是工作目錄不受影響
l --soft:緩存區和工作目錄中的內容都不變(僅僅庫中的內容回滾的指定版本)
l 使用這些選項的時候,就不能再指定具體的文件了
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/54ae8f8351550ce24176c04c92239604.png)
狀態
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/71a550c8a984f4a2128a9f64b7012a95.png)
到這里,僅僅是保存在將暫存區中的內容刪除了,接下來就可以將這個文件回滾到修改之前的狀態
(4)現在若想丟棄code.txt的修改,執行如下命令即可。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/9831f9bea646ce2be61d164e3df5b478.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/37630b24e0baa6f8d66130e4d625beee.png)
現在,如果你不但改錯了東西,還從暫存區提交到了版本庫,則需要進行版本回退。
小結:
l 場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令git checkout -- file。
l 場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了場景1,第二步按場景1操作。
l 場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節。
來演示三個選項的作用
先來演示hard選項
1 在版本庫中編輯一個文件1,并add到暫存區
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/5d530dcb7bce2f17fc4248533e299132.png)
2 編輯另一個文件(不保存到暫存區)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/2c5bbb630e4f1b577ff93f0a2ca70758.png)
3 查看狀態,一個在暫存區 一個是未追蹤狀態
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/b71db601d079d062721aef77afa375b2.png)
4 用git reset --hard xxxx 回滾到一個狀態
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/a1e85d5186146a53bd624aa9642f51d9.png)
5 再次查看狀態(此時發現是clean,什么狀態的都沒有了)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/41b06d00f52f39d5b36681a1fb4af1cd.png)
6 這兩個文件中新添加的內容都沒了
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/a370b5a15a1deabee555e293779fd538.png)
先來演示soft選項
前面部分略
1 執行 reset,回滾到第一個版本
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/fc1c65b52e38f2304d76f209c5218e70.png)
2 此時暫存區和文件中的內容都還在
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/69dc1a095d7b3d61645f6b9f38eee320.png)
3 查看當前所處的版本,已經回到了第一個版本,其他的版本都沒了
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/9c879cf18be9dfe16f3930329531f09a.png)
對比工作區和某個版本中文件的不同:
(1) 繼續編輯文件code.txt,在其中添加一行內容。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/e5f736f400318148a93ceabadc4a10fb.png)
(2) 現在要對比工作區中code.txt和上個版本中code.txt的不同。使用如下命令:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/1a5ec4f8e3e0b2d76e150bfc7fae92de.png)
我們也可以和版本庫中的第二個版本做比對
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/e0a7de42a8b74086425df0e2f1ebddd3.png)
對比兩個版本間文件的不同:
(1) 現在要對比HEAD和HEAD^版本中code.txt的不同,使用如下命令:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/3ed628ef52b772b3e19fef0b79259c63.png)
(1) 我們把目錄中的code2.txt刪除。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/6ad4029784e757af1f86d3196beaec1b.png)
這個時候,git知道刪除了文件,因此,工作區和版本庫就不一致了,git status命令會立刻提示哪些文件被刪除了。
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/f4bd59749d6c6686506a782cfbfef7b6.png)
(2) 現在你有兩個選擇,一是確實要從版本庫中刪除該文件,那就用命令git rm刪掉,并且git commit:
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/50be31433c697f5f0b37eca1a304442c.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/11ebc5ed25d427c4c956f2bc92b2aa83.png)
![img](file:///C:/Users/sy/Documents/My Knowledge/temp/fc8918e9-6218-4de1-ae60-6e01447f1ea3/128/index_files/10747f8023cf258fd8bd1b157e2fc920.png)
另一種情況是刪錯了,可以直接使用git checkout – code2.txt,這樣文件code2.txt又回來了。
小結:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。