git圖解

qq_1102978036發表於2020-12-27

原文: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 add README.md
git commit -m "首次提交程式碼"
git remote add origin https://github.com/wteam-xq/testGit.git
git push -u origin master

指令解釋:

`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`的關係

先拋簡單結論:

git pull
#等同於下面命令
git fetch
git merge

實際專案:我們在testGit工程中修改README.md,然後更新、提交下程式碼 執行以下git 指令(日常使用中會用`git status`看看是否有檔案需要`git add`):

git commit -am 'update readme.md'
git push origin master

原理圖如下:

遠端倉庫程式碼更新後, 我們進入另一本地倉庫:copyTestGit\testGit,將遠端倉庫的程式碼更新至該本地倉庫。

在該目錄下輸入以下git指令:

git fetch 
git merge origin/master

日常使用圖方便一般都是直接:

git pull

以上指令的詳細探討請看 少用pull,多用fetch 和 merge

注意: 本文注重git工作原理圖不考慮多分支情況,且使用了git clone所以副本工程已經跟主分支建立了追蹤關係,所以'pull' 'fetch' 後都不接分支程式碼 )

以上指令區別的原理圖:

回到頂部

3.更新到本地倉庫時, 出現衝突,解決衝突

首先, 我們先重現下出現衝突的情況; 在testGit目錄下先修改README.md檔案第三行,hello word 修正為 hello world:

提交該修改到遠端倉庫(提交細節參照前述步驟):

然後, 在副本工程copyTestGit/testGit 目錄下也修改README.md檔案第三行,hello word 修正為 hello world2:

現在副本工程修改完了程式碼打算提交,提交前先將遠端倉庫最新程式碼更新至本地倉庫, 慣例使用指令:

git pull

指令執行之後會發現以下衝突提示:

出現以上提示, 說明本次更新程式碼失敗;主要在於本地工作區間遠端倉庫的新程式碼衝突了, 圖解如下:

接下來,有兩種方式處理衝突: 放棄本地修改或 解決衝突後提交本地修改

3.1 放棄本地修改

放棄本地修改意味著將遠端倉庫的程式碼完全覆蓋本地倉庫以及本地工作區間, 如果對git的指令不熟悉那大可以將本地工程完全刪除,然後再重新拷貝一次(`git clone`)。

當然, git如此強大沒必要用這麼原始的方法,可以讓本地倉庫程式碼覆蓋本地修改,然後更新遠端倉庫程式碼; 

本地倉庫程式碼完全覆蓋本地工作區間,具體指令如下:

git checkout head .

(注意: 別遺漏 "head" 後的 " ." )

然後更新遠端倉庫的程式碼就不會出現衝突了:

git pull

原理圖如下:

3.2 解決衝突後提交本地修改

覆蓋原生程式碼解決衝突方法適合不太懂git的菜鳥, 像我這種git老鳥(其實並不是(¬_¬))當然用更高階的git指令解決衝突。

細心的同學或許已發現,快取區 除了開始出現外,後續提交程式碼、更新程式碼篇章都在打醬油;終於,這次衝突解決事件, 它將會是主角!

解決衝突後提交本地修改的思路大概如下:

將本地修改的程式碼放在快取區, 然後從遠端倉庫拉取最新程式碼,拉取成功後再從快取區將修改的程式碼取出, 這樣最新程式碼跟本地修改的程式碼就會混雜在一起, 手工解決衝突後, 提交解決衝突後的程式碼。

原理圖:

對應到我們實際專案中, 進入 copyTestGit/testGit 執行指令`git pull`出現 (重回到上述衝突場景)

error: Your local changes to the following files would be overwritten by merge:
        README.md
Please, commit your changes or stash them before you can merge.
Aborting

將本地修改放入快取區(成功後本地工作區間的程式碼跟本地倉庫程式碼會同步), 具體指令:

git stash 

遠端倉庫獲取最新程式碼,具體指令:

git pull

然後, 取出本地修改的程式碼, 具體指令:

git stash pop

然後, git 自動合併衝突失敗, 衝突的程式碼就很清晰的展現在我們面前了:

(小廣告:3.2欄更多細節請移步本人另一博文git 程式碼衝突處理

手工解決衝突:

告訴git, 這個檔案(README.md)的衝突 已經解決:

git add README.md

提交程式碼(細節參考前述流程):

git commit -am '終於解決衝突啦!'
git push origin master

於是本地有衝突的程式碼就提交成功啦!

回到頂部

後記:

以上很多git指令適合在無圖形化介面的linux中使用(例如:阿里雲伺服器操作git), 實際開發中當然是用圖形化介面解決!

解決衝突之覆蓋原生程式碼對應的是: 工程目錄下tortoiseGit(git 小烏龜) “Revert” :

解決衝突之解決衝突後提交本地修改對應的是: 手工合併衝突程式碼後,工程目錄下tortoiseGit(git 小烏龜) “resolve” :

參考文章:

1.Git版本控制與工作流

2.圖解 Git 管理專案程式碼

3.如何在window上把你的專案提交到github

4.Git遠端操作詳解

5.Git 少用 Pull 多用 Fetch 和 Merge

6.Git教程推薦一(廖雪峰)

7.Git教程推薦二(云溪)

8.Mac OS X Git安裝教程

9.git-ssh 配置和使用

10.github設定新增SSH

11.生成多個git ssh金鑰

12.ssh-agent 使用指南

 

相關文章