1. 程式人生 > 實用技巧 >git stash與git commit的區別

git stash與git commit的區別

問題的出現

寫這篇文章的緣由是在工作中初次使用Git的時候遇到了一個奇怪的現象,即每次提交程式碼的時候,如果沒有及時拉取程式碼就會導致本地庫的程式碼不是最新的,這樣自己修改程式碼之後想要push到遠端倉庫的時候就會遭到拒絕,每次被拒絕以後我會先拉取程式碼,然後再繼續push,這樣可以成功提交程式碼,可是會產生兩個提交物件,一個是我改動產生的提交物件(這個是應該有的),可是還會產生另外一個Merge branch…的提交物件,這個物件裡面是我未拉取的別人的提交,最後作為了我的提交push到了遠端倉庫,這樣的現象會使得提交歷史記錄比較混亂,容易讓人迷惑,稍有不慎,就會把別人的提交誤認為其他人或自己的。
由於對Git的瞭解有限,所以這個現象產生的原因自己一直百思不得其解,直到有一天通過看書與討論總算弄清楚了現象產生的原因。

隱藏的區別

在專案開發的過程中,我使用的開發工具是STS,而另一位同事使用的開發工具是IntelliJ IDEA,裡面分別集成了Git的外掛,使用STS的時候會出現前述的現象,可是使用IDEA在上述情況下並不會產生兩個提交物件,也就是不會把他人的提交變成自己的提交再重新提交一遍,我們推測一定是兩個工具預設使用的Git命令不同,所以導致產生的現象不一樣。
最後,我們使用命令列重現了兩種現象,終於弄懂了不同的Git命令的區別,本質上就是git stash命令和git commit命令的區別。如果我們知道Git的基本原理,那就一定知道Git中儲存的是檔案的快照而非每個檔案與初始版本的差異,那麼在每次提交的時候,Git都會對當時的全部檔案製作一個快照並儲存這個快照的索引(儲存在提交物件中)。假設我們在master

分支進行開發工作:

          A  local
         /
    D---E---A'  master

在拉取了E(字母代表一個提交物件)提交之後,我們忘記拉取最新的程式碼就進行了修改,這時候master分支上的提交已經變成了A'
(1) 如果我們使用git commit命令,那麼我們本地就會產生一個A的提交物件,那麼git pull的時候便需要把master分支合併到本地(可能需要解決衝突),然後再提交:

          A  local
         / \
    D---E---A'  master

合併後產生了一個M提交物件:

          A---M  local
         / 
    D---E---A'  master

最後git push提交到master分支上,則會產生兩個提交:

    D---E---A'---A---M    master

(2) 如果我們使用git stash命令,那麼我們本地就不會產生新的提交物件,而是把本地的更改先行快取,那麼git pull的時候便可以直接把本地的HEAD更新為A'

          A'  local
         / 
    D---E---A'  master

然後再使用git stash pop命令將本地的修改恢復(可能需要解決衝突),這就相當於我們在A'的基礎上進行了修改,然後進行git commit產生了新的提交物件B

          A'---B  local
         / 
    D---E---A'  master

最後git push提交到master分支上,則只會產生一個提交:

    D---E---A'---B    master

總結

奇怪現象出現的原因並不是Git的bug,而是我們操作方式的不對。通過這個實驗,我們也瞭解了在兩個不同的IDE中對於Git操作的預設指令也是不一樣的,STS中的EGit外掛對於本地的修改會預設git add,而IDEA中整合的Git對本地的修改會預設git stash

版權宣告:本文為CSDN博主「cloud_yf」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/u010629610/article/details/87335894