版本控制主要分爲兩種,集中式版本控制和分佈式版本控制。CVS和SVN即便典型的集中式版本控制系統,而Git是目前世界上最早進的分佈式版本控制系統。 git
集中式版本控制:windows
集中式版本控制的倉庫是集中存放在中央服務器的,而幹活的時候,用的都是本身的電腦,因此要先從中央服務器取得最新的版本,而後開始幹活,幹完活了,再把本身的活推送給中央服務器。集中式版本控制系統最大的弊端就是必須聯網才能工做。在局域網的狀況下效率不錯,可是經過外放訪問的話,因爲網絡帶寬和穩定性的因素將致使效率極低。安全
分佈式版本控制:bash
分佈式版本控制系統沒有「中央服務器」的概念,每一個人的電腦上都是一個完整的版本庫,這樣,你工做的時候,就不須要聯網了,由於版本庫就在你本身的電腦上。既然每一個人電腦上都有一個完整的版本庫,那多我的如何協做呢?比方說你在本身電腦上改了文件A,你的同事也在他的電腦上改了文件A,這時,大家倆之間只需把各自的修改推送給對方,就能夠互相看到對方的修改了。服務器
和集中式版本控制系統相比,分佈式版本控制系統的安全性要高不少,由於每一個人電腦裏都有完整的版本庫,某一我的的電腦壞掉了沒關係,隨便從其餘人那裏複製一個就能夠了。網絡
簡介:分佈式
Git 是用於 Linux內核開發的版本控制工具。與經常使用的版本控制工具 CVS, Subversion 等不一樣,它採用了分佈式版本庫的方式,沒必要服務器端軟件支持,使源代碼的發佈和交流極其方便。 Git 的速度很快,這對於諸如 Linux kernel 這樣的大項目來講天然很重要。 Git最爲出色的是它的合併跟蹤(merge tracing)能力。工具
簡介:學習
Git 是用於 Linux內核開發的版本控制工具。與經常使用的版本控制工具 CVS, Subversion 等不一樣,它採用了分佈式版本庫的方式,沒必要服務器端軟件支持,使源代碼的發佈和交流極其方便。 Git 的速度很快,這對於諸如 Linux kernel 這樣的大項目來講天然很重要。 Git最爲出色的是它的合併跟蹤(merge tracing)能力。spa
Git bash
Git Bash是Git在windows下的一個模擬終端,接下來的Git的學習都將在此終端進行。雙擊桌面的Git Bash圖 標,便可打開Git終端。
由於Git是分佈式版本控制系統,因此,每一個機器都必須自報家門。你的名字和Email地址。在Git Bash中輸入如下命令:
在Git的全局配置中添加一個用戶名
在Git的全局配置中添加一個郵箱
3)可使用git config --list查看全局的配置信息,當中能夠看到你所添加的用戶名和郵箱信息
建立完用戶信息以後,接下來咱們就能夠開始建立一個本地的版本庫了。
1)在任意一個磁盤中新建一個目錄,例如:在D盤中建立一個文件夾叫mygit。
2)在Git Bash中進入此文件夾。
3)使用git init命令將mygit目錄初始化一個空的本地版本庫
OK,這樣咱們就建立了一個本地版本庫,只不過這個庫的工做區中沒有任何的內容,
可是有一個隱藏文件夾「.git」。這個文件夾就是Git的版本庫。
(備註:在Git中是有版本庫、工做區、暫存區這幾個概念,這部份內容將在後面進行詳細介紹)
版本庫有了,那麼咱們就能夠向版本庫中添加文件了。
1) 在mygit目錄中建立一個文本文件(例如hello.txt)並填寫一些內容
2)在Git Bash中使用命令git add hello.txt
3)再使用命令git commit -m "提交說明" 提交到版本庫中
接下來對hello.txt文件進行修改,再添加一些內容。而後使用git status命令進行查看。git status命令可讓咱們時刻關注倉庫當前的狀態。
紅色的部分告訴咱們hello.txt的文件已經修改,可是尚未提交到倉庫。
還可使用git diff命令查看修改前和修改後的內容。
修改完後仍是使用git add和git commit命令提交到本地版本庫中。
咱們再次使用git status命令查看版本庫當前的狀態,這時你會發現剛纔修改的內容已經提交到版本庫中,沒有任何可提交的內容了。
工做區(Working Directory)
在以前建立的mygit目錄,這個就是工做區。咱們建立的任何文件都是存放在工做區中。
版本庫(Repository)
工做區有一個隱藏目錄「.git」,這個就是Git的本地版本庫。
說明:
Git的版本庫裏存了不少內容,其中最重要的就一個是暫存區(stage),還有Git爲咱們自動建立的第一個主分支master,以及指向master的一個指針叫HEAD(HEAD還能夠指向其餘的分支,就是切換分支)。
咱們把文件往Git版本庫裏添加的時候,是分兩步執行的:
第一步是用git add把文件添加進去,實際上就是把新建或修改的文件添加到暫存區。
第二步是用git commit執行提交,實際上就是把暫存區的全部內容提交到當前master分支。
1) 可使用git log命令查看最近的提交日誌列表,當初會有相應的版本號、用戶信息、提交時間和提交說明等內容。
說明:
commit:提交的版本號
Author:提交人信息
Date:提交時間
再後面的信息就是提交說明
2)使用git reset 命令執行版本回退
reset命令有三個參數,這三個參數將致使回退的內容將在不一樣的做用域中。
--soft,這個參數表示在版本庫中回退到舊的版本。而最新的版本內容會移到暫存區保存。($ git reset --soft HEAD^soft 綠色,(工做區有,版本庫沒有)暫存區還有,只須要commit)
--mixed, 這個參數表示在版本庫中進行版本回退,同時重置暫存區。(默認選項)
($ git reset --mixed HEAD^mixed 紅色,(存在於工做區,版本庫也沒有)暫存區沒有,而且要先add在commit)
--hard,這個參數表示表示在版本庫中進行版本回退,同時重置暫存區和工做區。
例如:git reset --soft HEAD^ 表示在版本庫中回退到上一個版本
($ git reset --hard HEAD^hard (工做區、暫存區、和版本庫都沒有)清空全部)
HEAD說明:
1) HEAD表示回退到當前最新版本
例如:git reset --mixed HEAD (回退到當前最新的版本,並重置暫存區)
2) HEAD^表示回退到上一個版本
例如:git reset --mixed HEAD^ (回退到上一個版本,並重置暫存區)
3) HEAD~2表示回退到上兩個版本(其中2能夠替換成其餘數字,表示回退到第幾個版本)
例如:git reset --mixed HEAD~2 (回退到上兩個版本,並重置暫存區)
版本號說明:
能夠將HEAD替換成版本號,表示回退到指定的版本。版本號不必定須要所有輸入,只須要輸入前面幾個字符便可。
例如:git reset --mixed 版本號 (回退到指定版本,並將版本內容重置到暫存區)
3)使用git reset <filename>命令撤銷暫存區的操做
例如:git reset hello.txt
1) 使用git rm filename命令刪除工做區中的文件
例如:git rm hello.txt
注意:刪除以後,記得要將此操做commit到版本庫中,由於此時刪除的動做還只是在暫存區中,並未同步到版本庫。
2) 使用git rm 目錄名 -r -f 刪除文件夾及其下全部的文件
例如:git rm demo -r -f
注意:執行完一樣須要commit到版本庫中
1)分支的做用
分支在實際中有什麼用呢?假設你準備開發一個新功能,可是須要兩週才能完成,第一週你寫了50%的代碼,若是馬上提交,因爲代碼還沒寫完,不完整的代碼庫會致使別人不能幹活了。若是等代碼所有寫完再一次提交,又存在丟失天天進度的巨大風險。有了分支,就不用怕了。你建立了一個屬於你本身的分支,別人看不到,還繼續在原來的分支上正常工做,而你在本身的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的主分支上,這樣,既安全,又不影響別人工做。
2) 分支的概念
每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在Git裏,這個分支叫主分支,即master分支。HEAD嚴格來講不是指向提交,而是指向master,master纔是指向提交的,因此,HEAD指向的就是當前分支。
每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也愈來愈長:
當咱們建立新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:
從如今開始,對工做區的修改和提交就是針對dev分支了,好比新提交一次後,dev指針往前移動一步,而master指針不變:
假如咱們在dev上的工做完成了,就能夠把dev合併到master上。Git怎麼合併呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合併:
合併完分支後,甚至能夠刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉後,咱們就剩下了一條master分支:
1. 建立分支: git branch 分支名
例如:git branch dev
2. 切換分支: git checkout 分支名
例如: git checkout dev
說明:也可使用 git branch dev -b 一次1和2的兩步操做(建立並切換分支)
3. 查看分支: git branch
說明:*號表標識前正在操做的分支
4. 合併分支:git merge 分支名
例如:git meger dev
咱們先切換到master分之下,而後合併dev分支的內容
這樣,咱們就把dev分支的內容合併到了master分支上
5. 刪除分支:git branch -d 分支名
例如:git branch -d dev
版本衝突
在合併分支時,並不必定都成功。這是由於當兩個分支都作了修改而且都提交到了版本庫中,這樣在合併的時候可能就會產生版本衝突。
場景案例:
1) 在master主分支中對A文件進行修改並提交
2)切換到dev分支也對A文件進行內容修改並提交
3)切換回master分支合併dev分支的內容,這是就產生版本衝突,合併失敗
由於master分支和dev分支各自都分別有新的提交。這種狀況下,Git沒法執行「快速合併」,只能試圖把各自的修改合併起來,但這種合併就致使了衝突的緣由。
咱們查看文件內容,Git用<<<<<<<,=======,>>>>>>>標記出不一樣分支的內容。
所以咱們手動將內容修改合併後再進行提交以解決此問題。
git diff 用於比較內容的差異。
比較規則:
先比較暫存區內容,若是暫存區爲空時則比較當前版本庫中HEAD所指向的分支內容。
例如:git diff
說明:git diff 默認是比較全部文件的內容。也能夠指定文件名,用於比較當前文件的內容。例如:git diff hello.txt
例如: git diff 分支名
說明:一樣能夠指定具體某個文件進行內容比。例如:git diff dev hello.txt
例如:git diff 分支名..分支名
說明:一樣能夠指定具體某個文件進行內容比。例如:git diff master..dev hello.txt
例如:git diff HEAD^
說明:還能夠比較上n個版的內容。例如:git diff HEAD~2 (比較上兩個版本的內容)。
而且能夠指定文件名,比較個某個文件內容。例如:git diff HEAD~2 hello.txt
說明:也能夠比較上n個版的內容和比較個指定文件的內容。同上
有這樣一種狀況,例如你在主分支master下進行一些代碼的內容修改,忽然因爲緊急突發緣由不得不讓你立馬切換至dev分之下進行一些bug修復。可是當你要切換到dev分支時,不得不先提交master下的內容,不然沒法進行切換。以下圖:
這時,能夠利用git來幫咱們先保存master分之下的工做狀態,而後就能夠安心切換到dev分之下進行工做,等完成以後再切換回master分支,而後再恢復回以前的工做狀態繼續工做。
這個命令就是 git stash
1)保存當前工做狀態: git stash
保存後,就能夠切換到其餘分支
在其餘分支工做完後,再切換回master分支。
2)查看保存的工做狀態列表:git stash list
說明:{0}是保存的狀態號
3)恢復狀態:git stash pop stash@{狀態號}
例如:git stash pop stash@{0}
這樣,就成功恢復到以前保存的狀態中。
發佈一個版本時,咱們一般先在版本庫中打一個標籤(tag),這樣,就惟一肯定了打標籤時刻的版本。未來不管何時,取某個標籤的版本,就是把那個打標籤的時刻的歷史版本取出來。因此,標籤也是版本庫的一個快照。
Git的標籤雖然是版本庫的快照,但其實它就是指向某個commit的指針,因此,建立和刪除標籤都是瞬間完成的。
當咱們要對某個版本進行打包發佈時,要找到對應的版本號(也就是commit ID),可是
版本號是一串並很差記的字符串。如:63c4b0c15f897ab4b1c50519f2946af7c5545e8e
這樣的字符串,這時標籤就很是有用了。由於標籤是一個很容易記的名字,一個標籤跟一個版本號是綁定在一塊兒的,因此只要根據標籤查找版本號就能夠了。
1)建立標籤:git tag 標籤名
例如:git tag v1.0
說明:默認標籤是打在最新提交的版本號上的,也能夠打在指定的版本號上。例如:
git tag v1.0 63c4b0c (只要寫上版本號的前幾位便可)
2)查看全部標籤:git tag
3)根據標籤查看版本內容:git show 標籤名
例如:git show v1.0
4)刪除標籤:git tag -d 標籤名
例如:git tag -d v1.0