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


免責聲明!

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



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