Git爲什麼物?
Git 是什麼?你們確定會說不就是版本控制器嘛,是的Git是目前世界上最早進的分佈式版本控制系統(沒有之一)。
1)那什麼是版本控制器?
舉個簡單的例子,好比咱們用Word寫文章,那你必定有這樣的經歷:好比增長一個段落你得複製一份,你刪除一個段落你又得複製一份,防止下次又要修改保留上次你要刪除的段落。最後一個接一個的版本,你複製了不少版本,最後可能你本身都不知道修改了哪些?嘿嘿,而後你只能一個一個的找,太麻煩了,如果有東西幫你管理那應該多好。
2)分佈式管理
你寫的文章或書,你確定會給你朋友或者其餘人看,讓他們給你建議並作相應的修改,而後他們用郵件或U盤再發給你,你再合併修改一下,真是麻煩,因而你想,若是有一個軟件,不但能自動幫我記錄每次文件的改動,還可讓朋友之間協做編輯,這樣就不用本身管理一堆相似的文件了,也不須要把文件傳來傳去。若是想查看某次改動,只須要在軟件看一眼就能夠,豈不是很方便?這個軟件用起來就應該像這個樣子,能記錄每次文件的改動:node
版本 | 用戶 | 說明 | 修改日期 |
1 | user1 | 增長一行內容 | 2014/4/10 10:22 |
2 | user2 | 修改一行內容 | 2014/4/10 13:12 |
3 | user3 | 刪除幾個字 | 2014/4/15 20:42 |
4 | user2 | 增長某個內容 | 2014/4/20 16:32 |
Git 的誕生
簡單說:Linus開發Linux內核,須要版本控制器,因而開發了Git。下面是開發週期:
1)2005/4/3 開發;
2)2005/4/6 發佈;
3)2005/4/7 管理自身;
4)2005/6/16 管理Kernel2.6.12。
大牛是怎麼定義的呢?你們能夠體會一下。哈哈^_^…… Git 迅速成爲最流行的分佈式版本控制系統,尤爲是2008年,GitHub網站上線了,它爲開源項目免費提供Git存儲,無數開源項目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。至於Git與GitHub的關係,會再下面的文章裏說明。git
集中管理 VS 分佈式管理
Linus一直痛恨的CVS及SVN都是集中式的版本控制系統,而Git是分佈式版本控制系統,集中式和分佈式版本控制系統有什麼區別呢? 下面咱們來看看兩張圖:
1)集中管理程序員
集中式版本控制系統,版本庫是集中存放在中央服務器的,而幹活的時候,用的都是本身的電腦,因此要先從中央服務器取得最新的版本,而後開始幹活,幹完活了,再把本身的活推送給中央服務器。中央服務器就比如是一個圖書館,你要改一本書,必須先從圖書館借出來,而後回到家本身改,改完了,再放回圖書館。github
缺點:
集中式版本控制系統最大的毛病就是必須聯網才能工做,若是在局域網內還好,帶寬夠大,速度夠快,可若是在互聯網上,遇到網速慢的話,可能提交一個10M~20M的文件就須要10分鐘甚至更多時間,這還不得把人給急死啊。後端
2)分佈式管理centos
那分佈式版本控制系統與集中式版本控制系統有何不一樣呢?首先,分佈式版本控制系統沒有「中央服務器」,每一個人的電腦上都是一個完整的版本庫,這樣,你工做的時候,就不須要聯網了,由於版本庫就在你本身的電腦上。既然每一個人電腦上都有一個完整的版本庫,那多我的如何協做呢?比方說你在本身電腦上改了文件fiel,你的同事也在他的電腦上改了文件file,這時,大家倆之間只需把各自的修改推送給對方,就能夠互相看到對方的修改了。數組
和集中式版本控制系統相比,分佈式版本控制系統的安全性要高不少,由於每一個人電腦裏都有完整的版本庫,某一我的的電腦壞掉了沒關係,隨便從其餘人那裏複製一個就能夠了。而集中式版本控制系統的中央服務器要是出了問題,全部人都無法幹活了。
在實際使用分佈式版本控制系統的時候,其實不多在兩人之間的電腦上推送版本庫的修改,由於可能大家倆不在一個局域網內,兩臺電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。所以,分佈式版本控制系統一般也有一臺充當「中央服務器」的電腦,但這個服務器的做用僅僅是用來方便「交換」你們的修改,沒有它你們也同樣幹活,只是交換修改不方便而已。如上圖!緩存
Git特色安全
1)分佈式 2)存儲快照而非差別 3)本地有徹底的版本庫,幾乎全部操做都在本地 4)有內在的一致性,SHA1 5)優秀的分支管理 6)支持各類協同模式 7)開源,有一些第三方軟件可整合使用,幾乎全部操做都是 與CVS/SVN,Git 的優點 1)支持離線開發,離線Repository(倉庫) 2)強大的分支功能,適合多個獨立開發者協做 3)速度塊
爲何選擇Git來控制版本,理由以下:bash
1)快速 若是你每移動一下鼠標都要等待五秒,是否是很受不了?版本控制也是同樣的,每個命令多那麼幾秒鐘,一天下來也會浪費你很多時間。Git的操做很是快速,你能夠把時間用在別的更有意義的地方。 2)離線工做 在沒有網絡的狀況下如何工做?若是你用SVN或者CVS的話就很麻煩。而Git可讓你在本地作全部操做,提交代碼,查看歷史,合併,建立分支等等。 3)回退 人不免犯錯。我很喜歡Git的一點就是你能夠「undo」幾乎全部的命令。你能夠用這個功能來修正你剛剛提交的代碼中的一個問題或者回滾整個代碼提交操做。你甚至能夠恢復一個被刪除的提交,由於在後端,Git幾乎不作任何刪除操做。 4)省心 你有沒有丟失過版本庫?我有,而那種頭疼的感受如今還記憶猶新。而用Git的話,我就沒必要擔憂這個問題,由於任何一我的機器上的版本都是一個完整的備份。 5)選擇有用的代碼提交 當你把紐帶,冰塊還有西紅柿一塊兒扔進攪拌機的時候至少有兩個問題。第一,攪拌事後,沒有人知道以前扔進去了些什麼東西。第二,你不能回退,從新把西紅柿拿出來。一樣的,當你提交了一堆無關的更改,例如功能A增強,新增功能B,功能C修復,想要理清這一堆代碼到底幹了什麼是很困難的。固然,當發現功能A出問題的時候,你沒法單獨回滾功能A。Git能夠經過建立「顆粒提交」,幫你解決這個問題。「staging area」的概念可讓你決定到底那些東西須要提交,或者更新,精確到行。 6)自由選擇工做方式 使用Git,你能夠同時和多個遠程代碼庫鏈接,「rebase」而不是"merge"甚至只鏈接某個模塊。可是你也能夠選擇一箇中央版本庫,就像SVN那樣。你依然能夠利用Git的其餘優勢。 7)保持工做獨立 把不一樣的問題分開處理將有助於跟蹤問題的進度。當你在爲功能A工做的時候,其餘人不該該被你尚未完成的代碼所影響。分支是解決這個問題的辦法。雖然其餘的版本控制軟件業有分支系統,可是Git是第一個把這個系統變得簡單而快速的系統。 8)隨大流 雖然只有死於才隨着波浪前進,可是不少時候聰明的程序員也是隨大流的。愈來愈多的公司,開源項目使用Git,包括Ruby On Rails,jQuery,Perl,Debian,Linux Kernel等等。擁有一個強大的社區是很大的優點,有不少教程、工具。
Git原理
1)四種基本類型 BLOB: 每一個blob表明一個(版本的)文件,blob只包含文件的數據,而忽略文件的其餘元數據,如名字、路徑、格式等。 TREE: 每一個tree表明了一個目錄的信息,包含了此目錄下的blobs,子目錄(對應於子trees),文件名、路徑等元數據。所以,對於有子目錄的目錄,git至關於存儲了嵌套的trees。 COMMIT:每一個commit記錄了提交一個更新的全部元數據,如指向的tree,父commit,做者、提交者、提交日期、提交日誌等。每次提交都指向一個tree對象,記錄了當次提交時的目錄信息。一個commit能夠有多個(至少一個)父commits。 TAG: ag用於給某個上述類型的對象指配一個便於開發者記憶的名字, 一般用於某次commit。
2)工做區(Working Dir),提交區/暫存區(stage/index),版本庫
Git的安裝
不一樣的系統不一樣的安裝命令,centos系統下直接yum就能夠。 [root@master-node ~]# yum install -y git 安裝完成後,還須要最後一步設置,在命令行輸入: [root@master-node ~]#git config --global user.email "you@example.com" [root@master-node ~]#git config --global user.name "Your Name" 由於Git是分佈式版本控制系統,因此,每一個機器都必須自報家門:你的名字和Email地址。你也許會擔憂,若是有人故意冒充別人怎麼辦?這個沒必要擔憂,首先咱們相信你們都是善良無知的羣衆,其次,真的有冒充的也是有辦法可查的。 注意: git config命令的--global參數,用了這個參數,表示你這臺機器上全部的Git倉庫都會使用這個配置,固然也能夠對某個倉庫指定不一樣的用戶名和Email地址。
Git經常使用的命令(即git + 下面的參數組成的命令):
add 添加文件內容至索引 bisect 經過二分查找定位引入 bug 的變動 branch 列出、建立或刪除分支 checkout 檢出一個分支或路徑到工做區 clone 克隆一個版本庫到一個新目錄 commit 記錄變動到版本庫 diff 顯示提交之間、提交和工做區之間等的差別 fetch 從另一個版本庫下載對象和引用 grep 輸出和模式匹配的行 init 建立一個空的 Git 版本庫或從新初始化一個已存在的版本庫 log 顯示提交日誌 merge 合併兩個或更多開發歷史 mv 移動或重命名一個文件、目錄或符號連接 pull 獲取併合並另外的版本庫或一個本地分支 push 更新遠程引用和相關的對象 rebase 本地提交轉移至更新後的上游分支中 reset 重置當前HEAD到指定狀態 rm 從工做區和索引中刪除文件 show 顯示各類類型的對象 status 顯示工做區狀態 tag 建立、列出、刪除或校驗一個GPG簽名的 tag 對象
建立版本庫
什麼是版本庫呢?版本庫又名倉庫,英文名repository,你能夠簡單理解成一個目錄,這個目錄裏面的全部文件均可以被Git管理起來,每一個文件的修改、刪除,Git都能跟蹤,以便任什麼時候刻均可以追蹤歷史,或者在未來某個時刻能夠「還原」。 因此,建立一個版本庫很是簡單,首先,選擇一個合適的地方,建立一個空目錄: 第一步:建立一個倉庫的目錄 [root@master-node /]# mkdir git_test [root@master-node /]# cd git_test/ [root@master-node git_test]# pwd /git_test 第二步:經過git init 命令把這個目錄變成git能夠管理的倉庫 [root@master-node git_test]# git init 初始化空的 Git 版本庫於 /git_test/.git/ [root@master-node git_test]# ls -al 總用量 12 drwxr-xr-x 3 root root 4096 5月 10 13:53 . drwxr-xr-x. 19 root root 4096 5月 10 13:50 .. drwxr-xr-x 7 root root 4096 5月 10 13:53 .git 瞬間Git就把倉庫建好了,並且告訴你是一個空的倉庫(empty Git repository),細心的讀者能夠發現當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄裏面的文件,否則改亂了,就把Git倉庫給破壞了。也不必定必須在空目錄下建立Git倉庫,選擇一個已經有東西的目錄也是能夠的。 第三步:把文件添加到版本庫 首先這裏再明確一下,全部的版本控制系統,其實只能跟蹤文本文件的改動,好比TXT文件,網頁,全部的程序代碼等等,Git也不例外。版本控制系統能夠告訴你每次的改動,好比在第5行加了一個單詞「Linux」,在第8行刪了一個單詞「Windows」。而圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但無法跟蹤文件的變化,只能把二進制文件每次改動串起來,也就是隻知道圖片從100KB改爲了120KB,但到底改了啥,版本控制系統不知道,也無法知道。 如今咱們編寫一個readme.txt文件,內容以下 [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt 必定要放到git_test目錄下面,子目錄也能夠,放到其餘地方git找不到文件。 把一個文件放到Git倉庫只須要兩步。 1)用命令git add告訴git,把文件添加到倉庫 [root@master-node git_test]# git add readme.txt 執行上面的命令,沒有任何的顯示就對了。Linux的哲學思想:沒有消息就是最好的消息,說明添加成功。 2)用命令git commit告訴git,把文件提交到倉庫 [root@master-node git_test]# git commit -m "cgt write a readme file" [master(根提交) 87818f5] cgt write a readme file 1 file changed, 2 insertions(+) create mode 100644 readme.txt 簡單解釋一下git commit命令,-m後面輸入的是本次提交的說明,能夠輸入任意內容,固然最好是有意義的,這樣你就能從歷史記錄裏方便地找到改動記錄。 嫌麻煩不想輸入-m "xxx"行不行?確實有辦法能夠這麼幹,可是強烈不建議你這麼幹,由於輸入說明對本身對別人閱讀都很重要。實在不想輸入說明的童鞋請自行Google,我不告訴你這個參數。 git commit命令執行成功後會告訴你,1個文件被改動(咱們新添加的readme.txt文件),插入了兩行內容(readme.txt有兩行內容)。 爲何Git添加文件須要add,commit一共兩步呢?由於commit能夠一次提交不少文件,因此你能夠屢次add不一樣的文件,好比: [root@master-node git_test]# touch file1 file2 file3 [root@master-node git_test]# ls file1 file2 file3 readme.txt [root@master-node git_test]# git add file1 file2 file3 [root@master-node git_test]# git commit -m "add 3 files" [master 827526e] add 3 files 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 file1 create mode 100644 file2 create mode 100644 file3
再次插足一下,說明一下git的工做流:
你的本地倉庫由 git 維護的三棵"樹"組成。第一個是你的 工做目錄,它持有實際文件;第二個是 暫存區(staging),它像個緩存區域,臨時保存你的改動;最後是 HEAD,它指向你最後一次提交的結果。 你能夠提出更改(把它們添加到暫存區),使用以下命令: git add <filename> git add * 這是 git 基本工做流程的第一步;使用以下命令以實際提交改動: git commit -m "代碼提交信息" 如今,你的改動已經提交到了 HEAD,可是還沒到你的遠端倉庫。
回滾-讓去哪就去哪
前面已經建立了一個readme.txt文件,如今咱們對他進行一些改動操做。 [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 執行git status [root@master-node git_test]# git status # 位於分支 master # 還沒有暫存以備提交的變動: # (使用 "git add <file>..." 更新要提交的內容) # (使用 "git checkout -- <file>..." 丟棄工做區的改動) # # 修改: readme.txt # 修改還沒有加入提交(使用 "git add" 和/或 "git commit -a") git status命令可讓咱們時刻掌握倉庫當前的狀態,上面的命令告訴咱們,readme.txt被修改過了,但尚未準備提交的修改。 雖然Git告訴咱們readme.txt被修改了,但若是能看看具體修改了什麼內容,天然是很好的。好比你次日上班時,已經記不清上次怎麼修改的readme.txt,因此,須要用git diff這個命令看看,而後add以後在看一下status,是顯示要commit的文件,如今再回想一下那個工做流圖 [root@master-node git_test]# git diff diff --git a/readme.txt b/readme.txt index b7cffdb..43b7253 100644 --- a/readme.txt +++ b/readme.txt @@ -1,2 +1,3 @@ Git is veryt good tool auth :cgt +date:2016-5-10 [root@master-node git_test]# git add readme.txt [root@master-node git_test]# git status # 位於分支 master # 要提交的變動: # (使用 "git reset HEAD <file>..." 撤出暫存區) # # 修改: readme.txt 接下來進行commit操做 [root@master-node git_test]# git commit -m "add date" [master de00305] add date 1 file changed, 1 insertion(+) 提交以後,在查看status [root@master-node git_test]# git status # 位於分支 master 無文件要提交,乾淨的工做區
版本的回退
如今,你已經學會了修改文件,而後把修改提交到Git版本庫,如今,再練習一次,修改readme.txt文件以下: [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 version:1 [root@master-node git_test]# git add readme.txt [root@master-node git_test]# git commit -m "version" [master 8b7d4ee] version 1 file changed, 1 insertion(+) 目前咱們已經提交了三次,暫時你還能記住,可是在實際工做中咱們是記不住的,否則要版本控制系統幹什麼。版本控制系統確定有某個命令能夠告訴咱們歷史記錄,在Git中,咱們用git log命令查看: [root@master-node git_test]# git log commit 8b7d4eebe4e03809162f8193d6b2338926896ab4 Author: caoxiaojian <1099415469@qq.com> Date: Tue May 10 14:59:16 2016 +0800 version commit de003058c91312f695b57f42724f826f6ef42f17 Author: caoxiaojian <1099415469@qq.com> Date: Tue May 10 14:52:10 2016 +0800 add date commit 827526ee243c93bfaf8f4f2f9dc22d31325cb47a Author: caoxiaojian <1099415469@qq.com> Date: Tue May 10 14:23:08 2016 +0800 add 3 files commit 87818f5454a2bc41cfbeca4b923a510d11fe72ac Author: caoxiaojian <1099415469@qq.com> Date: Tue May 10 14:19:08 2016 +0800 cgt write a readme file git log 顯示從最近到最遠的提交日誌,咱們能夠看到四次提交,最近的一次是version,上一次是date,最先的一次是cgt write a readme file 。 若是嫌輸出的信息太多,可使用--pretty=oneline [root@master-node git_test]# git log --pretty=oneline 8b7d4eebe4e03809162f8193d6b2338926896ab4 version de003058c91312f695b57f42724f826f6ef42f17 add date 827526ee243c93bfaf8f4f2f9dc22d31325cb47a add 3 files 87818f5454a2bc41cfbeca4b923a510d11fe72ac cgt write a readme file 須要友情提示的是,你看到的一大串8b7d4eebe4e03809162f8193d6b2338926896ab4相似的是commit id(版本號),和SVN不同,Git的commit id不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個很是大的數字,用十六進制表示,並且你看到的commit id和個人確定不同,以你本身的爲準。爲何commit id須要用這麼一大串數字表示呢?由於Git是分佈式的版本控制系統,後面咱們還要研究多人在同一個版本庫裏工做,若是你們都用1,2,3……做爲版本號,那確定就衝突了。 如今開始回滾, 準備把readme.txt回退到上一個版本,也就是「date」的那個版本,怎麼作呢? 首先,Git必須知道當前版本是哪一個版本,在Git中,用HEAD表示當前版本,也就是最新的提交3628164...882e1e0(注意個人提交ID和你的確定不同),上一個版本就是HEAD^,上上一個版本就是HEAD^^,固然往上100個版本寫100個^比較容易數不過來,因此寫成HEAD~100。 回滾,咱們可使用git reset這個命令 [root@master-node git_test]# git reset --hard HEAD^ HEAD 如今位於 de00305 add date [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 能夠看出,他沒有version那行,說明回滾成功。 再來看git log [root@master-node git_test]# git log commit de003058c91312f695b57f42724f826f6ef42f17 Author: caoxiaojian <1099415469@qq.com> Date: Tue May 10 14:52:10 2016 +0800 add date commit 827526ee243c93bfaf8f4f2f9dc22d31325cb47a Author: caoxiaojian <1099415469@qq.com> Date: Tue May 10 14:23:08 2016 +0800 add 3 files commit 87818f5454a2bc41cfbeca4b923a510d11fe72ac Author: caoxiaojian <1099415469@qq.com> Date: Tue May 10 14:19:08 2016 +0800 cgt write a readme file 沒有了以前的version,那我要怎麼才能恢復呢,回你的終端上,看看version的commit id,咱們找到了: 8b7d4eebe4e03809162f8193d6b2338926896ab4 version,執行恢復。恢復的時候ID不須要寫所有的。 [root@master-node git_test]# git reset --hard 8b7d4eebe4 HEAD 如今位於 8b7d4ee version [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 version:1
回滾原理解析:
Git的版本回退速度很是快,由於Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從當前的version,指到date
回滾後
而後順便把工做區的文件更新了。因此你讓HEAD指向哪一個版本號,你就把當前版本定位在哪。 到了這裏確定有童鞋要問,那我要是不知道我前面的ID了,我去哪裏回滾,我是否是該收拾工位回滾到家中了,git早就替你想好了,可使用git reflog,把以前的ID都顯示出來 [root@master-node git_test]# git reflog 8b7d4ee HEAD@{0}: reset: moving to 8b7d4eebe4 de00305 HEAD@{1}: reset: moving to HEAD^ 8b7d4ee HEAD@{2}: commit: version de00305 HEAD@{3}: commit: add date 827526e HEAD@{4}: commit: add 3 files 87818f5 HEAD@{5}: commit (initial): cgt write a readme file
工做區和暫存區
不知道你是否是理解了我以前說的那個工做流,我們這裏再來囉嗦一遍。
Git和其餘版本控制系統如svn不一樣之處是有暫存區的概念
先弄清楚這幾個名次
工做區:
就是在你的電腦裏能看到的目錄,好比我們建立的git_test
版本庫:
工做區中有一個隱藏目錄.git(以前已經給童鞋們提到過這個文件),它不算工做區,而是git的版本庫。
git的版本庫裏面存放了不少的東西,其中最重要的就是稱爲stage(index)的暫存區,還有git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫head。
當咱們在工做區建立了文件後,執行add後,再來看這個圖
當你執行commit後,暫存區的內容就沒有
管理修改
爲何Git比其餘版本控制系統設計得優秀,由於Git跟蹤並管理的是修改,而非文件。 你會問,什麼是修改?好比你新增了一行,這就是一個修改,刪除了一行,也是一個修改,更改了某些字符,也是一個修改,刪了一些又加了一些,也是一個修改,甚至建立一個新文件,也算一個修改。 爲何說Git管理的是修改,而不是文件呢?咱們仍是作實驗。第一步,對readme.txt作一個修改,第二步,添加到暫存區。第三步,查看狀態 [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 version:1 modify----------1 [root@master-node git_test]# git add readme.txt [root@master-node git_test]# git status # 位於分支 master # 要提交的變動: # (使用 "git reset HEAD <file>..." 撤出暫存區) # # 修改: readme.txt # 第四步,再次編輯readme.txt,而後直接commit,再次查看status [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 version:1 modify----------1 modify----------2 [root@master-node git_test]# git commit -m "modify" [master 766baac] modify 1 file changed, 1 insertion(+) [root@master-node git_test]# git status # 位於分支 master # 還沒有暫存以備提交的變動: # (使用 "git add <file>..." 更新要提交的內容) # (使用 "git checkout -- <file>..." 丟棄工做區的改動) # # 修改: readme.txt # 修改還沒有加入提交(使用 "git add" 和/或 "git commit -a") 發現第二次的修改沒有commit,那是由於你沒有add 提交後,用git diff HEAD -- readme.txt命令能夠查看工做區和版本庫裏面最新版本的區別: [root@master-node git_test]# git diff HEAD -- readme.txt diff --git a/readme.txt b/readme.txt index 4416460..07c12e7 100644 --- a/readme.txt +++ b/readme.txt @@ -3,3 +3,4 @@ auth :cgt date:2016-5-10 version:1 modify----------1 +modify----------2
撤銷修改
編輯了readme, [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 version:1 modify----------1 modify----------2 caoxiaojian is xiaojianjian 已經編輯完成,突然發現了問題,最後一行,道出了筆者的心聲。既然已經發現錯誤,那就很容易糾正它,你能夠刪除掉最後一行,手動把文件恢復到上一個版本的狀態,若是用git status查看一下, [root@master-node git_test]# git status # 位於分支 master # 還沒有暫存以備提交的變動: # (使用 "git add <file>..." 更新要提交的內容) # (使用 "git checkout -- <file>..." 丟棄工做區的改動) # # 修改: readme.txt # 修改還沒有加入提交(使用 "git add" 和/或 "git commit -a") 你能夠發現上面提示你使用 "git checkout -- <file>..." 丟棄工做區的改動,那咱們執行下 [root@master-node git_test]# git checkout -- readme.txt [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 version:1 modify----------1 已經回來了。 命令git checkout -- readme.txt意思就是,把readme.txt文件在工做區的修改所有撤銷,這裏有兩種狀況: 一種是readme.txt自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態; 一種是readme.txt已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。 總之,就是讓這個文件回到最近一次git commit或git add時的狀態。 git checkout -- file命令中的--很重要,沒有--,就變成了「切換到另外一個分支」的命令,咱們在後面的分支管理中會再次遇到git checkout命令。 剛剛我們沒有將修改提交到暫存區,那假如你提交到了呢??????你說咋整呢?????是否是嚇尿了???? [root@master-node git_test]# cat readme.txt Git is veryt good tool auth :cgt date:2016-5-10 version:1 modify----------1 caoxiaojian is xiaojianjian [root@master-node git_test]# git add readme.txt [root@master-node git_test]# git status # 位於分支 master # 要提交的變動: # (使用 "git reset HEAD <file>..." 撤出暫存區) # 修改: readme.txt 你要是聰明的話,你應該已經知道要怎麼作了。。。。對是的,就是你想的那樣。 [root@master-node git_test]# git reset HEAD readme.txt 重置後撤出暫存區的變動: M readme.txt [root@master-node git_test]# git status # 位於分支 master # 還沒有暫存以備提交的變動: # (使用 "git add <file>..." 更新要提交的內容) # (使用 "git checkout -- <file>..." 丟棄工做區的改動) # # 修改: readme.txt # 修改還沒有加入提交(使用 "git add" 和/或 "git commit -a") 已經退出了暫存區。你可能要問,那要是已經commit了呢??你小子膽子還真不小啊,教你一招,以前不是講過回滾嘛,直接回滾。不過這個也是有條件的,就是你尚未把本身的本地版本庫推送到遠程。Git是一個分佈式版本控制,他還有遠程版本庫,一旦你提交到遠程版本庫,那你就能夠git go home
刪除文件
先建立文件,後add,在commit,而後刪除工做區的文件 [root@master-node git_test]# cat test.txt qwertyuiop[ adfghjjljh fdgscvxz [root@master-node git_test]# git add test.txt [root@master-node git_test]# git commit -m "del test" [master 63d3bf7] del test 1 file changed, 3 insertions(+) create mode 100644 test.txt [root@master-node git_test]# rm -rf test.txt [root@master-node git_test]# git status # 位於分支 master # 還沒有暫存以備提交的變動: # (使用 "git add/rm <file>..." 更新要提交的內容) # (使用 "git checkout -- <file>..." 丟棄工做區的改動) # # 修改: readme.txt # 刪除: test.txt # 修改還沒有加入提交(使用 "git add" 和/或 "git commit -a") 如今你有兩個選擇,一是確實要從版本庫中刪除該文件,那就用命令git rm刪掉,而且git commit: [root@master-node git_test]# git rm test.txt rm 'test.txt' [root@master-node git_test]# git commit -m "remove test.txt" [master 5f04ee2] remove test.txt 1 file changed, 3 deletions(-) delete mode 100644 test.txt 如今文件就從版本庫中完全的刪除了。 命令git rm用於刪除一個文件。若是一個文件已經被提交到版本庫,那麼你永遠不用擔憂誤刪,可是要當心,你只能恢復文件到最新版本,你會丟失最近一次提交後你修改的內容。 另外一種狀況是刪錯了,由於版本庫裏還有呢,因此能夠很輕鬆地把誤刪的文件恢復到最新版本: 使用 git checkout -- test.txt git checkout實際上是用版本庫裏的版本替換工做區的版本,不管工做區是修改仍是刪除,均可以「一鍵還原」。
遠程倉庫
可使用github給咱們提供的服務,做爲咱們的一個遠程倉庫。可是須要作一下的設置。 因爲你的本地Git倉庫和GitHub倉庫之間的傳輸是經過SSH加密的,因此咱們首先生成祕鑰。 第1步:建立SSH Key。 在用戶主目錄下,看看有沒有.ssh目錄,若是有,再看看這個目錄下有沒有id_rsa和id_rsa.pub這兩個文件,若是已經有了,可直接跳到下一步。若是沒有,打開Shell(Windows下打開Git Bash),建立SSH Key: ssh-keygen -t rsa -C "youremail@example.com" 你須要把郵件地址換成你本身的郵件地址,而後一路回車,使用默認值便可,因爲這個Key也不是用於軍事目的,因此也無需設置密碼。 若是一切順利的話,能夠在用戶主目錄裏找到.ssh目錄,裏面有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的祕鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,能夠放心地告訴任何人。 第2步:添加公鑰到你的 登錄GitHub,打開「Account settings」,「SSH Keys」頁面,而後將你的key添加上。 爲何GitHub須要SSH Key呢?由於GitHub須要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git支持SSH協議,因此,GitHub只要知道了你的公鑰,就能夠確認只有你本身才能推送。
添加遠程庫
你本來在本地已經建立了一個Git倉庫,如今又想在github上也建立一個倉庫,讓這兩個倉庫能夠遠程同步。這樣github的倉庫既能夠做爲備份,又可讓其餘人經過該倉庫來協做。
第一步:建立一個新的倉庫repository
右上角有個➕,而後如今new repository
而後進入建立頁面
倉庫內容的提交
接下來我們看如何使用
本地沒有倉庫的狀況下,要先建立倉庫。
[root@master-node ~]# mkdir /test
[root@master-node ~]# cd /test
使用git init 建立定義倉庫
[root@master-node ~]# git init
Initialized empty Git repository in C:/Program Files/Git/test/.git/
[root@master-node ~]# ls -al
total 8
drwxr-xr-x 1 cgt 197121 0 五月 16 06:11 ./
drwxr-xr-x 1 cgt 197121 0 五月 16 06:11 ../
drwxr-xr-x 1 cgt 197121 0 五月 16 06:11 .git/
在倉庫中建立一個文件,而後add commit
[root@master-node ~]# echo "# test " >> README.md
[root@master-node ~]# git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
[root@master-node ~]# git commit -m "first commit"
[master (root-commit) 7eeb945] first commit
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
1 file changed, 1 insertion(+)
create mode 100644 README.md
至此,提交到本地的head中。也就是本地倉庫中,而後從本地倉庫向遠程倉庫提交。
使用remote關聯一個遠程庫,add是定義一個遠程的名稱,默認通常使用origin,後面跟的是遠程倉庫的名稱
[root@master-node ~]# git remote add origin git@github.com:caoxiaojian/test.git
把本地庫的內容推送到遠程,其實是將本地的當前分支master,推送到遠程
[root@master-node ~]# git push -u origin master
Warning: Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts.
Counting objects: 3, done.
Writing objects: 100% (3/3), 210 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:caoxiaojian/test.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。
再次修改README.md
[root@master-node ~]# echo "# this is my test file " >> README.md
[root@master-node ~]# git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
[root@master-node ~]# git commit -m "2 commit"
[master warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
80bc0e7] 2 commit
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
1 file changed, 1 insertion(+)
[root@master-node ~]# git push origin master
Warning: Permanently added the RSA host key for IP address '192.30.252.120' to the list of known hosts.
Counting objects: 3, done.
Writing objects: 100% (3/3), 257 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:caoxiaojian/test.git
7eeb945..80bc0e7 master -> master
到github下面對應的倉庫裏查看
每次本地提交後,只要有必要,就可使用命令git push origin master推送最新修改
克隆遠程庫
在剛建立的倉庫中建立新文件
建立文件
建立完成後能夠看見你的新文件
由於以前已經建立了test這個本地倉庫,因此先刪除,而後再clone
[root@master-node ~]# rm -rf /test/
[root@master-node ~]# git clone git@github.com:caoxiaojian/test.git
Cloning into 'test'...
Warning: Permanently added the RSA host key for IP address '192.30.252.121' to the list of known hosts.
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 9 (delta 0), reused 6 (delta 0), pack-reused 0
Receiving objects: 100% (9/9), done.
Checking connectivity... done.
[root@master-node ~]# cd /test/
test (master)
[root@master-node ~]# ls
new_file README.md
test (master)
[root@master-node ~]# cat new_file
make a new file for clone test
分支管理分支在實際中有什麼用呢?假設你準備開發一個新功能,可是須要兩週才能完成,第一週你寫了50%的代碼,若是馬上提交,因爲代碼還沒寫完,不完整的代碼庫會致使別人不能幹活了。若是等代碼所有寫完再一次提交,又存在丟失天天進度的巨大風險。如今有了分支,就不用怕了。你建立了一個屬於你本身的分支,別人看不到,還繼續在原來的分支上正常工做,而你在本身的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的分支上,這樣,既安全,又不影響別人工做。