at_today git--一文弄懂git的工做區、索引區、本地倉庫、遠程倉庫以及add、commit、push三個操做

git中文件所在位置有四個,在工做區內、在索引區內、在本地倉庫、在遠程倉庫。處於四個位置中文件的狀態分別爲untracked、unmodified、modified、staged。經過三個操做能夠把文件進行狀態轉移:git add 把工做區文件添加到索引區;git commit 把索引區文件添加到本地倉庫;git push 把本地倉庫文件添加到遠程倉庫。git

爲了方便記憶,本身想了一個不肯定是否恰當的類比:若是類比咱們平時的一個文檔編輯活動。文件在工做區時,咱們能夠類比成咱們準備好了一段要存儲的內容;在索引區時,能夠類比爲咱們在某個位置新建了一個word文檔,往裏輸入了咱們剛剛準備的內容,可是沒有保存至關於這個時候git才知道這個文件的存在;文件在本地倉庫時,至關於ctrl +s 把文件保存到了文件系統中;在遠程倉庫,就至關於咱們把本地文件存儲到了雲盤。緩存

一下內容引用了不少大佬的文章,由於本地整理的太早了,出處記錄不詳,後續慢慢補充參考信息。服務器

 

 

 

 

工做區(working directory), 簡言之就是你工做的區域。對於git而言,就是的本地工做目錄。工做區的內容會包含提交到暫存區和版本庫(當前提交點)的內容,同時也包含本身的修改內容。app

暫存區(stage area, 又稱爲索引區index),是git中一個很是重要的概念。是咱們把修改提交版本庫前的一個過渡階段。查看GIT自帶幫助手冊的時候,一般以index來表示暫存區。在工做目錄下有一個.git的目錄,裏面有個index文件,存儲着關於暫存區的內容。git add命令將工做區內容添加到暫存區。post

本地倉庫(local repository), 版本控制系統的倉庫,存在於本地。當執行git commit命令後,會將暫存區內容提交到倉庫之中。在工做區下面有.git的目錄,這個目錄下的內容不屬於工做區,裏面即是倉庫的數據信息,暫存區相關內容也在其中。這裏也可使用merge或rebase將遠程倉庫副本合併到本地倉庫。圖中的只有merge,注意這裏也可使用rebase。fetch

遠程版本庫(remote repository), 與本地倉庫概念基本一致,不一樣之處在於一個存在遠程,可用於遠程協做,一個倒是存在於本地。經過push/pull可實現本地與遠程的交互;spa

遠程倉庫副本, 本地的一個分支,能夠理解爲存在於本地的遠程倉庫緩存。如需更新,可經過git fetch/pull命令獲取遠程倉庫內容。版本控制

 

1、本地各區域之間的操做指針

1-1 工做區與本地緩存區code

一、撤銷對工做區的修改 (即在文件已經修改、但還沒有add以前撤銷對文件的修改):git checkout

使用方法:

git checkout 文件名
撤銷對工做區修改;這個命令是以最新的存儲時間節點(add和commit)爲參照,覆蓋工做區對應文件file;這個命令改變的是工做區

二、將本地距離上次commit以後的修改從工做區添加到緩存區 : git add

使用方法:

git add 文件名   :  添加單個文件  
git add .  :  將修改操做的文件和未跟蹤新添加的文件添加到git系統的暫存區,注意不包括刪除   
git add -u :將已跟蹤文件中的修改和刪除的文件添加到暫存區,不包括新增長的文件,注意這些被刪除的文件被加入到暫存區再被提交併推送到服務器的版本庫以後這個文件就會從git系統中消失了。 
git add -A: 表示將全部的已跟蹤的文件的修改與刪除和新增的未跟蹤的文件都添加到暫存區。

三、撤銷向緩存區的add : git reset

使用方法:

git reset HEAD 文件名 :
清空add命令向暫存區提交的關於file文件的修改;這個命令將修改從新放回到工做區,僅改變暫存區,並不改變工做區,這意味着在無任何其餘操做的狀況下,工做區中的實際文件同該命令運行以前無任何變化
git reset HEAD : 若是後面什麼都不跟的話 就是上一次add 裏面的所有撤銷了

2-1 本地緩存區與本地倉庫

一、將本地緩存區中的修改提交到本地倉庫 : git commit

使用方法:

git commit -m "提交說明"  :  將add到緩存區的所有修改提交到本次倉庫

注意:
使用 git log 命令能夠查看所有commit歷史信息。
commit命令會記錄一條log,生成當前分支上的一個log節點(即一個版本),commit的一個個版本造成分支的生命線。 

 

 

 

2、本地各版本之間的操做

2-1 版本向後推動

git add
git commit -m "info"

2-2 版本回退  : git reset

修改頭指針指向以前的版本,目標版本以後的版本都再也不存儲。

 

 

 使用方法:

git log : 查找要回退到的目標版本號
git reset --hard 目標版本號 : 回退到目標版本

適用場景: 若是想恢復到以前某個提交的版本,且那個版本以後提交的版本咱們都不要了,就能夠用這種方法。

注意: 此時若是git push 到遠程會報錯,由於當前本地版本比遠程版本要低,使用git push -f 能夠強制推上去(固然前提得遠程容許推,公司的代碼庫通常會有限制)

2-3 撤銷提交 : git revert

撤銷某次提交,和reset不一樣的是以前commit的歷史都還保存在版本庫中。

 

 

 好比,咱們commit了三個版本(版本1、版本2、 版本三),忽然發現版本二不行(如:有bug),想要撤銷版本二的提交,但又不想撤銷版本三的提交,就能夠用 git revert 命令來逆向操做版本二,生成新的版本四,這個版本四里會保留版本三的東西,但撤銷了版本二的東西。

使用方法:

git log 查看要反作的目標版本號
git revert  -n 目標版本號  撤銷目標版本號所作的修改
git commit -m "message"   commit這次反作操做

適用場景: 若是咱們想撤銷以前的某一版本,可是又想保留該目標版本後面的版本,記錄下這整個版本變更流程,就能夠用這種方法。

3、本地各分支之間的操做

3-1 默認master分支

一個分支就是一條時間線,默認有一條時間線master,其中有個指針master,這個master指針是指向提交的,每次提交,master指針都會向後移一位,這樣不斷去提交,master分支就會愈來愈長。還有個HEAD指針,這個指針指向當前所在分支的的指針。

 

 

 3-2 分支建立

若建立新分支,如dev分支,git會新建一個dev指針,與master指針功能同樣。先是指向和master一樣的位置,當checkout切換到dev分支時候,HEAD指針就指向了dev指針了,當在dev分支下提交,dev指針向後移動。

 

 

 

 使用方法:

git branch branch_name : 基於當前commit建立一個新的分支
git branch : 查看所有分支

3-3 分支切換

即移動head指針,指向目標分支指針:git checkout branch_a。注意只有分支幹淨的時候才能提交,要是分支幹淨共有兩種方法,要麼把修改commit提交,要麼把修改暫存

使用方法:

commit方法:

git add .  
git commit -m "message" 
git checkout branch_b

或,stash暫存

複製代碼
git add .
git stash
git checkout branch_b

在branch_b作完操做又想回到branch_a的時候

git checkout branch_a
git stash pop 
複製代碼

git stash 具體使用見後

注意: 在切換分支以前必定要commit 或 stash 當前分支上的修改,不然在當前分支上作的操做會直接帶到目標分支,當在目標分支上執行commit操做的時候這些修改就被提交到目標分支,容易形成代碼混亂。

git commit會把修改提交,體如今分支的時間線上。若是還不想提交(過多沒有階段性成果的提交會使得分支時間線不清晰) git stash是把修改暫存,不會體如今時間線上,從新回到分支後,pop以前暫存的內容,能夠繼續修改

git stash使用

複製代碼
git stash : 將未提交的修改保存至堆棧中

git stash save "stash message info" : 爲這次stash添加說明信息,便於之後查看

git stash list : 查看stash棧中的內容

git stash pop : 將stash中的內容彈出,並應用到當前分支對應的工做目錄上,該命令將堆棧中最近保存的內容刪除(出棧操做)

git stash apply stash名稱 : 將指定id的內容應用到當前分支的工做目錄,內容不會刪除,能夠在多個分支上重複進行操做

git stash drop stash名稱 :從堆棧中移除某個指定的stash

git stash clear : 清除堆棧中的全部 內容

git stash show : 查看堆棧中最新保存的stash和當前目錄的差別。

git stash branch : 從最新的stash建立分支。
應用場景:當儲藏了部分工做,暫時不去理會,繼續在當前分支進行開發,後續想將stash中的內容恢復到當前工做目錄時,若是是針對同一個文件的修改(即使不是同行數據),那麼可能會發生衝突,恢復失敗,這裏經過建立新的分支來解決。能夠用於解決stash中的內容和當前目錄的內容發生衝突的情景。
複製代碼

3-4 合併分支

分支合併,操做很簡單,若將dev分支內容合到master上,就是將master的指針指向dev指針指向的位置便可。

  • git merge --no-ff branch_name 將branch_name分支合併到當前分支。

git merge:默認狀況下,Git執行"快進式合併"(fast-farward merge),會直接將Master分支指向Develop分支。 使用--no-ff參數後,會執行正常合併,在Master分支上生成一個新節點。爲了保證版本演進的清晰,建議採用這種方法。

  • git rebase

解決衝突

刪除分支

刪除分支就是將指向分支的指針(如dev)刪除掉

使用方法:

git checkout branch_a 切換到其餘分支
git branch -d branch_b 刪除分支

4、本地與遠程之間的操做

4-1 向遠端

  • git push 將本地倉庫推送到遠端倉庫
git add
git commit
git pull 
解決衝突
git push

4-2 向本地

複製代碼
git fetch : 使用遠程倉庫中的內容更新遠程倉庫副本。此時並未合併到本地倉庫,即本地倉庫的代碼沒有被修改,知識拉取了遠程commit數據。

git merge : 實現遠程倉庫與本地倉庫的合併

git pull  :下拉遠程分支並與本地分支合併(使用遠程倉庫的內容更新遠程倉庫副本以及本地倉庫)。根據配置的不一樣,至關於git fetch + git merge 或 git fetch + git rebase。

git clone   :   本地沒有 repository 時,將遠程 repository 整個下載過來。
複製代碼
相關文章
相關標籤/搜索