[英]Specify branch for a git submodule?
我已經在我的git存儲庫中添加了一個git子模塊,它工作正常。
在我的“父”存儲庫中,我創建了一個功能分支: myfeature ,需要對子模塊進行一些更改。 但是我不想影響使用相同子模塊的其他團隊。 因此,我在子模塊存儲庫submodule-feature上創建了相應的功能分支,並進行了一些更改。 然后,我已經從子模塊目錄添加/提交更改,然后在父存儲庫的根目錄中添加了更改。
但是,當我在“父”存儲庫上切換回master時,子模塊仍位於submodule-feature功能分支上。 那不是我所期望的。 因為現在當我在master上運行測試時,它們失敗了,因為我在submodule-feature分支的submodule中引入了一些重大更改。
不可能將子模塊的分支鎖定到父存儲庫分支嗎?
編輯:基於: 添加Git子模塊時,如何指定分支/標簽?
看起來我可以在.gitmodules
為子模塊存儲庫指定一個分支
[submodule "mysubmodule"]
path = mysubmodule
url = https://bla.git
branch = submodule-feature
並在jenkins中添加以下其他git行為:
和:
在父 myfeature分支上運行構建時,它將克隆/簽出submodule-feature
分支。
但是,在本地工作時,這當然需要一些手動步驟。 但是從CI方面來看,它非常容易實現。
簡短的答案通常只是 “不”。 盡管詹金斯(Jenkins)有一個復選框,但在此處使用它可能不是一個好主意-是否使用,取決於誰控制名稱到ID的映射。 其他CI系統可能具有也可能沒有相似的復選框。 要了解我在這里得到的內容,請繼續閱讀。
子模塊的理念是,超級項目由其子模塊控制。 我認為,這部分內容對於任何人都不會感到驚訝或反對。 但關鍵在於上層項目控制每個子模塊的方式 。 這部分確實讓人感到驚訝,原因很簡單。 一般來說,這是對Git存儲庫的基本誤解。
人們認為,Git存儲庫中重要的是分支 ,或更確切地說,是master
和develop
等分支名稱 。 那根本不是真的。 這些分支在大多數情況下實際上無關緊要 。 對於人類而言,這些分支名稱具有巨大的,壓倒一切的目的。 對於Git來說,它們提供的服務幾乎都是平凡的,其他名稱也可以很好地覆蓋它,例如標簽名稱,遠程跟蹤名稱或refs/stash
或HEAD@{17}
。 1個
在Git中, 提交 (而不是分支名稱(也不是標簽名稱,也沒有任何其他名稱))是核心的基本內容。 承諾就是Git的存在理由 。 沒有提交,Git將不起作用。 對於提交,Git很有用。 提交實際上是由其哈希ID標識的,其真實名稱是那些丑陋的大字符串,如b5101f929789889c2e536d915698f58d5c5c6b7a
。 愚蠢的事物,例如易讀的名稱,例如master
或develop
,對於弱者,生物……人類都是如此。
當然,我們作為弱者, 就像我們的名字一樣。 因此,我們在存儲庫中使用它們。 但是,當我們擁有一個像超級項目一樣的存儲庫來控制另一個存儲庫(例如子模塊)時,在這種情況下, 就沒有人參與了 。 因此,Git使用提交ID來控制在每個子模塊中提取哪個提交哈希ID。
因此,這就是驚奇的源頭-除非您了解了Git的來源,這一點也就不足為奇了。 當您讓超級項目選擇子模塊提交時,超級項目通過哈希ID選擇子模塊提交。 任何分支名稱都不相關。 哈希ID准確且始終正確。 分公司名稱是草率的,他們移動 ,有目的的,從提交承諾,隨着時間的推移。 一個提交哈希ID可以具有零個或多個直接指向它的分支名稱,或者可以通過提交圖到達它。 2
您在超級項目中進行的每個提交都記錄了子模塊預期已檢出的確切子模塊哈希ID。 因此,當您在超級項目中git checkout
某些提交時,通常應該立即讓每個子模塊通過在超級項目中指定的哈希ID進行自己的單獨git checkout
。 3
請記住,每個子模塊都是其自己的Git存儲庫,因此它具有自己的HEAD
,索引和工作樹。 輔助模塊索引記錄被檢出到子模塊的工作樹中的文件和HEAD
在每個子模塊中分離的頭的方式,記錄當前簽出的哈希ID提交。 選擇此哈希ID的是超級項目的Git,方法是將其存儲在超級項目中的提交中,而子模塊的Git負責簽出此特定的提交。 在此過程中,沒有任何地方提到分支名稱。 分支名稱無關!
1名稱的In-Git功能除了為弱者提供了拐杖外,還可以防止物體被垃圾收集 。 如果無法通過某些名稱訪問對象,則該對象很容易受到收集的影響。 由於大多數提交大多是鏈接在一起的,因此一個名稱傾向於保護存儲庫中的大多數提交。 另見腳注2。
2有關可達性的更多信息,請參見“像(a)Git一樣思考” 。
3默認情況下,這實際上不會自動發生。 您必須在配置中使用git checkout --recurse-submodules
或設置submodule.recurse
。 根據您正在執行的操作(尤其是如果您嘗試更新子模塊),自動進行操作既方便又非常煩人。
如您所述, .gitmodules
文件可以記錄分支名稱。 您也可以將其復制到.git/config
(如果同時設置了.git/config
設置, .gitmodules
覆蓋.gitmodules
設置。)但是通常,子模塊根本不在分支上; 如上所述,它已進入分離HEAD模式。 那么,什么是好這個部門的名字嗎?
第一個但有些不令人滿意的答案是:一點都不好。 大多數操作只是不使用它。
第二個更令人滿意的答案是: 一些特殊用途的操作確實使用它。 具體來說,如果您正在更新超級項目,並且想要進行一個新的超級項目提交來記錄新的子模塊哈希ID,則需要某種方式來挑選新的子模塊提交哈希ID。 解決此問題的方法有多種,名稱是為其中一種方式設計的。
例如,假設子模塊是一個不受您控制的公共存儲庫(也許在GitHub上)。 您只需要使用它。 也許每年兩次,或者一天可能有50000次,那么有人會更新GitHub存儲庫。 他們將新的提交提交給master
或他們的develop
或諸如此類,破壞了您使用的一堆東西,但這不是問題,因為您的超級項目不會說 “讓我獲得他們最新的master
或develop
提交” ”,您的超級項目會說“讓我提交a123456...
”,並且a123456...
永遠都是相同的提交,直到宇宙熱死,或者我們停止使用Git,以先發生的為准。 但是,在破壞了您自己的一堆軟件的同時,他們引入了您必須具備的一項很酷的新功能。
此時,您想要做的就是擁有Git,它也控制着您的子模塊,告訴您的子模塊Git: 去找我他們最新的master
或develop
或我以前記錄的名字。 由於您確實記錄了該名稱,因此可以使用以下命令引導Git指示子模塊執行該操作:
git submodule update --remote
(您可以在其中添加一些額外的標志,例如--checkout
或--rebase
或--merge
,但我不打算討論這些詳細信息,我現在假設您僅直接使用它們的最新標志) 。 您的Git擁有您的子模塊Git運行git fetch
,然后根據您的子模塊的分支名稱副本將您的子模塊存儲庫更新為最新提交。 (現在至少涉及三個Git,即您的超級項目,您的子模塊和GitHub上的Git存儲庫。因此,這有點復雜。無論他們是誰,他們可能都有一個或多個Git存儲庫用於控制GitHub,但是至少您不必處理它。嗯,還沒有。)
現在您的子模塊已更新,您必須修復自己的代碼,以使用新功能並處理它們對已使用的東西所做的所有重大更改。 因此,您需要做所有這些,在本地計算機上構建和測試軟件,而且都不需要在這里使用CI,並且可以正常工作。 現在,您可以git add
的更改,並git add
子模塊的名稱。 現在,您的超級項目的索引和工作樹都匹配了,您可以在超級項目中進行新的提交了。
請注意, git add submodule-path
僅告訴您的Git在索引中記錄子模塊Git存儲庫中當前檢出的提交的哈希ID 。 再說一次, 分支名稱(如果有)是不相關的。 子模塊存儲庫是在分支master
還是develop
,或者具有分離的HEAD都無關緊要; 重要的是原始提交哈希ID 。
現在,您運行git commit
進行新的提交。 索引中的哈希ID是您通過運行git add submodule-path
記錄的提交哈希ID,它控制哪個提交將被視為子模塊的“正確”提交。 在這種情況下 ,您之前運行git submodule update --remote
的事實選擇了該提交ID。 但是唯一重要的是索引中的哈希ID,該ID進入新提交。
現在,您可以git push
在超級項目Git存儲庫中所做的提交git push
提交到其他系統,例如CI系統。 它可以git checkout
此提交,並且此提交記錄正確的子模塊哈希ID。
顯然,這要困難得多,取決於您的CI系統是否將其作為功能提供,這可能會更難。
現在,您已經知道這是如何構造的,您已經擁有了所需的工具。 您必須具有CI系統更新(或獲取)超級項目的克隆。 該超級項目的.gitmodules
文件中還包含CI系統必須克隆的所有子模塊的URL和路徑。 它可能包含也可能不包含這些子模塊的某些分支名稱。
CI系統現在必須指示某些Git(超級項目Git或子模塊Git),以使子模塊Git git checkout
一些已經記錄為正確提交的提交以外的提交,以便超級項目不再使用CI提交系統已簽出。 換句話說,您將不再構建提交給CI系統的內容 。 您正在使用CI系統從身體部位中構建新的科學怪人的怪物:提交時的主體,但未直接指定的其他提交中提取的肢體:相反,您允許其他人指定哪個提交去了。 您給CI系統起了一個名字,並告訴它詢問他們(無論他們是誰)該名稱到達的哈希ID。
您的CI系統現在可以嘗試構建和使用此科學怪人的怪物。 如果一切運作良好,CI系統將需要作出新的承諾,這是很多喜歡你的承諾,除了它記錄了它從他們身上得到了-whoever他們,再一次,有問題的輔助模塊中的散列ID。 除非您的CI系統也是您的主要存儲庫的真實來源,否則您的CI系統現在可能還需要將此提交推送到某個地方的權限。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.