一、源起
程式碼,對於軟體公司而言是最為寶貴的資產。如何保管程式碼才是是最高效的呢?
假設我們不使用任何工具,各自為政,那麼將會至少存在以下幾個問題:
- 團隊成員因為硬碟損壞或者離職等原因導致程式碼丟失,則該成員的程式碼丟失
- 團隊成員無法得到其他成員的程式碼。需要定期花時間將自己的程式碼與其他成員合併(兩兩合併),以便於得到完整的程式碼,專案一旦複雜,這個工作量極大
- 如果專案開發過程中,發覺編碼思路出錯,需要將程式碼回退到三天前的狀態,則需要全部重寫
- 專案上線後,發覺存在一個低階bug,需要確認這個bug誰寫的(然後...)
這裡涉及到的都是程式碼管理的問題。而且只是真實世界程式碼管理問題之中很少很少的一部分。
解決這類問題的專業工具,就是今天要介紹的程式碼管理工具,或者稱為版本管理工具(VCS Version Control System)。 VCS 中每次將程式碼更改提交給VCS管理時,就會產生一個版本(Version),因此可以追蹤到單個檔案的更改。一般的VCS系統都存在一個伺服器,可以將原生程式碼提交到遠端伺服器,並支援自動的程式碼合併,因此團隊成員可以輕鬆地共享程式碼,合併程式碼的成本也大大降低。
市面上的VCS軟體非常多,但群雄逐鹿的年代已經過去了。Git 就是現今最為流行和最為強大的版本管理系統。他的作者就是鼎鼎大名的linux核心作者linus torvalds。是大佬雲集的linux社群用來管理linux核心程式碼的版本管理工具,看血統也知道必然強大。
二、Git的安裝
windows
訪問git官網(git-scm.com/) 下載安裝包,之後點選下一步到底安裝。安裝完成後,git提供了一個git-bash,是在windows下模擬的linux終端,可以使用基礎的linux命令。
linux
使用包管理器直接下載安裝。比如centos下 yum install git
mac
建議使用homebrew安裝, brew install git
三、Git基本概念
我們來以Git為例,講解下VCS常見的一些概念。
Git-Server 及 Git Remote
Git是C/S架構,意味著Git也存在一個伺服器,一個本地客戶端。一個Git伺服器(git-server)可以託管多個git程式碼倉庫(git-repository)。意味著,你可以在同一個git伺服器上,為專案A建立一個程式碼倉庫,也可以為專案B建立一個程式碼倉庫,兩個程式碼倉庫獨立管理,互不影響。每個在伺服器上的程式碼倉庫相較於原生程式碼倉庫而言稱為remote,每個本地客戶端可以存在多個remote。也就是說,你可以將同一個專案的程式碼推送到多個remote。比如推送到國外的github,同時推送到國內的gitee.
git伺服器可以自建(常用工具gitlab,gogs),也可以使用託管服務網站。最著名的就是github.com,但因為眾所周知的原因速度稍慢。國內的主要有碼雲(gitee.com),阿里code等。
Git-Client 及 原生程式碼倉庫
我們的程式碼在自己電腦上,要與git伺服器互動,顯然需要一個客戶端,稱為git-client。最早git是linux的一個命令列程式(畢竟人家是linux之父寫的),所以Git-client在linux下就是git命令。隨著技術發展,現在也有windows版本,也出現了一些GUI工具(最著名的有SourceTree)等。
Git原生程式碼倉庫,是git遠端倉庫的一個本地副本。通常的表現形式是一個名為 .git
的資料夾。它支援本地提交,並支援跟遠端倉庫進行同步。
Git會在本地的每次提交會產生一個版本,git會分配一個獨立的提交ID,提交包含了檔案的修改內容、提交的說明資訊、作者資訊等。git可以在不聯網的情況下瀏覽提交記錄,包括本地提交以及已經同步過的遠端提交記錄。也可以單獨檢視某個檔案的修改資訊。git支援也支援回滾到某個特定的版本,方便撤銷程式碼更改。當提交被推送到遠端時,這些提交記錄也會被提交。
git對檔案的管理是需要主動新增的。一旦新增後,git會自動監控檔案修改,並根據是否提交來更新檔案狀態。
Git分支
Git的一個重要的作用是支援並行開發,比如 A和B獨立開發兩個不相關的功能,可以同時開發,並且在合適的時間合併程式碼。這項支援的特性稱為Git分支,是Git一項非常重要的特性。後續我們在其他文章中單獨來討論。
四、Git的使用
4.1 建立遠端倉庫
下面來講解git的用法,首先我們需要有一個git的遠端倉庫。個人學習不建議自建,建議使用gitee。
- 首先訪問 gitee.com/signup?from… 註冊gitee賬號
- 然後點選頭像旁的+ 號 建立倉庫
- 如果是多人協作,可以在倉庫管理介面中新增人員,操作如下
將連結或者二維碼發給邀請的物件即可。
4.2 本地倉庫操作
下面 我們來講解本地倉庫的幾個基本的操作
- 克隆:clone,從遠端下載一個程式碼倉庫的操作,在git稱為clone克隆操作,這個操作不單是下載了倉庫中的程式碼檔案,也包括了提交記錄,分支等等附屬資訊。克隆完成後,本地得到的是一個完整的倉庫
- 新增:add, 將一個檔案新增到git管理範圍中。
- 提交:commit,這個提交是本地提交,在本地倉庫中建立了一次提交,產生了一個版本,並且新增了提交記錄。不需要聯網。
- 推送:push,將原生程式碼倉庫的提交資訊及程式碼更改推送給遠端倉庫,需要聯網
- 拉取:pull 從遠端倉庫下載程式碼更改及提交資訊,需要聯網
具體操作步驟:
- 開啟一個git-bash終端,首先配置環境
$ git config --global user.name "你的名字或暱稱,使用者名稱"
$ git config --global user.email "你的郵箱,與【設定-多郵箱管理】中的“提交郵箱”保持一致"
複製程式碼
- 使用 git clone 命令克隆一個遠端倉庫
$ git clone https://gitee.com/somename/somerepo.git
Cloning into 'somerepo'...
remote: Enumerating objects: 273, done.
remote: Counting objects: 100% (273/273), done.
remote: Compressing objects: 100% (270/270), done.
remote: Total 273 (delta 102), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (273/273), 117.85 MiB | 3.75 MiB/s, done.
Resolving deltas: 100% (102/102), done.
Updating files: 100% (79/79), done.
複製程式碼
倉庫地址在gitee倉庫頁面獲取
- 切換到clone完成的專案目錄下,在資料夾中新增檔案,並使用git add 將檔案新增到git管理中
# 切換到專案資料夾下
$ cd somerepo/
# 使用vi建立一個文字檔案
$ vi somecode.txt
# 檢視當前目錄下的檔案狀態,可見是Untracked files
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
somecode.txt
nothing added to commit but untracked files present (use "git add" to track)
# 使用git add將檔案加入到git管理範圍內
$ git add somecode.txt
warning: LF will be replaced by CRLF in somecode.txt.
The file will have its original line endings in your working directory
# 此時檔案狀態變為 new file
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: somecode.txt
複製程式碼
- git status 檢視工作區狀態
- git commit 提交到本地的程式碼倉庫
git commit -m 提交訊息(說明本次提交的作用)
$ git commit -m '新增重要程式碼'
[master bb5a735] 新增重要程式碼
1 file changed, 1 insertion(+)
create mode 100644 somecode.txt
複製程式碼
- git push 推到遠端,這一步可能會彈出驗證框,需要你填入使用者名稱,密碼,則按照註冊gitee時的使用者名稱密碼填寫
$ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 314 bytes | 157.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.0]
To https://gitee.com/somename/somerepo.git
afbb494..bb5a735 master -> master
複製程式碼
- git log 檢視日誌記錄,後面跟檔案路徑即可檢視某個檔案的變更記錄
$ git log
commit bb5a7350d504b5e26fc6d1932e2165cc31aedbff (HEAD -> master, origin/master, origin/HEAD)
Author: xxx <xx.xxx@163.com>
Date: Thu Jul 22 16:54:45 2021 +0800
新增重要程式碼
複製程式碼
- 在gitee倉庫管理頁面,直接新增一個檔案,隨便填一些內容,便於模擬拉取
- git pull 拉取遠端的修改
$ git pull
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 268 bytes | 15.00 KiB/s, done.
From https://gitee.com/somename/somerepo.git
bb5a735..fd0f532 master -> origin/master
Updating bb5a735..fd0f532
Fast-forward
abc.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 abc.txt
複製程式碼
4.3 解決衝突
衝突的產生是因為兩個客戶端同時修改了同一個檔案的同一個位置,git無法自動合併,因此爆出衝突。
解決衝突的原則:先商量,再操作,嚴禁不商量直接覆蓋別人的程式碼
模擬方式:同時在本地和gitee倉庫管理頁修改somecode.txt 的同一行
1)修改gitee倉庫中的somecode.txt,提交編輯(無須推送,立即就應用到程式碼倉庫裡了)
- 點選檔案,進入檔案介面,選擇編輯檔案
- 內容改為 java123
2)提交原生程式碼,並push,會直接報錯
# 修改同一檔案,內容改為 java456
$ vi somecode.txt
# 再次新增修改
$ git add somecode.txt
warning: LF will be replaced by CRLF in somecode.txt.
The file will have its original line endings in your working directory
# 提交
$ git commit -m 製造衝突
[master 61fca79] 鍒墮€犲啿紿? 1 file changed, 1 insertion(+), 1 deletion(-)
# 推送,與遠端衝突,無法推送,要求先拉取(pull)
$ git push
To https://gitee.com/maizdotme/class56phrase3.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://gitee.com/maizdotme/class56phrase3.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
# 拉取後報檔案衝突
$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 261 bytes | 16.00 KiB/s, done.
From https://gitee.com/maizdotme/class56phrase3
e9d1c58..9ceecd7 master -> origin/master
Auto-merging somecode.txt
CONFLICT (content): Merge conflict in somecode.txt
Automatic merge failed; fix conflicts and then commit the result.
複製程式碼
3)解決衝突
衝突後的檔案內容改為:
<<<<<<< HEAD
java456
=======
java123
>>>>>>> 9ceecd77ce954380e3f4a75e0aa4a9df6b67ce4f
複製程式碼
=======
之上的內容為本地內容 ,之下的是遠端伺服器上的
手工修改檔案內容,之後再add、commit、push即可
# 修改內容為 java123456
$ vi somecode.txt
$ git add somecode.txt
$ git commit -m 合併衝突
[master 0415e1e] 合併衝突
# 推送成功
$ git push
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 552 bytes | 184.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.0]
To https://gitee.com/maizdotme/class56phrase3.git
9ceecd7..0415e1e master -> master
複製程式碼
五、IDE整合
以上介紹了git的基本操作。但通常我們的開發是在IDE中進行的。如何在IDE中使用GIT呢?
這裡以idea為例介紹一般IDE中的整合用法。
idea可以自動識別git專案,因此當你將一個git專案匯入idea時,idea就會自動新增git支援。
根據個人經驗,如果想在idea中使用git管理專案。建議按如下步驟操作:
- 在雲端建立git倉庫
- clone到本地
- 將專案程式碼放到該程式碼倉庫中 或者 建立專案時將專案程式碼位置指向該程式碼倉庫
- 匯入專案到idea中,idea會自動識別
常見操作支援:
clone
選擇選單欄VCS > Get from version control
填入git倉庫地址,選擇資料夾路徑
結束後會彈出詢問框,是否開啟新專案
add
idea會在新建檔案之後詢問是否加入到git,也可以勾選記住選項
這裡需要提一下 .gitignore
檔案,這個檔案可以放置在專案的根目錄下,列出git需要忽略的檔案,比如,maven專案的target資料夾, .idea
資料夾,idea的 .iml
檔案等。git每次提交時會自動忽略這些檔案。建議使用上。
commit
使用快捷鍵 ctrl+k
push
使用快捷鍵 ctrl+shift+k
pull
使用快捷鍵 ctrl+t
log
idea識別出git專案後會提供git日誌檢視介面
解決衝突
當出現衝突時,選擇點選衝突檔案即可進入以下的衝突解決介面,點選④和⑤處的加入到結果或者取消
其他
另外,還有兩個地方是跟git有關的,這兩個地方就可以完成所有的git相關的功能了
一個是在專案上右擊選擇Git選單
另一個 是在頂部選單 VCS
選單下
六、總結
本文主要是介紹VCS的概念,及Git的基本使用。內容比較粗淺,旨在幫助大家快速瞭解到Git的基本概念及基本使用。細節有不清晰的地方,可以提出探討。
無論你在學習上有任何問題,重慶蝸牛學院歡迎你前來諮詢,聯絡QQ:296799112
資源:
- Git官方的開源書籍 《Pro Git》線上中文版 git-scm.com/book/zh/v2
- 廖雪峰的GIT教程 www.liaoxuefeng.com/wiki/896043…
- backlog的有趣GIT教程 backlog.com/git-tutoria…