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


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

為了方便記憶,自己想了一個不確定是否恰當的類比:如果類比我們平時的一個文檔編輯活動。文件在工作區時,我們可以類比成我們准備好了一段要存儲的內容;在索引區時,可以類比為我們在某個位置新建了一個word文檔,往里輸入了我們剛剛准備的內容,但是沒有保存相當於這個時候git才知道這個文件的存在;文件在本地倉庫時,相當於ctrl +s 把文件保存到了文件系統中;在遠程倉庫,就相當於我們把本地文件存儲到了雲盤。

一下內容引用了很多大佬的文章,因為本地整理的太早了,出處記錄不詳,后續慢慢補充參考信息。

 

 

 

 

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

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

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

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

遠程倉庫副本, 本地的一個分支,可以理解為存在於本地的遠程倉庫緩存。如需更新,可通過git fetch/pull命令獲取遠程倉庫內容。

 

一、本地各區域之間的操作

1-1 工作區與本地緩存區

1、撤銷對工作區的修改 (即在文件已經修改、但尚未add之前撤銷對文件的修改):git checkout

使用方法:

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

2、將本地距離上次commit之后的修改從工作區添加到緩存區 : git add

使用方法:

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

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

使用方法:

git reset HEAD 文件名 :
清空add命令向暫存區提交的關於file文件的修改;這個命令將修改重新放回到工作區,僅改變暫存區,並不改變工作區,這意味着在無任何其他操作的情況下,工作區中的實際文件同該命令運行之前無任何變化
git reset HEAD : 如果后面什么都不跟的話 就是上一次add 里面的全部撤銷了

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

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

使用方法:

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

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

 

 

 

二、本地各版本之間的操作

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了三個版本(版本一、版本二、 版本三),突然發現版本二不行(如:有bug),想要撤銷版本二的提交,但又不想撤銷版本三的提交,就可以用 git revert 命令來逆向操作版本二,生成新的版本四,這個版本四里會保留版本三的東西,但撤銷了版本二的東西。

使用方法:

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

適用場景: 如果我們想撤銷之前的某一版本,但是又想保留該目標版本后面的版本,記錄下這整個版本變動流程,就可以用這種方法。

三、本地各分支之間的操作

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-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 整個下載過來。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM