目錄
一、git是什麼?
1,git與github
2,分布式與集中式
二、安裝、設定賬号、設定ssh
1、安裝、設定賬号
2,設定ssh
三、建立版本庫及送出檔案
1,建立版本庫
2,添加檔案到版本庫
四,常用指令彙總
五、git的時光穿梭機
1,版本回退
2,工作區和暫存區
3,管理修改
4,撤銷修改
5,删除檔案
部落客之前有些svn的學習筆記,與svn相對,git是一個更為流行的版本管理工具。
一、git是什麼?
1,git與github
Git是目前世界上最先進的分布式版本控制系統(沒有之一)。
Linus在1991年建立了開源的Linux,然後全世界有n多人送出代碼給Linus,Linus是如何管理這些代碼?事實是,在2002年以前,世界各地的志願者把源代碼檔案通過diff的方式發給Linus,然後由Linus本人通過手工方式合并代碼!那麼他為什麼不用cvs、svn之類的版本管理工具?因為速度慢,而且要聯網才能使用!
之後Linus采用了一段時間商業的版本控制系統BitKeeper,但是搞Linux的畢竟牛人衆多,有許多黑客嘗試破解這個版本管理工具,BitMover知道後,怒了!然後收回了Linux免費使用BitKeeper的權利。
但是黑客怎麼會受制于人!Linus花了兩周時間自己用C寫了一個分布式版本控制系統,這就是Git!一個月之内,Linux系統的源碼已經由Git管理了!是以,對于黑客(想成為進階工程師的人)不是自己去适應機器,而是讓機器适應你!沒有軟體,自己弄一個。
Git迅速成為最流行的分布式版本控制系統,尤其是2008年,GitHub網站上線了,它為開源項目免費提供Git存儲,無數開源項目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。至于github嗎,全球最大的搞G網站:
2,分布式與集中式
分布式與集中式的差別在于其管理方式,集中式:
分布式:
看出了差別嗎,分布式每一個節點都可以做倉庫,而集中式則隻有伺服器可以做倉庫!确定和優點是不是顯而易見?
包括微軟、IBM他們也有開發版本管理工具,但是呢,效率低而且不好用!是以開源軟體真是又好用又不用花費,開源才是提升技術的最好途徑!
二、安裝、設定賬号、設定ssh
1、安裝、設定賬号
windows安裝git,從官網下載下傳git程式,安裝好之後就有git bash
進入git bash後修改使用者及email:
$ git config --global user.name "Your Name"
$ git config --global user.email [email protected]
因為git是分布式版本控制系統,是以每台機器需要自保家門。注意
git config
指令的
--global
參數,用了這個參數,表示你這台機器上所有的Git倉庫都會使用這個配置,當然也可以針對某個倉庫設定username和email。
2,設定ssh
打開git bash,在控制台中輸入以下指令:
ssh-keygen -t rsa -C "郵箱"
密鑰類型可以用 -t 選項指定。如果沒有指定則預設生成用于SSH-2的RSA密鑰。這裡使用的是rsa。
同時在密鑰中有一個注釋字段,用-C來指定所指定的注釋,可以友善使用者辨別這個密鑰,指出密鑰的用途或其他有用的資訊。是以在這裡輸入自己的郵箱或者其他都行。
輸入完畢後程式同時要求輸入一個密語字元串(passphrase),空表示沒有密語。接着會讓輸入2次密碼(password),空表示沒有密碼。3次回車即可完成目前步驟,此時
[c盤>使用者>自己的使用者名>.ssh]
目錄下已經生成好了。
根據生成的位址,直接在git bash中cat檢視
登入github。打開setting->SSH keys,點選右上角 New SSH key,把生成好的公鑰
id_rsa.pub
放進 key輸入框中,再為目前的key起一個title來區分每個key。
3,出現一個Enter passphrase for key '/e/Gitspace/.ssh/id_rsa': 提示
出現這個提示時,直接輸入密碼之後就可以連接配接到自己的倉庫。
三、建立版本庫及送出檔案
1,建立版本庫
什麼是版本庫?版本庫又名倉庫,英文名repository,你可以簡單了解成一個目錄,這個目錄裡面的所有檔案都可以被Git管理起來,每個檔案的修改、删除,Git都能跟蹤,以便任何時刻都可以追蹤曆史,或者在将來某個時刻可以“還原”。
建立一個test1倉庫:
顯示建立一個test1的目錄,然後init成一個倉庫。在這個目錄下有一個.git目錄:
這個.git目錄是用來跟蹤版本的,沒事别動它。
2,添加檔案到版本庫
當把檔案添加到版本庫時,有幾個注意事項:
(1)Microsoft的Word格式是二進制格式,是以,版本控制系統是沒法跟蹤Word檔案的改動的,前面我們舉的例子隻是為了示範,如果要真正使用版本控制系統,就要以純文字方式編寫檔案。另外純文字建議采用utf-8,既沒有沖突,又被所有平台所支援。(嘿嘿,部落客有篇部落格也記了下各種編碼格式間的差別,可以看看什麼utf-8、utf-16之類的差別,最好用的就是utf-8咯);
(2)Windows下編輯文本特别注意一點:千萬不要使用Windows自帶的記事本編輯任何文本檔案!原因是Microsoft開發記事本的團隊使用了一個非常弱智的行為來儲存UTF-8編碼的檔案,他們自作聰明地在每個檔案開頭添加了0xefbbbf(十六進制)的字元,你會遇到很多不可思議的問題。是以嘛,可以用notepad、ue、sublime之類的編輯器。
我們編寫一個readme.txt檔案:
在sublime中打開并輸入:
Git is a version control system.
Git is free software.
設定以utf-8方式打開。
把一個檔案放入git倉庫分兩步:
(1)git add read
$ git add readme.txt
沒有任何顯示!這就是添加成功的意思
(2)git commit
git commit -m "a readme file"
-m 後面跟的就是送出說明的咯。
四,常用指令彙總
會添加檔案了之後,我們先來大概看一下可以使用的指令如下,有個概念即可:
五、git的時光穿梭機
修改readme檔案:
Git is a distributed version control system.
Git is free software.
輸入:git status
git status
指令可以讓我們時刻掌握倉庫目前的狀态,上面的指令輸出告訴我們,
readme.txt
被修改過了,但還沒有準備送出的修改。
想看一下具體修改了哪些地方:
git diff readme.txt
按照學習linux的方式,部落客還是很喜歡一行一行的看
diff --git a/readme.txt b/readme.txt
第一部分表示使用的git格式的diff
index d8036c1..013b5bc 100644
第二部分表示兩個版本的git哈希值(index區域的d8036c1對象,與工作目錄區域的013b5bc對象進行比較),最後的六位數字是對象的模式(普通檔案,644權限)。
--- a/readme.txt
+++ b/readme.txt
第三部分表示進行比較的兩個檔案,"---"表示變動前的版本,"+++"表示變動後的版本。
@@ -1,2 +1,2 @@
前面的"-1,2"分成三個部分:減号表示第一個檔案(即index區域的d29ab50對象),"1"表示第1行,"2"表示連續2行。合在一起,就表示下面是第一個檔案從第1行開始的連續3行。同樣的,"1,2"表示變動後,成為第二個檔案從第1行開始的連續2行。(我了解的-指變動前,+指變動後)
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.
\ No newline at end of file
最後一部分是具體的差異部分
知道做出了什麼修改之後,就可以放心地git add了。
執行完git add之後再執行git status:
git status
告訴我們,将要被送出的修改包括
readme.txt
然後送出:
git commit -m 'my test'
再調用git status:
Git告訴我們目前沒有需要送出的修改,而且,工作目錄是幹淨(working tree clean)的。
1,版本回退
再來修改一次readme:
Git is a distributed version control system.
Git is free software distributed under the GPL.
add、commit。
至此為止我們修改了兩次,有三個版本的readme。我們要如何檢視這些記錄呢?
git log 檢視git曆史記錄:
git log
指令顯示從最近到最遠的送出日志,我們可以看到3次送出,最近的一次是
append GPL
,上一次是
add distributed
,最早的一次是
wrote a readme file
。但是這些資訊是不是太多了,才一個檔案的修改就這麼多記錄。
我們可以采用
--pretty=oneline
參數來減少輸出資訊
資訊就簡介了很多,但是也能看到各個曆史操作。也可以改成:git log --pretty=oneline readme.txt檢視單個檔案。
注意一下這一串東西:be459e9f3da1583d15c2c0f85effa8fa768114c1和svn送出不太一樣,svn的commit id是1、2、3之類的,git的commit id 是一個SHA1計算出來的一個非常大的數字,用十六進制表示。為啥git的commit id如此複雜?因為git是一個分布式版本管理工具,如果采用1、2、3作為commit id,那肯定很容易發生沖突。
好了,現在我想把版本回退到 my test,要怎麼做?使用git reset 指令!
git reset --hard HEAD^
這樣就會退了一個版本:
這下麻煩了,要怎麼回到 append GL?
$ git reset --hard be459
HEAD is now at be459e9 append GL
這樣又可以了!版本号沒必要寫全,前幾位就可以了,Git會自動去找。當然也不能隻寫前一兩位,因為Git可能會找到多個版本号,就無法确定是哪一個了。
git的版本回退速度非常快,因為Git在内部有個指向目前版本的
HEAD
指針,當你回退版本的時候,Git僅僅是把HEAD從指向
append GPL
:
回到剛剛回退到GL的代碼,如果我不知道commit id,腫麼辦!我要怎麼回到最初:
Git提供了一個指令
git reflog
用來記錄你的每一次指令:
be459e9 (HEAD -> master) [email protected]{2}: commit: append GL
是以找到了append GL的commit id為:be459e9
2,工作區和暫存區
工作區就是你在電腦裡能看到的目錄;工作區裡有一個.git,這個不算工作區,而是git的版本庫。
Git的版本庫裡存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區,還有Git為我們自動建立的第一個分支
master
,以及指向
master
的一個指針叫
HEAD
。
前面把檔案加入到git倉庫的兩步,第一步是用
git add
把檔案添加進去,實際上就是把檔案修改添加到暫存區;第二步是用
git commit
送出更改,實際上就是把暫存區的所有内容送出到目前分支。可以了解成,先把需要送出的内容放在暫存區,然後通過commit送出所有内容。Git自動為我們建立了唯一一個
master
分支,是以,現在,
git commit
就是往
master
分支上送出更改。
再來加深一下對緩存區的認識。
修改readme:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
建立一個檔案LICENSE
調用git status :
Git非常清楚地告訴我們,
readme.txt
被修改了,而
LICENSE
還從來沒有被添加過,是以它的狀态是
Untracked
。
使用兩次指令
git add
,把
readme.txt
和
LICENSE
都添加後,用
git status
再檢視一下:
3,管理修改
為什麼git比其他版本管理工具更優秀?
因為Git跟蹤并管理的是修改,而非檔案。為什麼說git跟蹤的事修改?接下來我們來做個試驗證明。首先将三行的readme增加一行:
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.
然後添加:
然後,再修改readme
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git has a mutable index called stage.
Git tracks changes of files.
此時先送出再git status檢視git 狀态:
第二次的修改并沒有送出!因為這個送出的工作是這樣的:Git管理的是修改,當你用
git add
指令後,在工作區的第一次修改被放入暫存區,準備送出,但是,在工作區的第二次修改并沒有放入暫存區,是以,
git commit
隻負責把暫存區的修改送出了,也就是第一次的修改被送出了,第二次的修改不會被送出。
送出之後,我們用git diff HEAD -- readme.txt 檢視工作區和版本庫裡面最新版本
可見,第二次修改是沒有送出的,還是4行!
4,撤銷修改
承上例,
git checkout -- file
可以丢棄工作區的修改
5 line的修改是沒有上傳到緩存區此時我使用$ git checkout -- readme.txt
則有如下效果:
它回到了4行!它回到的是暫存區的狀态還是送出到版本庫的狀态?
指令
git checkout -- readme.txt
意思就是,把
readme.txt
檔案在工作區的修改全部撤銷,這裡有兩種情況:
一種是
readme.txt
自修改後還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀态;
一種是
readme.txt
已經添加到暫存區後,又作了修改,現在,撤銷修改就回到添加到暫存區後的狀态。
在這個示例中,它是回到了暫存區的狀态。
實際上這個checkout回到的是最近的add或commit狀态。
如果我add了之後,想回到沒有add之前呢?目前readme有四行資料:
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.
加一行,然後add:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git has a mutable index called stage.
Git tracks changes of files.
此時要采用git reset HEAD <file> 指令,可以把暫存區的修改撤銷掉(unstage),重新放回工作區:
git reset HEAD readme.txt
為什麼檔案裡還是由5行?!
因為這一步是清理了緩存區,接下來,還是要通過checkout修改
先git status看下狀态
如果是add的話,這裡是綠色的,說明取消了add。
$ git checkout -- readme.txt
這樣就可以了!
5,删除檔案
首先添加一個 test.txt:
之後我們删除掉這個檔案:
rm test.txt
工作區确實沒有了
檢視git 狀态:
緩存區沒有相應修改,是以需要用指令
git rm
删掉,并且
git commit
檢視一下git 狀态:
标綠說明,緩存區已進行了修改。
如果是誤删,但是緩存區裡還有,可以通過git --checkout test.txt 進行恢複。
參考:廖雪峰的部落格https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013745374151782eb658c5a5ca454eaa451661275886c6000