Git 是一個分佈式版本控制工具,它的做者 Linus Torvalds 是這樣給咱們介紹 Git —— The stupid content tracker(傻瓜式的內容跟蹤器)git
關於 Git 的產生背景在此不作講解,有興趣的能夠搜索一下。vim
先介紹一下 Git 的特色,主要有兩大特色:bash
版本控制:能夠解決多人同時開發的代碼問題,也能夠解決找回歷史代碼的問題。服務器
分 布 式:Git是分佈式版本控制系統,同一個Git倉庫,能夠分佈到不一樣的機器上。首先找一臺電腦充當服務器的角色,天天24小時開機,其餘每一個人都從這個「服務器」倉庫克隆一份到本身的電腦上,而且各自把各自的提交推送到服務器倉庫裏,也從服務器倉庫中拉取別人的提交。能夠本身搭建這臺服務器,也可使用GitHub網站。分佈式
[root@kai ~]# yum install git -y [root@kai ~]# git --version git version 1.8.3.1
新建一個目錄git_test,在git_test目錄下建立一個版本庫,命令以下:ide
[root@kai ~]# mkdir git_test [root@kai ~]# cd git_test/ [root@kai git_test]# ll -a total 0 drwxr-xr-x 2 root root 6 Mar 13 21:43 . dr-xr-x---. 5 root root 228 Mar 13 21:43 .. [root@kai git_test]# git init Initialized empty Git repository in /root/git_test/.git/ [root@kai git_test]# ll -a total 0 drwxr-xr-x 3 root root 18 Mar 13 21:44 . dr-xr-x---. 5 root root 228 Mar 13 21:43 .. drwxr-xr-x 7 root root 119 Mar 13 21:44 .git
能夠看到在git_test目錄下建立了一個.git隱藏目錄,這就是版本庫目錄。工具
在git_test目錄下建立一個文件code.txt,編輯內容以下:網站
[root@kai git_test]# vim code.txt
[root@kai git_test]# cat code.txt
this is the first line
使用以下兩條命令能夠建立一個版本:this
[root@kai git_test]# git commit -m 'version1'
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: unable to auto-detect email address (got 'root@kai.(none)')
# 出現該錯誤緣由是咱們沒有配置git庫的用戶名與郵箱,按提示建立便可。
[root@kai git_test]# git config --global user.email "kai@qq.com"
[root@kai git_test]# git config --global user.name "kai"
# 再次提交
[root@kai git_test]# git commit -m 'version1'
[master (root-commit) 020bf02] version1
1 file changed, 1 insertion(+)
create mode 100644 code.txt
使用以下命令能夠查看版本記錄:spa
[root@kai git_test]# git log commit 020bf021ec6d1b77836db4e96541d3659251714e Author: kai <kai@qq.com> Date: Wed Mar 13 21:57:42 2019 -0400 version1
繼續編輯code.txt,在裏面再增長一行:
[root@kai git_test]# vim code.txt
[root@kai git_test]# cat code.txt
this is the first line
this is the second line
使用以下命令再建立一個版本並查看版本記錄:
[root@kai git_test]# git add code.txt [root@kai git_test]# git commit -m 'version2' [master 6280fa5] version2 1 file changed, 1 insertion(+) [root@kai git_test]# git log commit 6280fa584403809ac2078a81120acf33e6bec836 Author: kai <kai@qq.com> Date: Thu Mar 14 00:58:35 2019 -0400 version2 commit 020bf021ec6d1b77836db4e96541d3659251714e Author: kai <kai@qq.com> Date: Wed Mar 13 21:57:42 2019 -0400 version1 [root@kai git_test]#
如今若想回到某一個版本,可使用命令:git reset --hard HEAD^。HEAD 表示當前版本,HEAD^ 表示上一個版本,HEAD^^ 表示上上個版本。也可使用另外一種表示方式:HEAD~n 表示前n個版本。
如今若以爲想回到版本1,可使用以下命令:
[root@kai git_test]# git reset --hard HEAD^ HEAD is now at 020bf02 version1 [root@kai git_test]# git log commit 020bf021ec6d1b77836db4e96541d3659251714e Author: kai <kai@qq.com> Date: Wed Mar 13 21:57:42 2019 -0400 version1 [root@kai git_test]# cat code.txt this is the first line [root@kai git_test]#
執行命令後使用git log查看版本記錄,發現如今只能看到版本1的記錄,cat code.txt查看文件內容,如今只有一行,也就是第一個版本中code.txt的內容。
假如咱們如今又想回到版本2,可使用以下命令:git reset --hard 版本號
從上面記錄能夠看到版本2的版本號爲:6280fa584403809ac2078a81120acf33e6bec836
在終端執行以下命令:(輸入版本號前幾位便可)
[root@kai git_test]# git reset --hard 6280fa5844 HEAD is now at 6280fa5 version2 [root@kai git_test]# git log commit 6280fa584403809ac2078a81120acf33e6bec836 Author: kai <kai@qq.com> Date: Thu Mar 14 00:58:35 2019 -0400 version2 commit 020bf021ec6d1b77836db4e96541d3659251714e Author: kai <kai@qq.com> Date: Wed Mar 13 21:57:42 2019 -0400 version1 [root@kai git_test]# cat code.txt this is the first line this is the second line [root@kai git_test]#
如今發現版本2有回來了,cat code.txt查看其裏面的內容和原來的相同。
假如說上面的終端已經關了,也就是咱們已經不知道版本2的版本號,該怎麼回退版本2?
首先咱們退回版本1:
[root@kai git_test]# git reset --hard HEAD^ HEAD is now at 020bf02 version1 [root@kai git_test]# cat code.txt this is the first line [root@kai git_test]#
那麼在不知道版本號狀況下怎麼再回到版本2呢?其實git reflog命令能夠查看咱們的操做記錄。
查到版本2的版本號,咱們再使用以下命令進行版本回退,版本從新回到了版本2。
[root@kai git_test]# git reflog 020bf02 HEAD@{0}: reset: moving to HEAD^ 6280fa5 HEAD@{1}: reset: moving to 6280fa5844 020bf02 HEAD@{2}: reset: moving to HEAD^ 6280fa5 HEAD@{3}: commit: version2 020bf02 HEAD@{4}: commit (initial): version1 [root@kai git_test]# git reset --hard 6280fa5844 HEAD is now at 6280fa5 version2 [root@kai git_test]# git log commit 6280fa584403809ac2078a81120acf33e6bec836 Author: kai <kai@qq.com> Date: Thu Mar 14 00:58:35 2019 -0400 version2 commit 020bf021ec6d1b77836db4e96541d3659251714e Author: kai <kai@qq.com> Date: Wed Mar 13 21:57:42 2019 -0400 version1 [root@kai git_test]#
1)工做區(Working Directory)
電腦中的目錄,好比咱們的git_test,就是一個工做區。
2)版本庫(Repository)
工做區有一個隱藏目錄.git,這個不是工做區,而是git的版本庫。
git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫HEAD。由於咱們建立git版本庫時,git自動爲咱們建立了惟一一個master分支,因此,如今 git commit 就是往master分支上提交更改。
能夠簡單理解爲,須要提交的文件修改統統放到暫存區,而後,一次性提交暫存區的全部修改。
下面上圖理解:
前面說了咱們把文件往git版本庫裏添加的時候,是分兩步執行的:
第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用git commit提交更改,實際上就是把暫存區的全部內容提交到當前分支。
下面在git_test目錄下再建立一個文件code2.txt,而後編輯內容,同時修改code.txt的內容:
[root@kai git_test]# vim code2.txt
[root@kai git_test]# cat code2.txt
the code2 first line
[root@kai git_test]# vim code.txt
[root@kai git_test]# cat code.txt
this is the first line
this is the second line
this is the third line
使用以下命令查看當前工做樹的狀態:
[root@kai git_test]# 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: code.txt # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # code2.txt no changes added to commit (use "git add" and/or "git commit -a") [root@kai git_test]#
上面提示咱們code.txt被修改,而code2.txt沒有被跟蹤。
咱們使用以下命令把code.txt和code2.txt加入到暫存區,而後再執行git status命令,結果以下:
[root@kai git_test]# git add code.txt [root@kai git_test]# git add code2.txt [root@kai git_test]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: code.txt # new file: code2.txt # [root@kai git_test]#
因此git add命令是把全部提交的修改存放到暫存區。
而後,執行git commit就能夠一次性把暫存區的全部修改提交到分支建立一個版本。
[root@kai git_test]# git commit -m 'version3' [master f18f0cc] version3 2 files changed, 2 insertions(+) create mode 100644 code2.txt [root@kai git_test]# git log commit f18f0ccadc62b83fa4c6e2222956ba2f2a0e5230 Author: kai <kai@qq.com> Date: Thu Mar 14 05:16:31 2019 -0400 version3 commit 6280fa584403809ac2078a81120acf33e6bec836 Author: kai <kai@qq.com> Date: Thu Mar 14 00:58:35 2019 -0400 version2 commit 020bf021ec6d1b77836db4e96541d3659251714e Author: kai <kai@qq.com> Date: Wed Mar 13 21:57:42 2019 -0400 version1 [root@kai git_test]#
一旦提交後,若是你又沒有對工做區作任何修改,那麼工做區就是「乾淨」的。執行以下命令能夠發現:
[root@kai git_test]# git status # On branch master nothing to commit, working directory clean [root@kai git_test]#
如今咱們的版本庫變成了這樣:
git管理的文件的修改,它只會提交暫存區的修改來建立版本。
編輯code.txt,並使用git add 命令將其添加到暫存區中。
[root@kai git_test]# vim code.txt
[root@kai git_test]# cat code.txt
this is the first line
this is the second line
this is the third line
this is the forth line
[root@kai git_test]# git add code.txt
繼續編輯code.txt,並在其中添加一行。
[root@kai git_test]# vim code.txt
[root@kai git_test]# cat code.txt
this is the first line
this is the second line
this is the third line
this is the forth line
this is the new line
[root@kai git_test]#
git commit 建立一個版本,並使用git status查看,發現第二次修改code.txt內容以後,並無將其添加的工做區,因此建立版本的時候並無被提交。
[root@kai git_test]# vim code.txt
[root@kai git_test]# cat code.txt
this is the first line
this is the second line
this is the third line
this is the forth line
this is the new line
[root@kai git_test]# git commit -m 'version4'
[master 66a9c99] version4
1 file changed, 1 insertion(+)
[root@kai git_test]# 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: code.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@kai git_test]#
繼續上面的操做,提示咱們可使用 git checkout -- <文件> 來丟棄工做區的改動。執行以下命令,發現工做區乾淨了,第二次的改動內容也沒了。
[root@kai git_test]# git checkout -- code.txt [root@kai git_test]# cat code.txt this is the first line this is the second line this is the third line this is the forth line [root@kai git_test]# git status # On branch master nothing to commit, working directory clean [root@kai git_test]#
咱們繼續編輯code.txt,並在其中添加以下內容,並將其添加的暫存區。
[root@kai git_test]# vim code.txt
[root@kai git_test]# cat code.txt
this is the first line
this is the second line
this is the third line
this is the forth line
the new line
[root@kai git_test]# git add code.txt
[root@kai git_test]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: code.txt
#
[root@kai git_test]#
git一樣告訴咱們,用命令 git reset HEAD file 能夠把暫存區的修改撤銷掉,從新放回工做區。
[root@kai git_test]# git reset HEAD code.txt Unstaged changes after reset: M code.txt [root@kai git_test]# 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: code.txt # no changes added to commit (use "git add" and/or "git commit -a") [root@kai git_test]#
如今若想丟棄code.txt的修改,執行以下命令便可。
[root@kai git_test]# cat code.txt this is the first line this is the second line this is the third line this is the forth line the new line [root@kai git_test]# git checkout -- code.txt [root@kai git_test]# cat code.txt this is the first line this is the second line this is the third line this is the forth line [root@kai git_test]# git status # On branch master nothing to commit, working directory clean [root@kai git_test]#
如今,若是你不但改錯了東西,還從暫存區提交到了版本庫,則須要進行版本回退。
回退小結:
場景1:當你改亂了工做區某個文件的內容,想直接丟棄工做區的修改時,用命令git checkout -- file。
場景2:當你不但改亂了工做區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了場景1,第二步按場景1操做。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節。
對比工做區和某個版本中文件的不一樣
繼續編輯文件code.txt,在最後添加一行 the new line,而後對比工做區中code.txt和HEAD版本中code.txt的不一樣。使用以下命令:
[root@kai git_test]# echo "the new line" >> code.txt [root@kai git_test]# cat code.txt this is the first line this is the second line this is the third line this is the forth line the new line [root@kai git_test]# git diff HEAD -- code.txt diff --git a/code.txt b/code.txt index 66f9219..324317f 100644 --- a/code.txt # - 表明HEAD版本中的 code.txt 內容 +++ b/code.txt # - 表明工做區中的 code.txt 內容
@@ -2,3 +2,4 @@ this is the first line this is the second line this is the third line this is the forth line +the new line # 工做區的比HEAD版本中的多了一行 [root@kai git_test]#
丟棄工做區的修改
[root@kai git_test]# git checkout -- code.txt [root@kai git_test]# git status # On branch master nothing to commit, working directory clean
對比兩個版本間文件的不一樣:
[root@kai git_test]# git diff HEAD HEAD^ -- code.txt
diff --git a/code.txt b/code.txt
index 66f9219..01e1274 100644
--- a/code.txt # - 表明 HEAD 版本中的 code.txt 內容
+++ b/code.txt # - 表明 HEAD^ 版本中的 code.txt 內容
@@ -1,4 +1,3 @@
this is the first line
this is the second line
this is the third line
-this is the forth line # HEAD 版本的比 HEAD^ 版本中的多了一行
[root@kai git_test]#
咱們把目錄中的code2.txt刪除。
[root@kai git_test]# rm -f code2.txt
這個時候,git知道刪除了文件,所以,工做區和版本庫就不一致了,git status命令會馬上提示哪些文件被刪除了。
[root@kai git_test]# 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: code2.txt # no changes added to commit (use "git add" and/or "git commit -a") [root@kai git_test]#
如今有兩個選擇,一是確實要從版本庫中刪除該文件,那就用命令 git rm 刪掉,而且 git commit:
[root@kai git_test]# git rm code2.txt rm 'code2.txt' [root@kai git_test]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: code2.txt # [root@kai git_test]# git commit -m 'delete_code2.txt' [master f25e944] delete_code2.txt 1 file changed, 1 deletion(-) delete mode 100644 code2.txt [root@kai git_test]# git status # On branch master nothing to commit, working directory clean [root@kai git_test]#
另外一種狀況是刪錯了,能夠直接使用git checkout – code2.txt,這樣文件code2.txt又回來了
刪除小結:
命令 git rm 用於刪除一個文件。若是一個文件已經被提交到版本庫,那麼你永遠不用擔憂誤刪,可是要當心,你只能恢復文件到最新版本,你會丟失最近一次提交後你修改的內容。