1 工作流程
首先需要說明的是,git的版本庫是以分支的形式進行管理的。當我們初始化一個新的版本庫時,會自動創建版本庫的第一個分支master
,我們對本地倉庫的修改都是提交到這個master
分支的。關于分支,后續會單獨介紹。
本地倉庫由git維護的三個組件構成:
1)工作區:文件系統中的文件目錄
2)stage\index(暫存區):緩存區域,保存需要提交到版本庫的文件(改動)
3)HEAD:這是一個指針,指向當前分支
上述stage以及HEAD保存在工作區中的.git/
目錄中。
工作流程圖如下:
如上圖所示,當我們需要向版本庫中添加新的文件或者修改文件時的工作流程:
首先,使用git add
指令將文件從工作區添加到stage中;
而后,使用git commit
指令將stage中的所有內容提交到當前分支。
2 本地倉庫管理
接下來主要介紹如何對本地倉庫進行管理,其中包括:查看狀態、添加文件、提交文件、版本管理、撤銷修改、刪除文件等。
2.1 狀態查看
我們可以使用git status
指令實時查看當前版本庫的狀態,然后根據當前的狀態進行后續操作,在日常使用過程中經常會用到這個指令,可以幫助我們實時掌握版本庫的狀態。
示例:
首先通過一下指令創建一個本地版本庫,并使用git status
指令查看版本庫狀態:
$ git init MyGitTest #創建本地版本庫
$ cd MyGitTest #切換到版本庫的工作目錄
$ git status #查看版本庫的狀態
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
2.2 添加文件到stage中
指令格式: git add filename
添加方式有如下幾種:
$ git add README.md #僅添加README.md文件
$ git add *.py #添加所有python文件
$ git add . #添加當前目錄下的所有文件
示例:
在MyGitTest
版本庫中編輯README.md
文件,添加如下內容:
a test for git
將該文件添加到stage,并查看版本狀態:
$ git add README.md
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README.md
通過版本狀態信息,我們有如下兩個選擇:
1)使用commit
指令將其提交到當前分支
2)使用提供的git rm --cached README.md
指令將添加到stage中的README.md文件撤銷,或者使用git reset HEAD READM.md
指令也可以實現對README.md文件的撤銷
2.3 將stage中的內容提交到當前分支
這里使用commit
指令將stage中的內容提交當版本庫的當前分支,主要有如下幾種形式:
$ git commit -m "msg of commit" -a #提交stage中所有內容
$ git commit -m "msg of commit" #同上
$ git commit -m "msg of commit" filename #僅提交filename文件
$ git commit --amend #增補提交,還沒有用過
示例:
將2.2中的添加到stage中的README.md
文件提交到版本庫的當前分支,并查看狀態
$ git commit -m "add README.md" README.md
[master (root-commit) 0e24ff7] add README.md
1 file changed, 1 insertion(+)
create mode 100644 README.md
$ git status
On branch master
nothing to commit, working directory clean
2.4 撤銷修改
2.4.1 撤銷在工作區做的修改
當我們在工作區,對文件進行了修改,突然發現修改的內容有錯誤,這時候就需要將文件在工作區的修改進行撤銷。一般有如下兩種情況:
1)文件在修改后沒有add到stage區,撤銷之后文件狀態與版本庫保持一致;
2)文件已經add到stage區,而后在工作區有對其進行了修改,此時撤銷工作區中文件的修改,文件和stage區中的狀態保持一致。
撤銷指令如下:
$ git checkout -- README.md #撤銷對文件README.md的修改
$ git checkout -- . #撤銷對所有文件的修改
$ git checkout -- *.py #撤銷對所有python文件的修改
示例:
修改工作區README.md
內容,修改后的內容:
$ cat README.md
a test for git
test for git checkout -- README.md
撤銷對README.md
文件的修改,并查看內容:
$ git checkout -- README.md
$ cat README.md
a test for git
2.4.2 撤銷add到stage中的內容
當我們對某些文件進行了修改,而且使用add
指令將其添加到了stage區,突然發現這些修改中出現錯誤,這時我們需要將stage區中的文件撤銷回工作區。具體指令如下:
$ git reset HEAD README.md #將stage區中的README.md文件撤銷回工作區
$ git reset HEAD #將stage區中的所有文件撤銷回工作區
示例:
修改工作區README.md
內容,修改后的內容,并將其添加到stage區,并查看狀態:
$ cat README.md
a test for git
test for git checkout -- README.md
$ git add README.md #添加到stage區
$ git status #查看狀態
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
$ git reset HEAD README.md #將文件從stage區撤銷會工作區
$ git status #查看狀態,發現添加到stage中的README.md被撤銷回工作區,狀態恢復到add指令前
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
特別注意
git status
指令會幫助我們實時掌握本地版本庫(工作區、stage區)的狀態,同時會提示可以對當前狀態進行操作的指令。例如上述最后查看狀態,提示可以使用add
將README.md
文件添加到stage或者使用checkout
指令撤銷對README.md
文件的修改
2.5 版本管理
之前提到過,git的版本庫是通過分支的形式進行管理的,本地版本庫默認的會創建一個master
分支,如果不創建其他分支,基本上所有的操作都是在這個master
分支上進行的。可以將分支看作是一個鏈表,每次使用commit
指令提交代碼時,都會保存一個當前版本的"快照",可理解為創建一個新的版本節點,并將這個節點插入到當前的分支中,HEAD指針總是指向最新的版本節點。
2.5.1 查看版本日志
上面提到每次commit
提交,都會保存版本"快照",并且會記錄到日志中,我們可以通過指令來查看日志中記錄的歷史commit
記錄。
使用git log
:
$ git log
commit a65eebe8ae8c080ebd8eeab6ff12a89cfde52836
Author: zhoushuo19 <zhoushuo_19@yahoo.com>
Date: Mon Dec 26 13:53:06 2016 +0800
add push_email.py
commit 51857938f7f6ce6a3c241b9140e9434abbea6676
Author: zhoushuo19 <zhoushuo_19@yahoo.com>
Date: Fri Dec 23 18:14:30 2016 +0800
add test
commit 0e24ff732c00aaa6de8b79a7a6a3719f264b8964
Author: zhoushuo19 <zhoushuo_19@yahoo.com>
Date: Fri Dec 23 17:46:08 2016 +0800
add README.md
git log
指令會顯示從最近到最遠的commit
提交日志。
當前版本庫master
分支如下圖所示:
特別注意
日志中的commit字段后邊是一個長度為40的十六進制字符串,這個就是每次commit
的版本號(SHA-1結果),每個版本號是唯一的,后續會介紹如何使用版本號來進行版本回退。
為了簡化日志的輸出,可以使用如下兩個指令:
$ git log --pretty=oneline
a65eebe8ae8c080ebd8eeab6ff12a89cfde52836 add push_email.py
51857938f7f6ce6a3c241b9140e9434abbea6676 add test
0e24ff732c00aaa6de8b79a7a6a3719f264b8964 add README.md
$ git log --oneline
a65eebe add push_email.py
5185793 add test
0e24ff7 add README.md
2.5.2 版本回退
當我們發現最近提交到版本庫中的內容有誤,需要將版本庫回退到之前某個版本時,就需要使用如下指令進行版本回退:
$ git reset --hard HEAD^ #回退到上一個版本
$ git reset --hard HEAD^^ #回退到上上個版本
$ git reset --hard HEAD~10 #回退到之前10個版本
$ git reset --hard 5185793 #回退到版本號開頭是5185793的版本
示例:
將之前版本回退一個版本:
$ git reset --hard HEAD^ #回退版本
HEAD is now at 5185793 add test
$ git log --oneline #查看版本日志
5185793 add test
0e24ff7 add README.md
經過上述版本回退,版本庫如下圖所示:
注意
版本回退速度非常快,這是因為在執行版本回退指令時,僅是將HEAD
指針指向了要回退的那個版本上。
2.5.3 版本恢復
經過上面的版本回退,我們成功的將版本庫版本回退到了版本號為5185793
的版本。這時我們可能需要將版本恢復到版本回退之前的版本也就是原來版本號為a65eebe
的版本,查看版本日志,發現那個版本在版本日志中已經消失了,怎么辦?
可以使用指令git reflog
來找到那個版本的版本號,這個指令記錄了執行過的每一條指令,如下所示:
$ git reflog
5185793 HEAD@{0}: reset: moving to HEAD^
a65eebe HEAD@{1}: commit: add push_email.py
5185793 HEAD@{2}: commit: add test
0e24ff7 HEAD@{3}: commit (initial): add README.md
這樣我們就可以將版本恢復了:
$ git reset --hard a65eebe
HEAD is now at a65eebe add push_email.py
2.6 刪除文件
首先,將工作區中的test
文件刪除,而后查看狀態:
$ rm 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: test
no changes added to commit (use "git add" and/or "git commit -a")
根據git status
指令的提示,可以進行如下兩個操作
1)確定要刪除test
文件,進行如下操作:
$ git rm test #刪除文件
rm 'test'
$ git status #查看狀態
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: test
$ git commit -m"remove test" #提交刪除
[master 9f4007d] remove test
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 test
2)誤刪,使用checkout
恢復該文件
$ git checkout -- test