版本信息
時間 | 版本 | 描述 |
---|---|---|
2021-03 | 1.0 | git版本控制介紹 |
關于GIT
GIT是一個分布式版本控制系統;什么是“版本控制”?版本控制是一種記錄一個或若干文件內容變化,以便將來查閱特定版本修訂情況的系統。
版本控制演變過程
本地版本控制
本地保存不同的版本,最流行的方式是RCS(一種用軟件實現自動存儲、檢索、日志記錄、識別、和合并修訂的系統)
- 優點: 簡單
- 缺點:出錯率高
中心化版本控制
通過中央服務器,保存所有文件的修改版本,協同工作的用戶通過客戶端連接中央服務器,拉取最新的文件或者提交更新。代表系統有Subversion
- 優點:用戶可以協同工作、管理員吧方便管理用戶進度
- 缺點:中央服務器故障數據損壞恢復困難
分布式版本控制
客戶端把代碼倉庫完整地鏡像下來,包括完整的歷史記錄,操作完全本地。代表系統有git
- 優點:可以離線本地操作速度快,切換靈活;服務器故障可以通過任何一個本地鏡像恢復數據包括提交記錄;
- 缺點:工作目錄只能是整個目錄,不支持單個目錄;權限控制一般通過文件讀寫權限實現;
git安裝和配置
git安裝
git配置
Git 自帶一個 git config
的工具來幫助設置控制 Git 外觀和行為的配置變量。
配置優先級:
項目內config(local) > 系統用戶config(global) > git自帶config(system)
通過命令git config --list --show-origin
可以查看配置及配置來源
常用配置命令如下,設置您的用戶名和電子郵件地址,用于每次提交
git config --global user.name "張三"
git config --global user.email zs@abc.com
ssh公鑰配置
cd ~/.ssh
# ssh-keygen -t rsa -C 'email@abc.com'
cat ~/.ssh/id_rsa.pub
# 添加公鑰
git工作流程
本地開發的工作流程
基本概念
-
HEAD
HEAD
是當前分支引用的指針,它總是指向該分支上的最后一次提交。 這表示HEAD
將是下一次提交的父結點。 通常,可以把HEAD
看做你的上一次提交的快照。可以簡單理解為: HEAD 指向分支(branch),分支指向提交 -
Index
Index(索引,或暫存區)是你預期的下一次提交
-
Workplace
工作目錄
多人協作的工作流程
git傳輸協議
本地協議
本地協議(Local protocol) :遠程版本庫就是同一主機上的另一個目錄
- 優點:基于文件系統的版本庫的優點是簡單,并且直接使用了現有的文件權限和網絡訪問權限。
- 缺點點:共享文件系統比較難配置,并且比起基本的網絡連接訪問,這不方便從多個位置訪問
http協議
-
智能 HTTP 協議
智能 HTTP是運行在標準的 HTTP/S 端口上并且可以使用各種 HTTP 驗證的協議
-
啞(Dumb) HTTP 協議
啞 HTTP 協議里 web 服務器僅把裸版本庫當作普通文件來對待,提供文件服務
優點:1.支持賬號密碼授權 2.可用性高 3.傳輸速度快
缺點點:使用需授權的推送,管理憑證會比使用 SSH 密鑰認證麻煩
ssh協議
ssh協議是一個驗證授權的網絡協議
- 優點:SSH 架設相對簡單
- 缺點點:SSH 協議的缺點在于它不支持匿名訪問 Git 倉庫
git協議
git協議是包含在 Git 里的一個特殊的守護進程;它監聽在一個特定的端口(9418),類似于 SSH 服務,但是訪問無需任何授權
- 優點:網絡傳輸快
- 缺點:缺乏授權機制
git內部原理
git 數據存儲方式
Git實際上是一個鍵值對數據庫(key-value data store)。 Git 存儲內容的方式一個文件對應一條內容,存儲一份數據,返回一個40位的 Hash 值作為鍵值。Hash 值的前兩位作為目錄,后38位為文件名。文件的內容就是 鍵值對 的 值 ,也就是 Git 存儲的一系列數據。
git對象
git cat-file -t commitHash
查看文件對象類型
-
數據對象
數據對象來記錄每一個文件的數據
-
樹對象
Git 在每次提交時,會將暫存區的所有數據保存起來,產生一個 樹對象 。樹對象中的數據記錄了在提交前,通過記錄暫存區中每個文件的數據對象的 鍵 值,記錄處于暫存區中的每個文件的狀態。
image-20210312104025811 -
提交對象
每次向 Git 倉庫中提交文件時,Git 會生成一個提交對象,用以保存當前提交的信息,包括此次提交的父提交對象,作者的信息等
git命令
git help
基礎命令
創建項目
-
git init
git init 初始化git倉庫
-
git clone
git clone remoteUrl 克隆倉庫
快照操作
-
git add
git add . 創建索引
-
git commit
git commit -a -m 'feat: message' 提交本地代碼
-
git reset
-
reset后發生了什么?
- 移動 HEAD 指向的分支
- 使索引看起來像 HEAD
- 使工作目錄看起來像索引
重置影響范圍
-
“HEAD” 一列中的 “REF” 表示該命令移動了 HEAD 指向的分支引用,而 “HEAD” 則表示只移動了 HEAD 自身。 特別注意 WD Safe? 一列——如果它標記為 NO,那么運行該命令之前請考慮一下
- git revert
- git revert 和 git reset 的區別
- git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit
- git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch時,導致這部分改變不會再次出現,但是git reset是之間把某些commit在某個branch上刪除,因而和老的branch再次merge時,這些被回滾的commit應該還會被引入
日志
-
git log
git log 操作日志
-
git reflog
git reflog 全部操作日志
-
git diff
git diff
-
git status
git status 當前git狀態查看
工具命令
貯藏
-
git stash
保存修改到本地,用于想要切換分支,但是還不想提交之前的改動
git stash list
git stash pop/apply
git stash branch branchName
git grep 搜索
分支管理命令
Git 的分支其實本質上僅僅是指向提交對象的可變指針
-
git branch
git branch -b branchName 從當前分支切換并創建新的分支
git branch -a 查看全部分支
-
git checkout
git checkout 切換分支
-
git fetch
git fetch 同步遠程倉庫信息到本地
-
git tag
git tag 標簽列表
git tag tagName 打標簽
-
git merge
git merge origin master 合并分支
-
git rebase
- git rebase origin master
-
git merge和 git rebase的區別
-
merge:自動創建一個新的commit
- 優點:記錄了真實的commit情況,包括每個分支的詳情
- 缺點:因為每次merge會自動產生一個merge commit,所以在使用一些git 的GUI tools,特別是commit比較頻繁時,看到分支很雜亂
-
rebase: 會合并之前的commit歷史
- 優點:得到更簡潔的項目歷史,去掉了merge commit
- 缺點:如果合并出現代碼問題不容易定位,因為re-write了history
-
刪除分支
-
git branch -d
git branch -d branchName 刪除本地分支
git push origin -d branchName 刪除遠程分支
其他
-
git cherry-pick
將代碼從一個分支轉移到另一個分支(通常是部分變動)
git cherry-pick commitHash 合并某次提交
git cherry-pick branchName 合并分支的最新提交
git cherry-pick --coutinue 合并沖突后解決完成繼續合并
git cherry-pick --abort 合并沖突還原
git常見場景
倉庫遷移
問題描述:如何遷移代碼到另一個倉庫?
cd existing_repo
git remote rename origin old-origin
git remote add origin https://gitlab.com/dujf54732/test.git
git push -u origin --all
git push -u origin --tags
版本回退
問題描述:剛合并到master的代碼發現有問題,需要將master 回滾到上一個版本,并且修復有問題代碼后重新合并到master?
reset
git reset --hard commitHash # 重置到哪一個提交
git push origin -f branchName # 1有丟失代碼風險 2如果又其他人協同開發,版本回退可能失敗
# 其他人需要同步遠程版本
git reset --hard origin/branchName
revert
# 回滾主分支代碼
git checkout master
git checkout -b master-revert
git revert commitFrom^..commitEnd
git commit -a -m 'fix: revert to lastest'
git push origin master-revert
# 合并到master
# 修改版本分支缺陷
git checkout master
git fetch
git merge orgin/master
git checkout -b master-feature
# 挑選之前有效的代碼
git cherry-pick commitHash1 commitHash1
# 修復缺陷
git commit -a -m 'fix: bugs'
git push origin master-feature
# 再次合并到master
git規范
分支規范
推薦合并到master的代碼全部通過merge request,然后coding review后再合并到master,master禁止commit和push
提交規范
commit message格式
type: description
type常用類型
feat - 新功能 feature
fix - 修復 bug
docs - 文檔注釋
style - 代碼格式(不影響代碼運行的變動)
refactor - 重構、優化(既不增加新功能,也不是修復bug)
test - 增加測試
revert - 回退
build - 打包
description
對本次提交的描述,推薦以設置、修改、增加、刪減、撤銷開頭。
feat: add XXXX
fix: 1. modify XXXX
2. modify XXXX