首頁  >  文章  >  開發工具  >  深入了解Git的多種工作流程

深入了解Git的多種工作流程

PHPz
PHPz原創
2023-03-29 11:50:46833瀏覽

這篇文章帶大家了解Git,介紹一下git 的基礎知識、以及基於 git 的多種工作流程,希望對大家有幫助!

深入了解Git的多種工作流程

透過本文你可以了解到:

  • git 的起源
  • git 的基礎知識
  • gitflow 流程的基本方式
  • 基於git 的多種工作流程

在講Git Flow 之前,我們先講別的東西

  • 什麼是版本?
    版是指印刷時的版,本就是印刷出來的書本;版本是一種稱謂,用來描述同一事物的相互之間有差異的各種形式、狀態或內容。
    換言之,任何事物只要有差異化都會涉及到版本這個概念,但是,我們這裡說的版本,包括後面聊到的東西,都應該是一些有意義的版本,舉個例子,小明1 月1日至1 月31 日每天都在改一份策劃書,2 月1 號小明的甲方說還是上一個版本好,此時對於小明來說,上一個版本是什麼?也許是最近一次小明發給甲方的一個方案,也許是上一個甲方說還可以的方案,但小明可能已經不記得具體是幾號改完給甲方的方案了。

  • 常見的版本控制有哪些?
    copy 檔案以命名區分的方式、本編輯器的撤回/前進功能、使用專業工具如svn、git 等等都屬於版本控制的範疇,不同的版本控制有不同的用途,例如文字編輯器的撤回,可以輕鬆撤銷本次修改,例如copy 文件,可以讓新舊文件同時存在,方便對比,但這些方式太過簡單了,而且中間過程都是一些臨時性的東西,不足以作為一個修改歷史參考或者完整版本來看待,為此,還需要一些專業工具,如集中式版本管理系統SVN、CVS,分散式版本管理系統BitKeeper、Git 等。

  • Git 開發背景

    同生活中的許多偉大事物一樣,Git 誕生於一個極富紛爭大舉創新的年代。 Linux 核心開源專案有著少數的參與者。絕大多數的 Linux 核心維護工作都花在了提交修補程式和保存歸檔的繁瑣交易上(1991-2002年間)。到 2002 年,整個專案組開始啟用一個專有的分散式版本控制系統 BitKeeper 來管理和維護程式碼。
    到了 2005 年,開發 BitKeeper 的商業公司同 Linux 核心開源社群的合作關係結束,他們收回了 Linux 核心社群免費使用 BitKeeper 的權力。這迫使 Linux 開源社群(特別是 Linux 的締造者 Linus Torvalds)基於使用 BitKeeper 時的經驗教訓,開發出自己的版本系統。他們對新的系統製訂了若干目標:

    • 速度
    • 簡單的設計
    • 對非線性開發模式的強力支持(允許成千上萬個並行開發的分支)
    • 完全分散式
    • 有能力高效管理類似Linux 核心一樣的超大規模專案(速度和資料量) 自誕生於 2005 年以來,Git 日臻成熟完善,在高度易用的同時,仍保留著初期設定的目標。它的速度飛快,極其適合管理大項目,有著令人難以置信的非線性分支管理系統(參見 Git 分支)。
  • 1991 年Linux 開發了linux 系統這個開源項目,採用郵件發送來源文件附帶patch的方式進行寫作開發,由Linux 本人進行手工合併;

  • 2002 年BitKeeper 與Linux 社群達成協議,允許Linux 社群免費試用BitKeeper,由於免費試用,協議內容更多是保護BitKeeper 本身。

  • 2005 年BitKeeper 不滿Linux 社群破壞協議內容(說白了就是反編譯BitKeeper,試圖做破解版或其他),終止合作;

  • #同2005 年,Linux 花了2 週時間,開發了Git 第一版,一個月內使用Git 來管理Linux 程式碼;

##Git 基礎知識

工作區(Workspace)、暫存區(Index)、版本庫(Repository)

# 创建并进入 testGitFlow 目录
# 此时 testGitFlow 就是我们的工作区(Workspace),也就是工作目录

$ mkdir testGitFlow && cd testGitFlow

# 初始化 git 仓库
# 此时目录中增加了 .git 目录,.git 目录就是 git 仓库,不属于工作区

$ git init

# 新增两个文件
$ echo 111 > a.txt
$ echo 222 > b.txt

# 添加两个文件到暂存区/索引(Index)
$ git add .

# 把索引中的两个文件添加到版本库(Repository)
$ git commit -m 'init'

以上涉及的幾個概念:


Workspace: 簡單理解就是我們的項目目錄
Index: 簡單理解就是儲存即將提交的內容的區域
Repository: 版本倉庫

Commit、Tree、Blob 物件

# 通过 git log 查看版本
$ git log

>
commit 2b304a56998989dbcfd77f370f4b43fcad9e5872 (HEAD -> master)
Author: huihuipan <huihuipan163@163.com>
Date:   Mon Feb 27 17:56:53 2023 +0800

    init


# 通过 git cat-file 查看 commit 信息

# 查看 commit 类型
$ git cat-file -t 2b304a
> commit

# 查看 commit 内容
$ git cat-file -p 10d717

>
tree 4caaa1a9ae0b274fba9e3675f9ef071616e5b209
author huihuipan <huihuipan163@163.com> 1677491813 +0800
committer huihuipan <huihuipan163@163.com> 1677491813 +0800

init

# 可以发现有 tree, author, committer 等信息
# 继续查看 tree 内容
$ git cat-file -t 4caaa1
> tree

$ git cat-file -p 4caaa1
>
100644 blob 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c	a.txt
100644 blob c200906efd24ec5e783bee7f23b5d7c941b0c12c	b.txt

# 可以发现有 blob 信息
# 继续查看 blob 内容
$ git cat-file -t 58c9bd 
> blob

$ git cat-file -p 58c9bd 
> 111

# 可以看到里面存储的是 a.txt 的内容

以上涉及的幾個概念:


commit: commit 記錄提交的版本
tree: tree 記錄不同版本下的目錄結構和檔案名稱
blob: blob 記錄檔案內容

此時我們的git 專案結構如下

深入了解Git的多種工作流程

修改文件及提交 commit 的時候發生了什麼事?

深入了解Git的多種工作流程

  1. 首先,a.txt 內容從111 修改為333,此時git 倉庫沒有變化,只是工作區和索引的內容對不上了;
  2. 執行git add 指令
    1. git 倉庫根據新的a.txt 內容(333)建立一個新的blob 結點,記錄a.txt 內容
    2. 從舊blob 的指向新的blob
  3. 執行git commit 指令
    1. 根據索引的狀態,產生tree 物件
    2. 根據新產生的tree 物件和上一個commit 對象,產生新的commit 物件
    3. 把分支指標從舊的commit 物件移到新的commit 物件

HEAD、Branch、Tag

Branch: 是指向Commit 的指標,每次提交新的commit,目前的Branch 都會指向最新的commit;

HEAD: 指向Branch 的指針,當checkout 到非branch 時,會提示處於分離頭指針狀態,可以做一些試驗性的動作;

Tag: 指向Commit 的指針,用作標籤,通常用作記錄固定版本,也可以理解為是指定commit 的別名;

以上我們可以得知,git 的版本管理粒度去到了文件級別,blob 之間的對比即可得到diff,這裡也引申出了一個開發上的一個思考,當我們的程式設計的基礎是比較小粒度的時候,後續開發和擴展就會更加靈活,事實上git 對commit 的操作也是非常靈活,靈活到稍不注意就有可能釀成事故。

Checkout、Merge、Rebase、Fetch、Pull

#checkout 檢出: 把HEAD 檢出到指定branch 或commit,或檢出指定版本指定檔的內容,由於在git 裡面checkout 承載了太多的功能,所有切換分支都有專屬指令switch

merge 合併:

深入了解Git的多種工作流程

#rebase 變基:深入了解Git的多種工作流程

rebase 會修改版本歷史,即使rebase 前面與rebase 後面的內容一致,但版本不再是同一個版本

fetch: 從另一個儲存庫下載物件和引用,如遠端程式庫

pull: git pull = fetch merge

基於Git 的幾個工作流程

Git Flow

深入了解Git的多種工作流程

簡介

出自Vincent Driessen2010年寫的一篇文章
《A successful Git branching model》

主要分支

深入了解Git的多種工作流程

##有兩個分支會貫穿整個版本的生命週期,也就是長期分支:

    master 分支:用於發布
  • develop 分支:用於開發 master 分支與develop 分支的關係如上,虛線部分指著兩個分支並不是直接發生關聯,而是透過release/hotfix 分支發生關聯
  • ##支持分支

#feature branches: 用於需求開發

深入了解Git的多種工作流程開發需求時從develop 分支拉出feature 分支,feature 分支開發完畢後(開發自測無問題)則合併回develop 分支,合併後刪除分支,後續出現bug 則在develop 分支修改。

release branches: 用於發布

深入了解Git的多種工作流程#當develop 分支處於一個相對穩定的狀態時即可從develop 分支拉出release 分支準備發布,release 分支不進行功能開發,僅進行bug 修復,直至無問題時合併到master 分支進行發布,同時合併回develop 分支後刪除release 分支。

  • hotfix branches: 用於修復生產問題

深入了解Git的多種工作流程

#hotfix 分支用於修復生產環境上急需修復的bug, 當生產環境出現bug時,從master 分支拉出hotfix 分支,修復後合併回master 分支進行發布,同時合併到develop 分支後刪除。

最後回顧完整的gitflow

深入了解Git的多種工作流程

補充

#在2020年 Vincent Driessen 補充了一條反思筆記,大概說Git Flow這種模式在持續交付的軟體下顯得複雜,可以考慮使用 Github Flow 而不是將Git Flow 硬塞到專案中。

Git Flow 之後Adam Ruka 針對Git Flow # 的技術細節做了最佳化,提出了One Flow

#Github Flow

深入了解Git的多種工作流程

相對於Git FlowGithub Flow 只有一條主幹分支,透過github 平台加持增加PR 流程: 進行某功能開發時,從master 分支拉出feature 分支,完成功能後提交pr, 讓相關人員進行review, review 期間仍可以對feature 進行提交,直至確認無問題後透過pr, 可以把feature 分支合併到master分支進行發布

GitLab Flow

GitLab Flow 使用##master 分支作為開發分支,基於master 分支另起發布分支production
GitLab Flow##以下分支定義:
環境分支:當你需要在不同環境發布不同的版本時使用
發布分支 #:當專案需要發布不同的版本時使用,宣告了一個發布分支後,這個分支只會合併嚴重的漏洞修復更新。

持續發布

深入了解Git的多種工作流程

gitlab-flow 推薦使用master 分支進行開發,基於master 分支另建production 分支進行發布,另外提出了環境分支的概念,根據不同環境,逐層合併,最後匯總到production 發布分支後進行發布

版本發布

深入了解Git的多種工作流程

如果你的專案需要發布不同的版本, gitlab-flow 版本發布模式可能更適合,在持續發布模式下,不同的版本會有不同的發布分支進行發布。

Aone Flow

深入了解Git的多種工作流程

Aone-flow 是以 master 分支為基礎,除 master 分支外其他都是臨時分支。基於 master 分支拉出環境分支,環境分支之間不進行任何關聯,獨立發展,環境分支也不允許直接修改,而是透過合併不同的 feature 分支進行組合。 feature 分支直到合併到 發布分支後才會刪除。有點是操作粒度更高更可控,缺點是環境分支的內容即使是一樣的,但版本歷史卻有可能不一致。

怎麼選擇版本控制

上面介紹了好幾種flow, 從gitflow 開始,gitflow 讓自由度超高的git 得到了指導性的使用方式;

而github- flow 又針對了gitflow 的複雜性提出了極簡版的flow;
gitlab-flow 又針對gitflow 和github-flow 過於複雜或過於簡單的方式,提出了自己折中的方案,同時也給了兩種交付方式(持續交付、版本交付)的方案;
最後也介紹了AoneFlow,一個操作粒度更自由的方案。

其實沒有萬能方案,不同的團隊/專案有著其特殊的情況,針對不同情況,flow 也在變化,合適的就是最好的。

最後

To conclude, always remember that panaceas don't exist. Consider your own context. Don't be hating. Decide for yourself.

引用Vincent Driessen 的一句話:「最後,永遠記得萬用藥不存在。考慮你自己的背景。不要討厭。自己決定」

更多程式設計相關知識,請造訪:程式設計影片! !

以上是深入了解Git的多種工作流程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn