Git & github 入門(上)

本節內容html

  1. github介紹
  2. 安裝
  3. 倉庫建立& 提交代碼
  4. 代碼回滾
  5. 工做區和暫存區
  6. 撤銷修改
  7. 刪除操做
  8. 遠程倉庫
  9. 分支管理
  10. 多人協做
  11. github使用
  12. 忽略特殊文件.gitignore

前戲

爲何要用版本控制?python

假設你在的公司要上線一個新功能,大家開發團隊爲實現這個新功能,寫了大約5000行代碼,上線沒2天,就發現這個功能用戶並不喜歡,你老闆讓你去掉這個功能,你怎麼辦?你說簡單,直接把5000行代碼去掉就好了,可是個人親,說的簡單,你的這個功能寫了3周時間,但你還能記得你是新增長了哪5000行代碼麼?因此你急須要一個工具,能幫你記錄每次對代碼作了哪些修改,而且能夠輕易的把代碼回滾到歷史上的某個狀態。 這個神奇的工具就叫作版本控制。 linux

 

版本控制工具主要實現2個功能:git

1.版本管理github

在開發中,這是剛需,必須容許能夠很容易對產品的版本進行任意回滾,版本控制工具實現這個功能的原理簡單來說,就是你每修改一次代碼,它就幫你作一次快照vim

2.協做開發bash

一個複雜點的軟件,每每不是一個開發人員能夠搞定的,公司爲加快產品開發速度,會招聘一堆跟你同樣的開發人員開發這個產品,拿微信來舉例,如今假設3我的一塊兒開發微信,A開發聯繫人功能,B開發發文字、圖片、語音通信功能,C開發視頻通話功能, B和C的功能都是要基於通信錄的,你說簡單,直接把A開發的代碼copy過來,在它的基礎上開發就行了,能夠,可是你在他的代碼基礎上開發了2周後,這期間A沒閒着,對通信錄代碼做了更新,此時怎麼辦?你和他的代碼不一致了,此時咱們知道,你確定要再把A的新代碼拿過來替換掉你手上的舊通信錄功能代碼, 如今人少,3我的之間溝通很簡單,但想一想,若是團隊變成30我的呢?來回這樣copy代碼,很快就亂了, 因此此時亟需一個工具,能確保一直存儲最新的代碼庫,全部人的代碼應該和最新的代碼庫保持一致服務器

常見版本管理工具介紹微信

一、VSS-- Visual Source Safe
此工具是Microsoft提供的,是使用的至關廣泛的工具之一,他能夠與VS.net進行無縫集成,成爲了獨立開發人員和小型開發團隊所適合的工具,基本上Window平臺上開發的中小型企業,當規模較大後,其性能一般是沒法忍受的,對分支與並行開發支持的比較有限。分佈式

二、CVS--Concurrent Versions System,
此工具是一個開源工具,與後面提到的SVN是同一個廠家:Collab.Net提供的。
CVS是源於unix的版本控制工具,對於CVS的安裝和使用最好對unix的系統有所瞭解能更容易學習,CVS的服務器管理須要進行各類命令行操做。目前,CVS的客戶端有winCVS的圖形化界面,服務器端也有CVSNT的版本,易用性正在提升。
此工具是至關著名,使用得至關普遍的版本控制工具之一,使用成熟的「Copy-Modify-Merge"開發模型,能夠大大的提升開發效率,適合於項目比較大,產品發佈頻繁,分支活動頻繁的中大型項目。

三、SVN --CollabNet Subversion
此工具是在CVS 的基礎上,由CollabNet提供開發的,也是開源工具,目前愈來愈受到你們的歡迎,估計未來可能會成爲最著名,使用最普遍的工具。
他修正cvs的一些侷限性,適用範圍同cvs,目前有一些基於SVN的第三方工具,如TortoiseSVN,是其客戶端程序,使用的也至關普遍。在權限管理,分支合併等方面作的很出色,他能夠與Apache集成在一塊兒進行用戶認證。
不過在權限管理方面目前尚未個很好用的界面化工具,SVNManger對於已經使用SVN進行配置的項目來講,基本上是沒法應用的,但對於從頭開始的項目是能夠的,功能比較強大,可是搭建svnManger比較麻煩。
是一個跨平臺的軟件,支持大多數常見的操做系統。做爲一個開源的版本控制系統,Subversion 管理着隨時間改變的數據。 這些數據放置在一箇中央資料檔案庫中。 這個檔案庫很像一個普通的文件服務器, 不過它會記住每一次文件的變更。 這樣你就能夠把檔案恢復到舊的版本, 或是瀏覽文件的變更歷史。Subversion 是一個通用的系統, 可用來管理任何類型的文件, 其中包括了程序源碼。


4. GIT
由於最初是從Linux起家的,很是依賴文件系統的一些特性,這些在 Linux 下表現的很好,而 Windows 下特別糟糕Git 中文教程
Git是一個開源的分佈式版本控制系統,用以有效、高速的處理從很小到很是大的項目版本管理.
Git 是 Linus Torvalds 爲了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟件。
Torvalds 開始着手開發 Git 是爲了做爲一種過渡方案來替代 BitKeeper,後者以前一直是 Linux 內核開發人員在全球使用的主要源代碼工具。開放源碼社區中的有些人以爲 BitKeeper 的許可證並不適合開放源碼社區的工做,所以 Torvalds 決定着手研究許可證更爲靈活的版本控制系統。儘管最初 Git 的開發是爲了輔助 Linux 內核開發的過程,可是咱們已經發如今不少其餘自由軟件項目中也使用了 Git。例如 最近就遷移到 Git 上來了,不少 Freedesktop 的項目也遷移到了 Git 上。

五、BitKeeper
是由BitMover公司提供的,BitKeeper自稱是「分佈式」可擴縮SCM系統。
不是採用C/S結構,而是採用P2P結構來實現的,一樣支持變動任務,全部變動集的操做都是原子的,與svn,cvs一致。

1.Github介紹

1.github介紹

不少人都知道,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網站上線了(github是一個基於git的代碼託管平臺,付費用戶能夠建私人倉庫,咱們通常的免費用戶只能使用公共倉庫,也就是代碼要公開。),它爲開源項目免費提供Git存儲,無數開源項目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。

歷史就是這麼偶然,若是不是當年BitMover公司威脅Linux社區,可能如今咱們就沒有免費而超級好用的Git了。

 

今天,GitHub已經是:

一個擁有143萬開發者的社區。其中不乏Linux發明者Torvalds這樣的頂級黑客,以及Rails創始人DHH這樣的年輕極客。
這個星球上最流行的開源託管服務。目前已託管431萬git項目,不只愈來愈多知名開源項目遷入GitHub,好比Ruby on Rails、jQuery、Ruby、Erlang/OTP;近三年流行的開源庫每每在GitHub首發,例如:BootStrap、Node.js、CoffeScript等。
alexa全球排名414的網站。
View Code

 

2. git安裝

安裝Git

最先Git是在Linux上開發的,很長一段時間內,Git也只能在Linux和Unix系統上跑。不過,慢慢地有人把它移植到了Windows上。如今,Git能夠在Linux、Unix、Mac和Windows這幾大平臺上正常運行了。

 要使用Git,第一步固然是安裝Git了。根據你當前使用的平臺來閱讀下面的文字:

在Linux上安裝Git

首先,你能夠試着輸入git,看看系統有沒有安裝Git:

$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

像上面的命令,有不少Linux會友好地告訴你Git沒有安裝,還會告訴你如何安裝Git。

若是你碰巧用Debian或Ubuntu Linux,經過一條sudo apt-get install git就能夠直接完成Git的安裝,很是簡單。

3.版本庫建立

什麼是版本庫呢?版本庫又名倉庫,英文名repository,你能夠簡單理解成一個目錄,這個目錄裏面的全部文件均可以被Git管理起來,每一個文件的修改、刪除,Git都能跟蹤,以便任什麼時候刻均可以追蹤歷史,或者在未來某個時刻能夠「還原」。

因此,建立一個版本庫很是簡單,首先,選擇一個合適的地方,建立一個空目錄:

$ mkdir git_trainning
$ cd git_trainning/
 
$ git init
Initialized empty Git repository in /Users/alex/git_trainning/.git/

瞬間Git就把倉庫建好了,並且告訴你是一個空的倉庫(empty Git repository),細心的讀者能夠發現當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄裏面的文件,否則改亂了,就把Git倉庫給破壞了。

若是你沒有看到.git目錄,那是由於這個目錄默認是隱藏的,用ls -ah命令就能夠看見。

把文件添加到版本庫

首先這裏再明確一下,全部的版本控制系統,其實只能跟蹤文本文件的改動,好比TXT文件,網頁,全部的程序代碼等等,Git也不例外。版本控制系統能夠告訴你每次的改動,好比在第5行加了一個單詞「Linux」,在第8行刪了一個單詞「Windows」。而圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但無法跟蹤文件的變化,只能把二進制文件每次改動串起來,也就是隻知道圖片從100KB改爲了120KB,但到底改了啥,版本控制系統不知道,也無法知道。

不幸的是,Microsoft的Word格式是二進制格式,所以,版本控制系統是無法跟蹤Word文件的改動的,前面咱們舉的例子只是爲了演示,若是要真正使用版本控制系統,就要以純文本方式編寫文件。

由於文本是有編碼的,好比中文有經常使用的GBK編碼,日文有Shift_JIS編碼,若是沒有歷史遺留問題,強烈建議使用標準的UTF-8編碼,全部語言使用同一種編碼,既沒有衝突,又被全部平臺所支持。

言歸正傳,如今咱們編寫一個first_git_file.txt文件,內容以下:

$ vim first_git_file.txt
 
first time using git, excited!
第一次用git哈哈

必定要放到git_trainning目錄下(子目錄也行),由於這是一個Git倉庫,放到其餘地方Git再厲害也找不到這個文件。

和把大象放到冰箱須要3步相比,把一個文件放到Git倉庫只須要兩步。

第一步,用命令git add告訴Git,把文件添加到倉庫:

1
$ git add first_git_file.txt

執行上面的命令,沒有任何顯示,說明添加成功。

第二步,用命令git commit告訴Git,把文件提交到倉庫:  

$ git commit -m "commit my first git file"
 
[master (root-commit) 621e6e4] commit my first git file
 Committer: Alex Li <alex@alexs-macbook-pro.local>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:
 
    git config --global --edit
 
After doing this, you may fix the identity used for this commit with:
 
    git commit --amend --reset-author
 
 1 file changed, 2 insertions(+)
 create mode 100644 first_git_file.txt
</alex@alexs-macbook-pro.local>

中間紅色部分的意思是,你在往git庫裏提交代碼時,你須要告訴git你是誰,這樣git就會紀錄下來是誰改的代碼,其實就是爲了往後查詢方便,你只須要提供一個名字和郵件地址就能夠,這裏個人git直接經過主機名本身建立了一個,但你能夠經過git config --global --edit修改

 

簡單解釋一下git commit命令,-m後面輸入的是本次提交的說明,能夠輸入任意內容,固然最好是有意義的,這樣你就能從歷史記錄裏方便地找到改動記錄。

嫌麻煩不想輸入-m "xxx"行不行?確實有辦法能夠這麼幹,可是強烈不建議你這麼幹,由於輸入說明對本身對別人閱讀都很重要。

爲何Git添加文件須要addcommit一共兩步呢?由於commit能夠一次提交不少文件,因此你能夠屢次add不一樣的文件,好比:

$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

4. 代碼回滾

4.1代碼修改並提交  

咱們已經成功地添加並提交了一個first_git_file.txt文件,如今,是時候繼續工做了,因而,咱們繼續修改first_git_file.txt文件,改爲以下內容:

First time using git, excited! update ...
insert line here...
第一次用git哈哈

如今,運行git status命令看看結果:

$ 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:   first_git_file.txt
 
no changes added to commit (use "git add" and/or "git commit -a")

雖然Git告訴咱們first_git_file.txt被修改了,但若是能看看具體修改了什麼內容,天然是很好的。好比你休假兩週從國外回來,第一天上班時,已經記不清上次怎麼修改的readme.txt,因此,須要用git diff這個命令看看:

$ git diff first_git_file.txt
diff --git a/first_git_file.txt b/first_git_file.txt
index 2d13c2c..248d853 100644
--- a/first_git_file.txt
+++ b/first_git_file.txt
@@ -1,3 +1,4 @@
-first time using git, excited!
+First time using git, excited! update ...
 insert line here...
 第一次用git哈哈
+insert line again haha...

輸出中+號綠色顯示的就是修改或新增的內容,-號紅色顯示的就是去掉或被修改的內容

知道了對first_git_file.txt 做了什麼修改後,再把它提交到倉庫就放心多了,提交修改和提交新文件是同樣的兩步,第一步是git add

$ git add . # .  表明把當前目錄下全部改動的文件都提交到代碼庫
Alexs-MacBook-Pro:git_trainning alex$ git commit -m "commit changes"
[master 50ad6b5] commit changes
 Committer: Alex Li <alex@Alexs-MacBook-Pro.local>
 1 file changed, 1 insertion(+)

提交後,咱們再用git status命令看看倉庫的當前狀態:

$ git status
# On branch master
nothing to commit (working directory clean)

Git告訴咱們當前沒有須要提交的修改,並且,工做目錄是乾淨(working directory clean)的。 

4.2 代碼回滾

如今,你已經學會了修改文件,而後把修改提交到Git版本庫,如今,再練習一次,修改first_git_file.txtt文件以下: 

First time using git, excited! update ...
insert line here..改以前的.
第一次用git哈哈
insert line again haha...
加點新內容 

而後嘗試提交:


$ git add first_git_file.txt
$ git commit -m "add new content"
[master 4459657] add new content
 Committer: Alex Li <alex@Alexs-MacBook-Pro.local>
 1 file changed, 2 insertions(+), 1 deletion(-)

像這樣,你不斷對文件進行修改,而後不斷提交修改到版本庫裏,就比如玩RPG遊戲時,每經過一關就會自動把遊戲狀態存盤,若是某一關沒過去,你還能夠選擇讀取前一關的狀態。有些時候,在打Boss以前,你會手動存盤,以便萬一打Boss失敗了,能夠從最近的地方從新開始。Git也是同樣,每當你以爲文件修改到必定程度的時候,就能夠「保存一個快照」,這個快照在Git中被稱爲commit。一旦你把文件改亂了,或者誤刪了文件,還能夠從最近的一個commit恢復,而後繼續工做,而不是把幾個月的工做成果所有丟失。

如今,咱們回顧一下first_git_file.txt文件一共有幾個版本被提交到Git倉庫裏了: 

版本1
first time using git, excited!
第一次用git哈哈


版本2
first time using git, excited!
insert line here...
第一次用git哈哈


版本3
first time using git, excited!
insert line here...
第一次用git哈哈
insert line again haha...


版本4
First time using git, excited! update ...
insert line here..改以前的.
第一次用git哈哈
insert line again haha...
加點新內容

固然了,在實際工做中,咱們腦子裏怎麼可能記得一個幾千行的文件每次都改了什麼內容,否則要版本控制系統幹什麼。版本控制系統確定有某個命令能夠告訴咱們歷史記錄,在Git中,咱們用git log命令查看:

$ git log
commit 445965781d1fd0d91e76d120450dd18fd06c7489
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 18:44:29 2016 +0800
 
    add new content
 
commit be02137bb2f54bbef0c2e99202281b3966251952
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 17:55:16 2016 +0800
 
    update again
 
commit 50ad6b526810bb7ccfea430663757ba2337b9816
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 17:46:51 2016 +0800
 
    commit changes
 
commit 621e6e44d04fa6a1cdc37826f01efa61b451abd1
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 17:42:50 2016 +0800
 
    commit my first git file

git log命令顯示從最近到最遠的提交日誌,咱們能夠看到4次提交,最近的一次是add new content,上一次是update again,最先的一次是commit my first git file。 若是嫌輸出信息太多,看得眼花繚亂的,能夠試試加上--pretty=oneline參數:

$ git log --pretty=oneline
445965781d1fd0d91e76d120450dd18fd06c7489 add new content
be02137bb2f54bbef0c2e99202281b3966251952 update again
50ad6b526810bb7ccfea430663757ba2337b9816 commit changes
621e6e44d04fa6a1cdc37826f01efa61b451abd1 commit my first git file

 

須要友情提示的是,你看到的一大串相似3628164...882e1e0的是commit id(版本號),和SVN不同,Git的commit id不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個很是大的數字,用十六進制表示,並且你看到的commit id和個人確定不同,以你本身的爲準。爲何commit id須要用這麼一大串數字表示呢?由於Git是分佈式的版本控制系統,後面咱們還要研究多人在同一個版本庫裏工做,若是你們都用1,2,3……做爲版本號,那確定就衝突了。

回滾回滾回滾  

好了,如今咱們啓動時光穿梭機,準備把first_git_file.txt回退到上一個版本,也就是「update again」的那個版本,怎麼作呢?

首先,Git必須知道當前版本是哪一個版本,在Git中,用HEAD表示當前版本,也就是最新的提交be02137bb2f54bbef0c2e99202281b3966251952(注意個人提交ID和你的確定不同),上一個版本就是HEAD^,上上一個版本就是HEAD^^,固然往上100個版本寫100個^比較容易數不過來,因此寫成HEAD~100

如今,咱們要把當前版本「add new content」回退到上一個版本「update again」,就可使用git reset命令:

$ git reset --hard HEAD^

HEAD is now at be02137 update again
 
此時再看你的文件內容,果真就退回去了
more first_git_file.txt
First time using git, excited! update ...
insert line here...
第一次用git哈哈
insert line again haha...
 
此時還能夠繼續再往前回退一個版本,不過且慢,然咱們用 git log再看看如今版本庫的狀態:

$ git log --pretty=oneline

be02137bb2f54bbef0c2e99202281b3966251952 update again
50ad6b526810bb7ccfea430663757ba2337b9816 commit changes
621e6e44d04fa6a1cdc37826f01efa61b451abd1 commit my first git file
 

最新的那個版本add new content已經看不到了!比如你從21世紀坐時光穿梭機來到了19世紀,想再回去已經回不去了,腫麼辦?

辦法其實仍是有的,只要上面的命令行窗口尚未被關掉,你就能夠順着往上找啊找啊,找到那個add new content的commit id是445965781d1fd0d91e76d120450dd18fd06c7489

,因而就能夠指定回到將來的某個版本:

git reset --hard 4459657

HEAD is now at 4459657 add new content

 

版本號不必寫全,前幾位就能夠了,Git會自動去找。固然也不能只寫前一兩位,由於Git可能會找到多個版本號,就沒法肯定是哪個了。

再當心翼翼地看看first_git_file.txt的內容:

First time using git, excited! update ...

insert line here..改以前的.
第一次用git哈哈
insert line again haha...
加點新內容
 

果真,我胡漢三又回來了。

Git的版本回退速度很是快,由於Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從指向add new content

 

如今,你回退到了某個版本,關掉了電腦,次日早上就後悔了,想恢復到新版本怎麼辦?找不到新版本的commit id怎麼辦?

在Git中,老是有後悔藥能夠吃的。當你用$ git reset --hard HEAD^回退到update again版本時,再想恢復到最新add new content的版本,就必須找到add new contentL的commit id。Git提供了一個命令git reflog用來記錄你的每一次命令:

$ git reflog

4459657 HEAD@{0}: reset: moving to 4459657
be02137 HEAD@{1}: reset: moving to HEAD^
4459657 HEAD@{2}: commit: add new content
be02137 HEAD@{3}: reset: moving to be02137bb
50ad6b5 HEAD@{4}: reset: moving to 50ad6b5
621e6e4 HEAD@{5}: reset: moving to 621e6e44
50ad6b5 HEAD@{6}: reset: moving to HEAD^
be02137 HEAD@{7}: commit: update again
50ad6b5 HEAD@{8}: commit: commit changes
621e6e4 HEAD@{9}: commit (initial): commit my first git file

終於舒了口氣,第二行顯示add new content的commit id是4459657,如今,你又能夠乘坐時光機回到將來了。

5. 工做區和暫存區

Git和其餘版本控制系統如SVN的一個不一樣之處就是有暫存區的概念。

先來看名詞解釋。

工做區(Working Directory

就是你在電腦裏能看到的目錄,好比個人git_trainning文件夾就是一個工做區:

$ ls git_trainning/
first_git_file.txt

版本庫(Repository)

工做區有一個隱藏目錄.git,這個不算工做區,而是Git的版本庫。

Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫HEAD

分支和HEAD的概念咱們之後再講。

前面講了咱們把文件往Git版本庫裏添加的時候,是分兩步執行的:

第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;

第二步是用git commit提交更改,實際上就是把暫存區的全部內容提交到當前分支。

由於咱們建立Git版本庫時,Git自動爲咱們建立了惟一一個master分支,因此,如今,git commit就是往master分支上提交更改。

你能夠簡單理解爲,須要提交的文件修改統統放到暫存區,而後,一次性提交暫存區的全部修改。

俗話說,實踐出真知。如今,咱們再練習一遍,先對first_git_file.txt作個修改,好比加上一行內容:

  First time using git, excited! update ...

  insert line here..改以前的.
  第一次用git哈哈
  insert line again haha...
  加點新內容
  update v5

而後,在工做區新增一個readme.md文本文件(內容隨便寫)。

先用git status查看一下狀態:

$ 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:   first_git_file.txt
 
Untracked files:
  (use "git add <file>..." to include in what will be committed)
 
    readme.md
 
no changes added to commit (use "git add" and/or "git commit -a")

Git很是清楚地告訴咱們,first_git_file.txt被修改了,而readme.md還歷來沒有被添加過,因此它的狀態是Untracked

如今,使用命令git add . ,再用git status再查看一下:

$ git add .
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    modified:   first_git_file.txt
    new file:   readme.md
</file>

如今,暫存區的狀態就變成這樣了:

(盜圖關係, 這裏readme.txt = first_git_file.txt , LICENSE = readme.md)

因此,git add命令實際上就是把要提交的全部修改放到暫存區(Stage),而後,執行git commit就能夠一次性把暫存區的全部修改提交到分支。

$ git commit -m "知道暫存區stage的意思了"

[master 9d65cb2] 知道暫存區stage的意思了
 2 files changed, 2 insertions(+)
 create mode 100644 readme.md

一旦提交後,若是你又沒有對工做區作任何修改,那麼工做區就是「乾淨」的:

$ git status

On branch master
nothing to commit, working directory clean

如今版本庫變成了這樣,暫存區就沒有任何內容了:

(盜圖關係, 這裏readme.txt = first_git_file.txt , LICENSE = readme.md)

 暫存區是Git很是重要的概念,弄明白了暫存區,就弄明白了Git的不少操做到底幹了什麼。

 

6. 撤銷修改  

天然,你是不會犯錯的。不過如今是凌晨兩點,你正在趕一份工做報告,你在readme.md中添加了一行:

#git study repo

git is great
but my stupid boss still prefers SVN.

在你準備提交前,一杯咖啡起了做用,你猛然發現了「stupid boss」可能會讓你丟掉這個月的獎金!

既然錯誤發現得很及時,就能夠很容易地糾正它。你能夠刪掉最後一行,手動把文件恢復到上一個版本的狀態。若是用git status查看一下:

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.md
 
no changes added to commit (use "git add" and/or "git commit -a")
</file></file>
你能夠發現,Git會告訴你, git checkout -- file能夠丟棄工做區的修改:
$ git checkout -- readme.md
 
more readme.md
#git study repo

你剛纔添加的2行罵老闆的話就被撤銷了,

命令git checkout -- readme.md意思就是,把readme.md文件在工做區的修改所有撤銷,這裏有兩種狀況:

一種是readme.md自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態;

一種是readme.md已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。

總之,就是讓這個文件回到最近一次git commitgit add時的狀態。

git checkout -- file命令中的--很重要,沒有--,就變成了「切換到另外一個分支」的命令,咱們在後面的分支管理中會再次遇到git checkout命令。  

如今假定是凌晨3點,你不但寫了一些胡話,還git add到暫存區了:

$ cat readme.md
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
My stupid boss still prefers SVN.
 
$ git add readme.md

慶幸的是,在commit以前,你發現了這個問題。用git status查看一下,修改只是添加到了暫存區,尚未提交: 

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    modified:   readme.md
</file>

Git一樣告訴咱們,用命令git reset HEAD file能夠把暫存區的修改撤銷掉(unstage),從新放回工做區:
$ git reset HEAD readme.md Unstaged changes after reset: M readme.md
git reset命令既能夠回退版本,也能夠把暫存區的修改回退到工做區。當咱們用HEAD時,表示最新的版本。 再用git status查看一下,如今暫存區是乾淨的,工做區有修改
$ 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.md # no changes added to commit (use "git add" and/or "git commit -a")
還記得如何丟棄工做區的修改嗎?
$ git checkout -- readme.md $ more readme.md #git study repo 整個世界終於清靜了!

 

7. 刪除操做

在Git中,刪除也是一個修改操做,咱們實戰一下,先添加一個新文件test.txt到Git而且提交:  

$ git add .
$ git commit -m "add test.txt"
[master a8fa95a] add test.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test.txt

通常狀況下,你一般直接在文件管理器中把沒用的文件刪了,或者用rm命令刪了:rm test.txt

這個時候,Git知道你刪除了文件,所以,工做區和版本庫就不一致了,git status命令會馬上告訴你哪些文件被刪除了:

$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
 
    deleted:    test.txt
 
no changes added to commit (use "git add" and/or "git commit -a")

如今你有兩個選擇,一是確實要從版本庫中刪除該文件,那就用命令git rm刪掉,而且git commit

x$ git rm test.txt
rm 'test.txt'
 
$ git commit -m "remove test"
[master 03df00a] remove test
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 test.txt

如今,文件就從版本庫中被刪除了。

另外一種狀況是刪錯了,由於版本庫裏還有呢,因此能夠很輕鬆地把誤刪的文件恢復到最新版本:$ git checkout -- test.txt

git checkout實際上是用版本庫裏的版本替換工做區的版本,不管工做區是修改仍是刪除,均可以「一鍵還原」。

 

 

文章太長爲了方便閱讀請看:

git &github 快速入門(下)

相關文章
相關標籤/搜索