Git開發者教程

一、什麼是git?

1.1、簡介

git是一個分佈式版本控制軟件,最初由林納斯·託瓦茲創作也就是偉大的Linux創始人Linus創作。

1.2、常見代碼託管平臺

  • 全世界最大的代碼託管網站: https://github.com/
  • 國內較多用戶使用的網站:https://gitee.com
  • 可以免費搭建自己的代碼託管網站的 gitLab
  • 版本控制工具還有cvs、svn

1.2、對比svn

簡單列舉一些和svn的比較:

  • svn是集中式版本控制系統,git是分佈式版本控制系統
  • svn是直接與服務器進行交互,git是將文件存到本地然後再推送到服務器
  • svn必須在連網的情況下工作,git可以不連網開發
  • svn易發生衝突,git相對於svn不易發生衝突
  • svn適用於多項目並行開發,git適用於單項目開發
  • git內容完整性要優於svn,git內容存儲使用的是SHA-1哈希算法,這能確保代碼內容的完整性,確保在遇到磁盤故障和網絡問題時降低對版本庫的破壞。
  • 相比svn,git對分支的隔離是邏輯隔離而不是物理隔離,這意味着創建分支非常快速、存儲分支不會佔用過多磁盤空間

二、git分支介紹

2.1、概念

  • 分支(branch)可以理解爲是倉庫(repository)的一種隔離視圖。
    分支的目的爲了支持多人、多版本開發。

  • Git支持多分支開發,並鼓勵使用本地多分支,這些分支之間是彼此完全獨立的。

  • 常見的分支操作包括:創建分支、切換分支、合併分支、刪除分支。

2.2、常見分支操作

2.2.1. 創建分支:給分支名取一個簡短且有意義的名字。
2.2.2. 提交改動:填寫有意義的commit message: what & why,推薦的commit message格式爲 : ,比如:512: 增加了對NFS的支持。
2.2.3. 發起合併請求:同時發起code review和討論,不經過review的代碼不允許合併進public branch。
2.2.4. 代碼評審和討論:

  • 審查代碼是否滿足功能、規範、測試結果、測試覆蓋等要求。
  • 審查合格才允許合併合進public branch,不合格的代碼退回重新修改。
  • 鼓勵使用同行評審(Peer Review)而不是上下級評審,鼓勵積極反饋、互動。
  • 評審對事不對人,多建議,不批評,不指責。
  • 評審過程對reviewer和代碼提交者雙方都是一個學習提升的過程。
  • 部署:使用經過完整測試的分支來部署到生產環境,部署後發生問題需要回退時,用上一個版本進行回退。
  • 合併回master分支。

部署成功,沒有問題後才合併到master分支。

三、分支策略

用git首先得了解項目需要採用哪一種分支策略。
目前主流的git工作流模式有git flow、github flow、gitlab flow,需要根據軟件集成方式和團隊規模和協作方式,調整自己團隊的分支策略。
幾種模型各有所長,下面簡述一下

  • git flow:出現時間最早,基於git的workflow的開山鼻祖,可以說給出了一個git flow的最佳實踐,缺點是流程比較複雜,release branch和hotfix branch幾乎沒人使用,另外需要長期維護master和dev兩個分支,在規模不大的場景下維護成本比較高
  • github flow:相當精簡,只有master主幹和feature branch這兩種,結構相當清晰,缺點是master默認爲當前上線的最新版本,在對於版本管理要求比較複雜的場景下靈活性不足
  • gitlab flow:出現的最晚,可以說集合了前兩家的長處,既保證只有一個長期主幹,結構清晰,同時也定義了不同場景下的branch,增強了靈活性。

3.1、git flow簡介

大多數公司都基於git flow的模式,並在此基礎上做了調整。
在這裏插入圖片描述

3.2、其他工作流模式

工作流模式每個公司的不一樣,都可能在gitflow的基礎上做了很大改動
下面列舉三種基於gitflow的改造後模式。

3.2.1、模式一

模式一簡要描述:

  • 功能模塊的同一個feature分支開發人員共同開發(也可額外創建自己的分支定期push到feature)
  • 一個feature對應一個測試環境
  • 功能分支sit測試完成後,直接到release版本
  • release版本驗收成功之後發生產。
  • hotfixes直接基於master進行修改和上線。
    在這裏插入圖片描述

3.2.2、模式二

每個開發者都有自己的分支,時不時地往dev分支上合併就可以了。跟模式一的區別在於,模式一的測試環境主要以feature爲準,到測試基本完成後發佈到develop的基本是小改動,小改動驗收完成後直接develop到生產,而模式而強調每個人一個分支,測試主要以develop爲準。

所以,團隊合作的分支看起來就像這樣:
在這裏插入圖片描述
對於多個業務模塊並行開發的具體場景如下
在這裏插入圖片描述

3.2.3、模式三

模式三和模式一、模式二很類似,主要區別在於不需要每個開發者創建分支,共同在一個feature分支上面去做開發。模式三和模式一的區別在於,模式一強調以feature分支作爲開發和測試的分支,而模式一穩定版本後直接發佈到release分支,而模式三強調所有修改以develop爲測試基準,測試完成直接發佈到master。

  • 開發【feature分支】:從develop拉新分支,命名feature/迭代版本號_功能說明,不可以從feature分支再拉新分支
  • 測試【develop分支】:將feature分支合併到develop分支,再部署到測試環境
  • 發佈【master分支】:將develop測試後的穩定版本合併到master分支,打版本標籤,再進行發佈,未經測試的不穩定代碼不可以合併到master
  • 修復線上問題【hotfix分支】:從master分支拉新分支,命名hotfix/xxx,修復bug後合併到master分支,再將修復從master分支合併到develop分支
    在這裏插入圖片描述

3.2.4、幾種模式對比

模式名稱 本地分支 測試環境分支 預生產環境 線上分支
模式一 feature/** feature/** release master
模式二 blob/john develop master
模式三 feature/** develop master

四、安裝和運行

登錄git官網: https://git-scm.com/ 下載git for windows,安裝後有3個程序:

  • git bash (模擬linux終端)- git cmd (windows終端)
  • git gui (windows界面)

推薦使用git bash,git cmd和git gui可以忽略。

在linux和mac上使用git和在windows上使用git bash一樣,不再贅述。
現在主流的ide(比如intellij idea和eclipse) 都對git有非常好的支持。
推薦通過ide + git bash 方法來使用git。

五、git開發操作流程

5.1、基本操作概覽

# master創建新分支:
git checkout master
# 創建並切換到 issues1234
git checkout -b  issues1234
# 推送新分支到遠程倉庫
git push origin issues1234
# 添加所有本地修改文件
git add ..
# commit所有本地修改文件到本地倉庫
git commit -m "***"
# push到遠程倉庫
git push origin issues1234

如下兩圖,主要區別在於

  • 圖一直接拉取git現有代碼,
  • 圖二初始化之後關聯遠程空倉庫

5.2、操作流程步驟

基本開發流程如:

  1. 建立遠程倉庫
  2. 拉取遠程倉庫代碼同步到本地倉庫和workspace
  3. 創建分支
  4. 基於分支開發
  5. 提交開發代碼並同步到倉庫(提交前先pull遠程代碼,如果有衝突則需要比對並解決衝突)
    在這裏插入圖片描述
    在這裏插入圖片描述

六、常用命令

常用命令比如:拉取、提交、添加、對比、提交、刪除、創建分支、合併分支、merge、強制回退、還原、部分還原、查看歷史,設置全局用戶名密碼、git免登陸、代碼審查

6.1、命令文檔

6.2、git help

在這裏插入圖片描述

6.3、git常用命令速查表

在這裏插入圖片描述
git:http和ssh的區別

七、常見場景

7.1、在gitlab上新建一個項目(repository)

7.1.1、 操作步驟

  1. 打開gitlab首頁
  2. 點擊new project按鈕
  3. 進入blank project填寫 項目名、項目描述(選填)、是否公開的項目
  4. 點擊 create project。

7.1.2、創建完成之後,

  1. 進入新建項目的首頁
  2. 找到clone 按鈕
  3. 查看git 地址,分爲http方式和ssh方式兩個地址

地址分爲SSH和HTTP(S)兩種方式如:

SSH和HTTP(S)兩種方式的主要區別是:

  • SSH方式需要將本地的SSH public key添加到GitLab賬號的setting中,比較安全。
  • HTTP(S)方式第一次push到GitLab時需要提供用戶名和密碼登陸,操作比較簡單。
    在這裏插入圖片描述
    在這裏插入圖片描述

7.2、遠程gitlab項目clone到本地

7.2.1、設置git config的user.name 和 user.email :

# 查看git config
git config --list

# 設置Global的user.name和user.email
git config --global user.name user_name
git config --global user.email user_email

# 查看git config確認
git config --list

7.2.2、從gitLab上clone一個repository到本地:

# SSH 方式
git clone <repo_git_url>

# HTTP 方式
git clone <repo_http_url>

7.3、分支管理

7.3.1、本地創建、切換分支

從master分支創建dev分支並切換到dev分支

# 切換到master分支
git checkout master
# 基於master分支,創建並切換到dev分支
git checkout -b dev

其中,git checkout -b dev 等價於:

# 創建dev分支
git branch dev
# 切換到dev分支
git checkout dev

查看本地當前的分支

# 查看本地當前的分支,分支前面帶“*”表示當前分支,剩下的分支表示本地有的分支。
git branch
# 查看遠程全部的分支,白色的表示本地有的,紅色的表示本地沒有,僅在遠程存在。
git branch -a

在這裏插入圖片描述

7.3.2、分支常見操作

 
# 列出所有本地分支
$ git branch
 
# 列出所有遠程分支
$ git branch -r
 
# 列出所有本地分支和遠程分支
$ git branch -a
 
# 新建一個分支,但依然停留在當前分支
$ git branch [branch-name]
 
# 新建一個分支,並切換到該分支
$ git checkout -b [branch]
 
# 新建一個分支,指向指定commit
$ git branch [branch] [commit]
 
# 新建一個分支,與指定的遠程分支建立追蹤關係
$ git branch --track [branch] [remote-branch]
 
# 切換到指定分支,並更新工作區
$ git checkout [branch-name]
 
# 切換到上一個分支
$ git checkout -
 
# 建立追蹤關係,在現有分支與指定的遠程分支之間
$ git branch --set-upstream [branch] [remote-branch]
 
# 合併指定分支到當前分支
$ git merge [branch]
 
# 選擇一個commit,合併進當前分支
$ git cherry-pick [commit]
 
# 刪除分支
$ git branch -d [branch-name]
 
# 刪除遠程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]

7.4、提交本地代碼修改到gitlab(開發日常)

7.4.1、本地代碼提交流程

本地開發流程如下圖步驟,中間可能涉及到文件對比、代碼衝突合併解決見其他場景

  1. pull最新的遠程代碼
  2. add本地修改的文件
  3. commit到本地倉庫
  4. push到遠程倉庫

在這裏插入圖片描述

7.4.2、命令行方式提交

快速提交的方式:

# git 添加文件三步驟

git add filename 或者默認提交所有新改動文件 git add .

git commit -m "本次提交描述信息"

git push origin master

帶比對功能的提交方式

# 更新working directory
git pull

# 改動代碼...此處省略2048個字

# 查看working tree狀態
git status

# 比較改動前後,查看改動了什麼 (用IDE來比較更加直觀)
git diff <file>

# 添加新建的文件到Git Stage中,或添加全部新建的文件到Git Stage中
git add <file>  # 和下面的命令二選一
git add .       # 和上面的命令二選一

# 提交改動到local repository
git commit -m "本次提交的消息"

# 推送到remote repository,創建remote new branch,並設置upstream reference
git push -u origin matser  #或者其他分支

# 如果第一次push時不通過-u 來push新的branch,在git pull時會提示要先設置upstream reference
# 設置upstream reference
git branch --set-upstream-to=origin/<branch> <branch>

#之後的push可以不需要再加-u參數:
git push origin <branch>


在這裏插入圖片描述

7.4.3、idea方式提交

  1. 確認當前所在分支
  2. pull遠程最新代碼到本地
  3. 查看本地的local changes代碼改動,和改動前做比對
  4. 選中要提交的代碼,右鍵點擊commit
  5. 進入commit的窗口,再次確認是否勾選剛剛勾選的文件
  6. 也可以在這個窗口中進行文件對比,比local changes中對比更方便
  7. 填寫commit信息,儘量描述清楚本次修改點,以便bug修復跟蹤和代碼review或者回退
  8. 去除勾選的右邊代碼分析之類的操作,加快提交速度
  9. 下拉commit選項,選擇commit and push,即可完成提交。(如果沒有信心是否提交成功,或者只commit到本地了倉庫了,那麼可以去頂部菜單欄找到VCS–>Git->Push。點擊push即可查看本地倉庫未推送的提交記錄,並點擊推送),也可以去gitlab的項目頁面去查看最新提交記錄)
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述

7.5、 增加/刪除文件

7.5.1、命令行方式

 
# 添加指定文件到暫存區
$ git add [file1] [file2] ...
 
# 添加指定目錄到暫存區,包括子目錄
$ git add [dir]
 
# 添加當前目錄的所有文件到暫存區
$ git add .
 
# 添加每個變化前,都會要求確認
# 對於同一個文件的多處變化,可以實現分次提交
$ git add -p
 
# 刪除工作區文件,並且將這次刪除放入暫存區
$ git rm [file1] [file2] ...
 
# 停止追蹤指定文件,但該文件會保留在工作區
$ git rm --cached [file]
 
# 改名文件,並且將這個改名放入暫存區
$ git mv [file-original] [file-renamed]

7.5.2、idea的方式

  • 直接常規操作複製到本項目即可,idea自動把文件添加到git的local changes中
  • 刪除同添加一樣刪除後在local changes中會變成灰色的文件

在這裏插入圖片描述

7.6、 本地新項目上傳到git

7.6.1、(先進入項目文件夾)通過命令 git init 把這個目錄變成git可以管理的倉庫

git init

7.6.2、把文件添加到版本庫中,使用命令 git add .添加到暫存區裏面去,不要忘記後面的小數點“.”,意爲添加文件夾下的所有文件

git add .

7.6.3、用命令 git commit告訴Git,把文件提交到倉庫。引號內爲提交說明

git commit -m "first commit"

6.6.4、關聯到遠程庫

git remote add origin 你的遠程庫地址
如:
git remote add origin https://github.com/githubusername/demo.git

7.6.5、獲取遠程庫與本地同步合併(如果遠程庫不爲空必須做這一步,否則後面的提交會失敗)

git pull --rebase origin master

7.6.6、把本地庫的內容推送到遠程,使用 git push命令,實際上是把當前分支master推送到遠程。執行此命令後會要求輸入用戶名、密碼,驗證通過後即開始上傳。

git push -u origin master

7.6.7、狀態查詢命令

git status

7.7、 配置.gitignore忽略提交文件

在項目根目錄下創建.gitignore文件。.gitignore 文件內容如下

/.idea/
/target/
/log/
application-uat.yml
!.mvn/wrapper/maven-wrapper.jar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
.lst
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

在項目目錄下執行該命令

git rm -r --cached .
git add .
git commit -m "update .gitignore"

7.8、 reset/revert版本回退

7.8.1、reset/revert比對

假設有一次提交a文件前commit id 爲 34719a7,提交的commit id爲34719a8,接着又有人提交了b、c文件,提交的commit id爲34719a9,如下表:

tag commit id commit 的文件 操作
34719a7
34719a8 a.java 把數據庫地址從192變成了127
head 34719a9 b.java、c.java b、c的查詢db方法都改成查詢redis,a地址變爲localhost

基於34719a9進行回退到34719a8

  • revert:僅會把a文件回退到34719a8變更前的內容,其他文件不會變動,
    即:34719a7提交後a文件=revert後的a文件,最終a的內容還是192。
  • reset:回退到那次commit id=34719a8提交後的樣子,後面的b、c文件也全盤迴退,即34719a8 commit後項目內容=reset 到 34719a8項目內容,最終b、c還是查詢db,a數據庫地址爲127。

如下表

操作 回退前commit id 回退版本commit id 操作前 操作後
revert 34719a9 34719a8 a爲127,b、c連接redis a變爲192,b、c的不變,查詢redis
reset 34719a9 34719a8 a爲127,b、c連接redis a變爲127,b、c的變化,查詢db方法

7.8.2、版本回退

對於本次變動的回退,一般情況建議使用revert,以防使用reset把其他開發人員提交的代碼給回退了。

7.8.2.1、在本地改動後,在git add 前回退,撤銷本地改動:

git checkout -- <file>

推薦使用idea的revert功能,更加簡單直觀。
控制檯-> local changes -> 右鍵 -> revert

7.8.2.2、在本地改動後,在git push 前回退,這裏直接用遠程覆蓋可以直接用reset
用遠程repository強制替換本地文件:

git fetch origin
git reset --hard origin/<branch>

推薦使用idea的reset功能,更加簡單直觀。
version control->log -> 右鍵選擇最後一次提交-> Reset current branch to here -> select “Hard”

7.8.2.3、在本地改動後,在git push後回退

  • 方法一:手工回退後,重新提交改動去覆蓋remote branch。

  • 方法二:使用idea的revert功能。(推薦)
    version control ->log -> 右鍵點擊revert -> 填寫commit的message。

  • 方法三:根據commit id 手動回退
    方法三如下操作

#查看git commit log,複製要回退的版本commit id
git log --graph --oneline --decorate --all
#將本地回退到指定版本
git reset --hard <commit_id>


# 查看working tree狀態,此時本地落後於遠程1個commit
git status

# 強制用本地覆蓋遠程(危險操作!!)
git push -f origin <branch>

# 再次查看working tree狀態,此時本地和遠程應該同步
git status

推薦使用方法二

方法三比較危險,不推薦使用;強烈建議通過protect branch來防止強制用本地覆蓋遠程分支。

7.9、 查看文件修改歷史

# 按樹形結構顯示
git log --graph --oneline --decorate --all [file]

# 按列表顯示
git log --pretty=oneline [file]

# 簡單粗暴顯示
git log [file]

7.10、文件對比與解決衝突

7.10.1、命令行文件對比

# 比較改動前後,查看改動了什麼 (用idea來比較更加直觀)
git diff <file>

# 顯示暫存區和工作區的差異
$ git diff
 
# 顯示暫存區和上一個commit的差異
$ git diff --cached [file]
 
# 顯示工作區與當前分支最新commit之間的差異
$ git diff HEAD
 
# 顯示兩次提交之間的差異
$ git diff [first-branch]...[second-branch]
 
# 顯示今天你寫了多少行代碼
$ git diff --shortstat "@{0 day ago}"
# 顯示出所有有差異的文件列表
git diff branch1 branch2 --stat 

# 顯示指定文件的詳細差異
git diff branch1 branch2 具體文件路徑

# 顯示出所有有差異的文件的詳細差異
git diff branch1 branch2                   

7.10.2、idea中文件對比

如圖可見,可以與歷史版本或者其他分支的該文件進行對比,比命令行更加直觀
在這裏插入圖片描述

7.10.3、命令行解決文件衝突

7.10.3.1、發生衝突的文件

<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1

其中,git使用<<<<<<<,=======,>>>>>>>標記文件中自己和別人產生衝突的部分。

在<<<<<<<,=======之間爲自己的代碼;
=======,>>>>>>>之間爲別人的代碼。

如果保留自己的代碼,將別人的代碼刪掉即可。

7.10.3.2、衝突解決後提交

git status

git add ***

git commit -m "fix conflict"

git push origin 分支名

7.10.4、idea解決文件衝突

產生衝突的場景

  • accept yours:代表以自己的爲準;

  • accept theris:代表以更新下來的文件爲準;

  • merge:代表手動合併

  • 一般解決衝突我們都是選擇merge

將需要的內容點擊:">>"既可以合併內容到result中,不需要的內容點擊“x”即可,合併完成後點擊apply即可。

值得注意的是,最將所有的“x >>”符號都要處理完,不需要的點擊“x”,需要的點擊“>>”
最後,不論是什麼場景下產生的衝突解決方法是一樣的。
在這裏插入圖片描述
在這裏插入圖片描述

7.11、合併分支

7.11.1、命令行合併

對於複雜的系統,我們可能要開好幾個分支來開發,具體git合併操作如下

1、進入要合併的分支(如本地分支luo合併到develop,則進入develop目錄)
git checkout develop
git pull

2、使用merge合併luo分支到develop
git merge luo

3、查看合併之後的狀態
git status

4、有衝突的話,通過idea解決衝突,比命令行直觀;

5、解決衝突之後,將衝突文件提交暫存區
git add 衝突文件

6、提交merge之後的結果
git commit

如果不是使用git commit -m "備註" ,那麼git會自動將合併的結果作爲備註,提交本地倉庫;

7、本地倉庫代碼提交遠程倉庫
git push

將develop合併到開發者本地分支、開發分支合併到master操作相同,合併慎重,避免錯誤提交導致頻繁回退的麻煩。

7.11.2、idea合併

把2.1.0分支合併到master步驟
1、拉取最新代碼
2、切換到master
3、如果有衝突或者其他異常,則再一次拉取代碼,直到確保切換到最新的master
4、選擇origin/2.1.0分支
5、點擊merge into current。
6、如果有衝突,則文件比對解決衝突
7、完成了2.1.0合併到master的操作
8、push代碼到遠程倉庫,選擇vsc->git->push
9、完成
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

八、代碼review

  • 代碼審查,通過merge request。
  • 審查代碼是否滿足功能、規範、測試結果、測試覆蓋等等。
  • 藉助工具來提升代碼審查的效率。
  • 審查合格才允許合進public branch,不合格的代碼退回重新修改。
  • 鼓勵使用同行評審(Peer Review)而不是上下級評審,鼓勵積極反饋、互動。

九、參考文檔

git flow
https://nvie.com/posts/a-successful-git-branching-model/
git版本控制、分支策略與代碼評審
https://blog.csdn.net/nklinsirui/article/details/80303605
常用git命令
https://blog.csdn.net/web_csdn_share/article/details/79243308
idea中的解決git文件衝突
https://www.cnblogs.com/newAndHui/p/10851807.html
git操作
https://segmentfault.com/a/1190000014461898
其他
https://www.cnblogs.com/hezhiying/p/9292314.html
https://www.cnblogs.com/aylin/p/6042653.html
https://www.jianshu.com/p/c2aefcf6b2b7
https://www.cnblogs.com/Gaoqiking/p/11116380.html
https://www.jianshu.com/p/1889b0fe073b

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章