git 使用手冊
- 版本:v1.0.3
- 初始日期:2020-10-18
- 最后修訂日期:2022-05-18
- 官方文檔 https://git-scm.com/book/zh/v2
- 下載鏈接 https://git-scm.com/downloads
- 視頻教程 https://www.bilibili.com/video/BV1PL411t7Xi?spm_id_from=333.999.0.0
基礎(chǔ)概念
分布式版本控制系統(tǒng)
三種狀態(tài)
區(qū)域 | 描述 |
---|---|
工作區(qū) | 本地的工作目錄 |
暫存區(qū) | stage 或者叫 index 的暫存區(qū),Git 自動創(chuàng)建的第一個(gè)分支 master肃廓,以及指向 master 的一個(gè)指針叫 HEAD |
Git倉庫 | 工作目錄里的一個(gè)隱藏目錄 .git |
狀態(tài) | 描述 |
---|---|
已提交(committed) | 數(shù)據(jù)已經(jīng)提交到本地倉庫中智厌,提交命令:git commit |
已修改(modified) | 數(shù)據(jù)在工作區(qū)已修改,未提交到暫存區(qū) |
已暫存(staged) | 數(shù)據(jù)已保存到暫存區(qū)盲赊,可批量提交到本地倉庫铣鹏,暫存命令 git add |
基本工作流程
- 工作區(qū)中修改文件
- 對修改的文件進(jìn)行快照,添加到暫存區(qū)
- 提交更新哀蘑,將保存在暫存區(qū)的文件快照永久存儲到 Git 倉庫中
基本配置
Git 自帶一個(gè) git config
的工具來幫助設(shè)置控制 Git 外觀和行為的配置變量诚卸。 這些變量存儲在三個(gè)不同的位置:
/etc/gitconfig
文件: 包含系統(tǒng)上每一個(gè)用戶及他們倉庫的通用配置。 如果在執(zhí)行git config
時(shí)帶上--system
選項(xiàng)绘迁,那么它就會讀寫該文件中的配置變量合溺。 (由于它是系統(tǒng)配置文件,因此你需要管理員或超級用戶權(quán)限來修改它缀台。)~/.gitconfig
或~/.config/git/config
文件:只針對當(dāng)前用戶棠赛。 你可以傳遞--global
選項(xiàng)讓 Git 讀寫此文件,這會對你系統(tǒng)上所有的倉庫生效。當(dāng)前使用倉庫的 Git 目錄中的
config
文件(即.git/config
):針對該倉庫恭朗。 你可以傳遞--local
選項(xiàng)讓 Git 強(qiáng)制讀寫此文件屏镊,雖然默認(rèn)情況下用的就是它。(當(dāng)然痰腮,你需要進(jìn)入某個(gè) Git 倉庫中才能讓該選項(xiàng)生效而芥。)
每一個(gè)級別會覆蓋上一級別的配置,所以 .git/config
的配置變量會覆蓋 /etc/gitconfig
中的配置變量膀值。
在同時(shí)對多個(gè) git 服務(wù)器操作時(shí)棍丐,需要確認(rèn)你的當(dāng)前用戶名和郵箱,建議全部使用 --local
級別的配置沧踏。
# 查看版本
git --version
# 查看配置
git config --list
git config -l
# 設(shè)置用戶名
git config --global user.name "姓名"
git config --local user.name "姓名"
# 沒有參數(shù)默認(rèn)等于 --local
git config user.name "姓名"
# 設(shè)置郵箱
git config --global user.email "郵箱地址"
git config --local user.email "姓名"
# 修改用戶名歌逢、郵箱
git config --global --replace-all user.name "姓名"
git config --global --replace-all user.email "郵箱地址"
# 刪除
git config --global --unset user.name "yourName"
git config --global --unset user.email "your@email.com"
本地倉庫
# 在已存在目錄中初始化倉庫,在 IDEA 中需要重新啟動后能看到項(xiàng)目文件狀態(tài)的改變
git init
# 添加文件到暫存區(qū)
git add <file>...
git add *
git add .
# 提交更新
git commit -m 'initial project version'
# 跳過暫存區(qū)域提交更新
git commit -a -m 'added new benchmarks'
# 檢查當(dāng)前文件狀態(tài)
git status
# 狀態(tài)簡覽
git status -s
# 查看本地倉庫
git ls-files
# 查看已暫存和未暫存的修改
git diff
# 查看提交歷史
git log
# oneline 會將每個(gè)提交放在一行顯示
git log --pretty=oneline
# -p 或 --patch翘狱,-2 選項(xiàng)來只顯示最近的兩次提交
git log -p -2
# 圖形化分支顯示日志
git log --graph --pretty=oneline
# 刪除文件秘案,如果要刪除之前修改過或已經(jīng)放到暫存區(qū)的文件,則必須使用強(qiáng)制刪除選項(xiàng) -f(譯注:即 force 的首字母)潦匈。 這是一種安全特性阱高,用于防止誤刪尚未添加到快照的數(shù)據(jù),這樣的數(shù)據(jù)不能被 Git 恢復(fù)茬缩。
git rm <file>
# 我們想把文件從 Git 倉庫中刪除(亦即從暫存區(qū)域移除)赤惊,但仍然希望保留在當(dāng)前工作目錄中。 換句話說凰锡,你想讓文件保留在磁盤未舟,但是并不想讓 Git 繼續(xù)跟蹤。
git rm --cached <file>
# 移動文件
git mv <file_from> <file_to>
# 取消暫存的文件
git reset HEAD <file>...
# 取消三個(gè)版本的暫存文件
git reset --hard HEAD^^^
git reset --hard HEAD~3
git reset --hard <版本標(biāo)識符>
# 撤消對文件的修改掂为、還原工作區(qū)刪除的文件
git checkout -- <file>...
遠(yuǎn)程倉庫
# 克隆遠(yuǎn)程倉庫裕膀,通過 https,需要輸入賬號密碼
# 還可以使用 ssh 方式 git@ 協(xié)議勇哗,需要本地生成公鑰魂角、私鑰,公鑰配置到 git 服務(wù)器智绸,不用輸入賬號密碼野揪,比較方便
# 克隆完畢后,根據(jù)需要切換分支
git clone <url>
# 使用本地 GIt 客戶端生成秘鑰
ssh-keygen -t rsa -C "GitHub 賬號郵箱"
# 測試公鑰是否生效
ssh -T git@github.com
# 查看本地已經(jīng)鏈接的遠(yuǎn)程倉庫
cd <project-name>
git remote -v
# 添加遠(yuǎn)程倉庫
git remote add <shortname> <url>
# 查看遠(yuǎn)程分支瞧栗、檢索遠(yuǎn)程分支(IDEA 中需要此命令刷新分支)
git fetch
# 從遠(yuǎn)程倉庫中抓取與拉取斯稳,<remote> 為遠(yuǎn)程倉庫的縮寫 <shortname>
git fetch <remote>
# 推送到遠(yuǎn)程倉庫
git push -u <remote> <branch-name>
# 查看某個(gè)遠(yuǎn)程倉庫
git remote show <remote>
# 提交本地新項(xiàng)目到遠(yuǎn)程空白倉庫流程
# 拉取遠(yuǎn)程倉庫到本地的一個(gè)空白文件夾、本地的代碼覆蓋到新創(chuàng)建的文件夾(注意不要覆蓋 .gig 文件夾)
# git add \ git commit \ git push
標(biāo)簽
# 列出標(biāo)簽
git tag
# 模糊查詢迹恐,按照通配符列出標(biāo)簽挣惰,可使用 -l 或 --list 選項(xiàng)
git tag -l "<tag-name>"
git tag -l "v1.8.5*"
# 創(chuàng)建標(biāo)簽,Git 支持兩種標(biāo)簽:輕量標(biāo)簽(lightweight)與附注標(biāo)簽(annotated)。多數(shù)情況使用附注標(biāo)簽憎茂,如果只是想用一個(gè)臨時(shí)的標(biāo)簽珍语, 或者因?yàn)槟承┰虿幌胍4孢@些信息,那么可以用輕量標(biāo)簽
# 創(chuàng)建附注標(biāo)簽竖幔,指定 -a 選項(xiàng)
git tag -a <tag-name> -m "備注"
git tag -a v1.4 -m "my version 1.4"
# 創(chuàng)建輕量標(biāo)簽板乙,不需要使用 -a、-s 或 -m 選項(xiàng)拳氢,只需要提供標(biāo)簽名字
git tag <tag-name>
git tag v1.4
# 后期打標(biāo)簽募逞,可以對過去的提交打標(biāo)簽
git tag -a v1.2 9fceb02
# 共享單個(gè)標(biāo)簽,把本地標(biāo)簽推送到遠(yuǎn)程倉庫
git push <remote> <tag-name>
git push origin v1.4
# 共享全部標(biāo)簽馋评,一次性把所有不在遠(yuǎn)程倉庫的本地標(biāo)簽全部推送到遠(yuǎn)程倉庫
git push <remote> --tags
git push origin --tags
# 刪除標(biāo)簽放接,注意需要 push 推送
git tag -d <tag-name>
# 刪除一個(gè)遠(yuǎn)程標(biāo)簽
git push <remote> :refs/tags/<tag-name>
分支
# 創(chuàng)建分支
git branch <branch-name>
# 創(chuàng)建并切換到分支
git branch -b <branch-name>
# 查看本地和遠(yuǎn)程倉庫分支
git branch -a
# 切換分支,當(dāng)前分支的代碼必須全部已提交
git checkout <branch-name>
# 刪除分支
git branch -d <branch-name>
# 查看所有分支留特,* 標(biāo)記當(dāng)前所在分支
git branch
# 合并分支
git merge <branch-name>
# 重命名分支纠脾,如果 new branch 存在,則使用 -M 強(qiáng)制重命名蜕青,否則使用 -m 重命名
git branch -m|-M <old branch> <new branch>
# 推送本地分支到遠(yuǎn)程乳乌,<branch-name> 為遠(yuǎn)程分支名,可以跨分支推送
git push <remote> <branch-name>
# 刪除遠(yuǎn)程分支市咆、本地分支保留
git push <remote> :<branch-name>
# 拉取遠(yuǎn)程分支并在本地創(chuàng)建分支
get checkout -b <local branch> <remote>/<remote branch>
# 根據(jù) tag 創(chuàng)建分支
git fetch 刷新分支信息
git branch <new-branch-name> <tag-name> 根據(jù) tag 創(chuàng)建新的分支
最佳實(shí)踐
Gitflow 工作流
標(biāo)準(zhǔn)流程
[圖片上傳失敗...(image-f10e3d-1652835548585)]
-
master 分支:
生產(chǎn)分支,最穩(wěn)定的版本再来,一直是 ready to deploy 狀態(tài)蒙兰。不接受開發(fā)人員直接 commit,只接受從其他分支 merge 操作芒篷。在很多企業(yè)中搜变,這個(gè)分支被默認(rèn)開啟分支保護(hù),只有維護(hù)者可以操作针炉。
-
hotfix 分支:
從 master 分支拉取的臨時(shí)修復(fù)分支挠他,用于解決一線緊急 bug。bug 解決后需要合入 master 分支并打上新的版本號篡帕,這個(gè)修改也需要同時(shí)合入 develop 分支殖侵。
-
develop 分支:
從master分支拉取的開發(fā)分支,用于功能集成镰烧。包含所有要發(fā)布到下一個(gè) Release 的代碼用于開發(fā)集成拢军、系統(tǒng)測試。
-
release 分支:
臨近既定的發(fā)布日怔鳖,就從 develop 分支上拉取一個(gè) release 分支茉唉,任何不在當(dāng)前分支中的新功能都推到下個(gè)發(fā)布中。release 分支用于發(fā)布,所以從當(dāng)前時(shí)間點(diǎn)之后新的功能不能再加到這個(gè)分支上度陆,這個(gè)分支只做 Bug 修復(fù)艾凯、文檔生成和其它面向發(fā)布的任務(wù)。當(dāng)對外發(fā)布的工作都完成了懂傀,release 分支合并到 master 分支并分配一個(gè)版本號打好 Tag趾诗;另外,這些從 release 分支新做的修改要反向合并回 develop 分支鸿竖。
-
feature 分支:
開發(fā)者使用的特性分支沧竟,父分支是 develop 分支,當(dāng)新功能完成時(shí)缚忧,合入 develop 分支悟泵。新功能提交從不直接與 master 分支交互。
優(yōu)點(diǎn)
- 使用一個(gè)用于發(fā)布準(zhǔn)備的專門分支(release 分支)闪水,使得一個(gè)團(tuán)隊(duì)可以在完善當(dāng)前的發(fā)布版本的同時(shí)糕非,可以在 develop 分支并行繼續(xù)開發(fā)下個(gè)版本的功能。這也打造了可視化的發(fā)布階段球榆,團(tuán)隊(duì)成員都可以在倉庫網(wǎng)狀結(jié)構(gòu)中可以看到發(fā)布狀態(tài)朽肥。
- 使用緊急修復(fù)分支(hotfix 分支)讓團(tuán)隊(duì)可以處理緊急問題的同時(shí)而不打斷其它工作或是等待下一個(gè)發(fā)布再合入 hotfix 修改。我們可以把 hotfix 分支想成是一個(gè)直接在 master 分支上處理的臨時(shí)發(fā)布持钉。
- 大型項(xiàng)目人員協(xié)作頻繁衡招,流程較多,合理的多角色分支幫助研發(fā)有條不紊進(jìn)行每强。
- 更符合 devops 理念始腾。
缺點(diǎn)
- 學(xué)習(xí)成本較高。
- 如果團(tuán)隊(duì)不遵守使用約定空执,帶來的影響更大浪箭。
簡化流程
簡化流程去掉了 release、feature 分支辨绊。
-
master 分支:
生產(chǎn)分支奶栖,最穩(wěn)定的版本,一直是 ready to deploy 狀態(tài)门坷。不接受開發(fā)人員直接 commit宣鄙,只接受從其他分支 merge 操作。在很多企業(yè)中默蚌,這個(gè)分支被默認(rèn)開啟分支保護(hù)框冀,只有維護(hù)者可以操作。
對于多模塊項(xiàng)目敏簿,所有的代碼在一個(gè)分支中明也,該分支代碼可同時(shí)部署到 prd宣虾、uat 環(huán)境。在發(fā)版時(shí)温数,需要確認(rèn)當(dāng)前發(fā)版的模塊绣硝,并打 tag 標(biāo)簽。
tag 標(biāo)簽命名規(guī)則為
v<主版本號>.<次版本號>.<修訂號>_<模塊>_<發(fā)版日期>_[hotfix]
撑刺。- 主版本號:全盤重構(gòu)時(shí)增加鹉胖、重大功能或方向改變時(shí)增加。
- 次版本號:增加新的業(yè)務(wù)功能時(shí)增加够傍。
- 修訂號:只要有改動就增加甫菠,當(dāng)主版本號+次版本號變更時(shí),修訂號重置為 0
例如一個(gè)系統(tǒng)有 cms冕屯、auth 兩個(gè)模塊寂诱,tag 標(biāo)簽可以如下:
- v1.0.0_release_cms_20211003
-
v1.0.0_release_auth_20211003
- v1.0.1_release_cms_auth_20211005
-
v1.0.2_release_auth_20211006_hotfix
- v1.0.3_release_all_20211019
-
hotfix 分支:
從 master 分支拉取的臨時(shí)修復(fù)分支,用于解決一線緊急 bug安聘。bug 解決后需要合入 master 分支并打上新的版本號痰洒,這個(gè)修改也需要同時(shí)合入 develop 分支。
分支命名規(guī)則為
hotfix_yyyyMMdd_<功能模塊>
浴韭,當(dāng)修復(fù)分支部署到生產(chǎn)系統(tǒng)丘喻、并穩(wěn)定運(yùn)行后,需要定期刪除修復(fù)分支念颈。 -
develop 分支:
從 master 分支拉取的開發(fā)分支泉粉,用于功能集成。包含所有要發(fā)布到下一個(gè) Release 的代碼用于開發(fā)集成榴芳、系統(tǒng)測試嗡靡。
一個(gè)完整的功能開發(fā)完畢后推送 push 一次,避免日志混亂翠语;推送前先拉取 pull 遠(yuǎn)程的倉庫代碼,避免代碼沖突财边。
常見任務(wù)
增加新功能
(dev)$: git checkout -b feature/xxx # 從 dev 建立特性分支
(feature/xxx)$: blabla # 開發(fā)
(feature/xxx)$: git add xxx
(feature/xxx)$: git commit -m 'feat comment'
(dev)$: git merge feature/xxx --no-ff # 把特性分支合并到 dev
修復(fù)緊急bug
(master)$: git checkout -b hotfix/xxx # 從 master 建立 hotfix 分支
(hotfix/xxx)$: blabla # 開發(fā)
(hotfix/xxx)$: git add xxx
(hotfix/xxx)$: git commit -m 'fix comment'
(master)$: git merge hotfix/xxx --no-ff # 把 hotfix 分支合并到 master肌括,并上線到生產(chǎn)環(huán)境
(dev)$: git merge hotfix/xxx --no-ff # 把 hotfix 分支合并到 dev,同步代碼
測試環(huán)境代碼
(release)$: git merge dev --no-ff # 把 dev 分支合并到 release酣难,然后在測試環(huán)境拉取并測試
生產(chǎn)環(huán)境上線
(master)$: git merge release --no-ff # 把 release 測試好的代碼合并到 master谍夭,運(yùn)維人員操作
(master)$: git tag -a v0.1 -m '部署包版本名' # 給版本命名,打Tag
Git 約定式提交
參考 http://www.reibang.com/p/eb44ae2e5016
提交說明的結(jié)構(gòu)如下所示
<類型>[(可選的作用域)]: <描述>
[可選的正文]
[可選的腳注]
每個(gè)提交都必須使用類型字段前綴憨募,它由一個(gè)名詞組成紧索,諸如
feat
或fix
,其后接一個(gè)可選的作用域字段菜谣,以及一個(gè)必要的冒號(英文半角)和空格珠漂。作用域字段可以跟隨在類型字段后面晚缩。作用域必須是一個(gè)描述某部分代碼的名詞,并用圓括號包圍媳危,例如:
fix(parser):
可以在類型/作用域前綴之后荞彼,
:
之前,附加!
字符待笑,以進(jìn)一步提醒注意破壞性變更鸣皂。當(dāng)有!
前綴時(shí),正文或腳注內(nèi)必須包含BREAKING CHANGE: description
類型
feat: 新增 feature
fix: 修復(fù) bug
docs: 僅僅修改了文檔暮蹂,比如 README, CHANGELOG, CONTRIBUTE 等等
style: 僅僅修改了空格寞缝、格式縮進(jìn)、逗號等等仰泻,不改變代碼邏輯
refactor: 代碼重構(gòu)荆陆,沒有加新功能或者修復(fù) bug
perf: 優(yōu)化相關(guān),比如提升性能我纪、體驗(yàn)
test: 測試用例慎宾,包括單元測試、集成測試等
chore: 改變構(gòu)建流程浅悉、或者增加依賴庫趟据、工具等
revert: 回滾到上一個(gè)版本
示例
包含了描述以及正文內(nèi)有破壞性變更的提交說明
feat: allow provided config object to extend other configs
BREAKING CHANGE: `extends` key in config file is now used for extending other config files
包含了可選的 ! 字符以提醒注意破壞性變更的提交說明
chore!: drop Node 6 from testing matrix
BREAKING CHANGE: dropping Node 6 which hits end of life in April
不包含正文的提交說明
docs: correct spelling of CHANGELOG
包含作用域的提交說明
feat(lang): add polish language
為 fix 編寫的提交說明,包含(可選的) issue 編號
fix: correct minor typos in code
see the issue for details on the typos fixed
closes issue #12
FAQ
如果提交符合多種類型我該如何操作术健?
回退并盡可能創(chuàng)建多次提交汹碱。約定式提交的好處之一是能夠促使我們做出更有組織的提交和 PR。
沖突是怎么產(chǎn)生的荞估,如何避免?
- 本地分支沖突咳促,在本地主干與分支對同一個(gè)文件進(jìn)行了修改并進(jìn)行了提交,在合并分支時(shí)會產(chǎn)生沖突
- 多人協(xié)同沖突勘伺,多人在同一個(gè)分支下跪腹,對同一個(gè)文件進(jìn)行了修改,在提交遠(yuǎn)程倉庫時(shí)產(chǎn)生沖突
- 推送 push 前飞醉,先拉取 pull 可以降低沖突
參考
https://support.huaweicloud.com/bestpractice-codehub/codehub_practice_1005.html
http://team.bulo.cn/2019/11/21/git%E5%88%86%E6%94%AF%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83/
https://www.zybuluo.com/Interista/note/107676
http://www.reibang.com/p/9801b98c1de4
https://blog.csdn.net/weimingjue/article/details/88424758
培訓(xùn)內(nèi)容
- 基礎(chǔ)概念
- 華為云新建空白倉庫
- IDEA git冲茸、svn切換
- 上傳已有項(xiàng)目到倉庫
- 創(chuàng)建分支
- 切換分支
- 日常提交(約定式注釋)
- 合并分支
- 發(fā)版本打標(biāo)簽