世上最詳細的git原理解釋(轉載)
????0528 2018-06-14 13:49:36 16648 收藏 23
原文路徑是https://www.cnblogs.com/cb0327/p/5066685.html
目錄
正文
本文背景,在實際項目中使用git已有一年,發現不少同事雖然會使用常用git指令,但並不理解每個指令對應的作用原理。今天靜下心總結下git 的基本理解:代碼的存在區域;本文以實際項目出發,理清使用git過程中,代碼的遷徙流程。
git跟傳統的代碼管理器(如:svn)不同, 主要區別在於git多了個本地倉庫以及緩存區,所以即使無法聯網也一樣能提交代碼。術語解釋:
工作區間: 即我們創建的工程文件, 在編輯器可直觀顯示;
緩存區: 只能通過git GUI或git shell 窗口顯示,提交代碼、解決衝突的中轉站;
本地倉庫: 只能在git shell 窗口顯示,連接本地代碼跟遠程代碼的樞紐,不能聯網時本地代碼可先提交至該處;
遠程倉庫: 即保存我們代碼的服務器,本文以公共版本控制系統:github爲例,登錄github賬號後可直觀顯示;
接下來, 我們以三個實際操作的例子講解git的日常,代碼如何在上述4個區域流動。
1.提交 代碼到遠程倉庫
首先在本地工作區間創建一個新工程:testGit,然後在項目裏新建一個README.md, 工作區間的工程如下:
遠程倉庫創建一新工程,具體操作參見 如何在window上把你的項目提交到github
將該新建的工程提交至遠程倉庫,關鍵的git 指令如下:
指令解釋:
`git init ` 表示在當前的項目目錄中生成本地的git管理;
`git add README.md` 將“README.md”文件保存至緩存區,實際開發中一般使用 `git add -A`,使用-A:將新增、刪除、修改的文件改動全保存至緩存區;
`git commit -m "first commit"` 將代碼從緩存區保存至本地倉庫,實際開發中一般使用`git commit -am "說明的文字"`,使用 -a:如果沒文件更改操作(增、刪、改名)就可以省略git add指令;
`git remote add origin https://github.com/wteam-xq/testGit.git`將本地倉庫與指定的遠程倉庫創建 聯繫;
`push -u origin master` 將本地倉庫代碼推送至遠程倉庫,實際開發中 該指令後需要輸入github 賬號以及密碼。(首次提交注意別遺漏`-u`指定默認主機)
以上指令正常執行後, 本地倉庫的代碼就提交到遠程倉庫了:
原理圖如下:
2.將遠程倉庫代碼更新到本地
首先我們新建一文件夾:copyTestGit,進入該文件夾後使用git 指令:
git clone https://github.com/wteam-xq/testGit
指令執行完畢後, 就在該文件夾下生成一份副本啦(相當於多人協作時另一臺設備上的工程文件),原理圖如下:
接下來, 討論`git pull`、 `git fetch` 、 `git merge`的關係
先拋簡單結論:
實際項目:我們在testGit工程中修改README.md,然後更新、提交下代碼 執行以下git 指令(日常使用中會用`git status`看看是否有文件需要`git add`):
原理圖如下:
遠程倉庫代碼更新後, 我們進入另一本地倉庫:copyTestGit\testGit,將遠程倉庫的代碼更新至該本地倉庫。
在該目錄下輸入以下git指令:
日常使用圖方便一般都是直接:
以上指令的詳細探討請看 少用pull,多用fetch 和 merge
(注意: 本文注重git工作原理圖不考慮多分支情況,且使用了git clone所以副本工程已經跟主分支建立了追蹤關係,所以'pull' 'fetch' 後都不接分支代碼 )
以上指令區別的原理圖:
3.更新到本地倉庫時, 出現衝突,解決衝突
首先, 我們先重現下出現衝突的情況; 在testGit目錄下先修改README.md文件第三行,hello word 修正爲 hello world:
提交該修改到遠程倉庫(提交細節參照前述步驟):
然後, 在副本工程copyTestGit/testGit 目錄下也修改README.md文件第三行,hello word 修正爲 hello world2:
現在副本工程修改完了代碼打算提交,提交前先將遠程倉庫最新代碼更新至本地倉庫, 慣例使用指令:
指令執行之後會發現以下衝突提示:
出現以上提示, 說明本次更新代碼失敗;主要在於本地工作區間跟遠程倉庫的新代碼衝突了, 圖解如下:
接下來,有兩種方式處理衝突: 放棄本地修改或 解決衝突後提交本地修改
3.1 放棄本地修改
放棄本地修改意味着將遠程倉庫的代碼完全覆蓋本地倉庫以及本地工作區間, 如果對git的指令不熟悉那大可以將本地工程完全刪除,然後再重新拷貝一次(`git clone`)。
當然, git如此強大沒必要用這麼原始的方法,可以讓本地倉庫代碼覆蓋本地修改,然後更新遠程倉庫代碼;
本地倉庫代碼完全覆蓋本地工作區間,具體指令如下:
(注意: 別遺漏 "head" 後的 " ." )
然後更新遠程倉庫的代碼就不會出現衝突了:
原理圖如下:
3.2 解決衝突後提交本地修改
覆蓋本地代碼解決衝突方法適合不太懂git的菜鳥, 像我這種git老鳥(其實並不是(¬_¬))當然用更高級的git指令解決衝突。
細心的同學或許已發現,緩存區 除了開始出現外,後續提交代碼、更新代碼篇章都在打醬油;終於,這次衝突解決事件, 它將會是主角!
解決衝突後提交本地修改的思路大概如下:
將本地修改的代碼放在緩存區, 然後從遠程倉庫拉取最新代碼,拉取成功後再從緩存區將修改的代碼取出, 這樣最新代碼跟本地修改的代碼就會混雜在一起, 手工解決衝突後, 提交解決衝突後的代碼。
原理圖:
對應到我們實際項目中, 進入 copyTestGit/testGit 執行指令`git pull`出現 (重回到上述衝突場景)
將本地修改放入緩存區(成功後本地工作區間的代碼跟本地倉庫代碼會同步), 具體指令:
從遠程倉庫獲取最新代碼,具體指令:
然後, 取出本地修改的代碼, 具體指令:
然後, git 自動合併衝突失敗, 衝突的代碼就很清晰的展現在我們面前了:
(小廣告:3.2欄更多細節請移步本人另一博文git 代碼衝突處理)
手工解決衝突:
告訴git, 這個文件(README.md)的衝突 已經解決:
提交代碼(細節參考前述流程):
於是本地有衝突的代碼就提交成功啦!
後記:
以上很多git指令適合在無圖形化界面的linux中使用(例如:阿里雲服務器操作git), 實際開發中當然是用圖形化界面解決!
解決衝突之覆蓋本地代碼對應的是: 工程目錄下tortoiseGit(git 小烏龜) “Revert” :
解決衝突之解決衝突後提交本地修改對應的是: 手工合併衝突代碼後,工程目錄下tortoiseGit(git 小烏龜) “resolve” :
參考文章:
5.Git 少用 Pull 多用 Fetch 和 Merge