由git subtree/submodule 引發(fā)的關(guān)于git hook 的解決方案

? ? ? ? 最近在學(xué)習(xí)objc_runtime源碼這部分的內(nèi)容需要寫一些筆記,看源碼的倉庫加入自己的一些筆記,但是看源碼的倉庫有很多一些關(guān)于runtime相關(guān)的代碼還有前輩朋哥的筆記。我想要把筆記抽出來作為子倉庫,同時(shí)想要在主倉庫里面也留著筆記。

倉庫圖

1、submodule方案

? ? ? ? 最常見的辦法就是把子倉庫作為主倉庫的子模塊,好有想法直接開搞。我馬上就添加子模塊,提交代碼,發(fā)現(xiàn)在主模塊中每次提交都不會獲知當(dāng)前子模塊修改提交的內(nèi)容,只會留下一句commit XXXXXX。


submodule方案

? ? ? ? 如果主倉庫不關(guān)注子倉庫的變化的話,可以使用這個(gè)方案,但是我關(guān)注呀!有時(shí)候我又想在主倉庫看看我之前提交的內(nèi)容,GitHub上也看不了,只能看到Submodule XXX。如果這樣的話,在GitHub上看不到具體的內(nèi)容,要拉去代碼才能看到里面的內(nèi)容,豈不是給搜索引擎?zhèn)內(nèi)鄙伲⊕撸┝藗€(gè)機(jī)會?可不行,萬一我想去GitHub上看看自己的筆記可不是沒得談。

如果是子模塊GitHub中顯示狀態(tài)

2、subtree方案

? ? ? ? 我就想那我就使用subtree的方式。subtree相當(dāng)于成為主倉庫的一個(gè)子項(xiàng)目一樣,可以看到變更修改所有操作,也可以推上去到主倉庫里(具體的subtree的使用已經(jīng)很多文章介紹到了)。subtree有個(gè)缺點(diǎn),我個(gè)人認(rèn)為的缺點(diǎn),就是推拉子項(xiàng)目的時(shí)候,出現(xiàn)莫名其妙的沖突和無更新內(nèi)容???

sourcetree 拉取到的內(nèi)容顯示
推送失敗的內(nèi)容

? ? ? ? 主倉庫就的README.md和子倉庫的README.md大家的路徑不一樣,為什么你就竄味了呢?再者我明明就有修改 為什么推送出現(xiàn)問題。

3、第三個(gè)猜想---subtree與submodule的結(jié)合體?

? ? ? ? 因?yàn)榻Y(jié)合嘛如果想要同時(shí)顯示和提交,那么有subtree來進(jìn)行顯示以及主倉庫管理子項(xiàng)目中文件,submodule來負(fù)責(zé)提交更新到我們的子倉庫中。

? ? ? ? 當(dāng)然不行,還有這么玩? 因?yàn)槲覀冃枰粋€(gè)路徑處理(因?yàn)槲覀兏牡淖觽}庫內(nèi)容肯定只有一個(gè)地方,難道要兩份地方改了這邊復(fù)制過去?不適合我們計(jì)算機(jī)仔的邏輯操作)。那么同一個(gè)路徑的話,當(dāng)我們加入后者(submodule)時(shí)候 ;就會提示改路徑已經(jīng)存在Index重復(fù),我嘗試直接在.gitmodules文件中加入無法識別出commit XX(如上submodule方案圖) 那么還是無法提交的。

4、第四個(gè)猜想---subtree與git hook結(jié)合體? ?

? ? ? ? 思路來源:由于一開始的想抽離筆記為另一個(gè)倉庫同時(shí)又保留在主倉庫這個(gè)想法,尋求解決方案,第一第二個(gè)方案都不完美,第三個(gè)方案想法很完美 但是不能完全的實(shí)現(xiàn)。所以就想著用subtree方案為基礎(chǔ),我把子倉庫的.git文件復(fù)制進(jìn)去不就好了?接著主倉庫(子倉庫在這里相當(dāng)于一個(gè)文件夾)盡管提交,到時(shí)候手動的去提交子倉庫。我突然想起不是hook這個(gè)東西,好家伙git有個(gè)hooks。我直接hook 到主倉庫commit的時(shí)機(jī)在此,偷偷在后面提交和推送子倉庫,做到神不知鬼不覺。

關(guān)于git hook

? ? ? ? ? ? 本次我用到的三個(gè)腳本,分別是pre-commit、commit-msg、post-commit;

? ? ? ? ? ? 一開始只是使用到了commit-msg想著在提交的時(shí)候,就提交以及推送子倉庫的內(nèi)容。(基本完成了簡單我的想法)但是問題來了,難道以后大家要用到這個(gè)的時(shí)候,專門去找到子倉庫的.git文件,接著復(fù)制到對應(yīng)的位置,接著開始,添加commit-msg的內(nèi)容。這不麻煩嗎?可不嘛!所以我開始麻煩自己了,可不可以把.git文件打包成一個(gè)壓縮包,接著對子倉庫是不可見的,對主倉庫可見;當(dāng)主倉庫進(jìn)行提交操作之前,就把其解壓出來放好在對應(yīng)位置,接著就開始提交子倉庫的內(nèi)容。

? ? ? ? 為什么主倉庫可見,因?yàn)槲覀兠看味家乱幌伦觽}庫的.git文件(.git文件是在git不可識別的/忽略的,所以主倉庫中也是無法識別的,才有了壓縮包這個(gè)想法)。

? ? ? ? ? 怎么做到呢?

? ? ? ? ? 第一 在主倉庫提交的時(shí)候 把子倉庫提交并且推送 。

? ? ? ? ? ? ? ? ? 子倉庫完成了提交和推送之后的.git文件此時(shí)可以進(jìn)行壓縮保存

? ? ? ? ? ? ? ? ? 為提交到主倉庫中作準(zhǔn)備

? ? ? ? ? 第二 主倉庫提交了的內(nèi)容 必須回滾回來上一個(gè)階段(混合回滾 保留原有修改)

? ? ? ? ? ? ? ? ? 因?yàn)槲疫@里要把子倉庫上次提交的.git壓縮包 提交到主倉庫中。

? ? ? ? ? 第三 推送主倉庫的內(nèi)容。


第一步

? ? ? ? 第一步 中產(chǎn)生了我們的子倉庫.git 壓縮包,我們在commit主倉庫的時(shí)候已經(jīng)提交上去了 但是我們還沒推送 還有話好說,所以我們就需要一個(gè)精髓的操作----回滾上一個(gè)階段。

? ? ? ? 第二步 我們才真正的把我們的修改內(nèi)容(來源上一步回滾)和.git包一起提交上去

第二步

? ? ? ? ? 涉及兩個(gè)中間變量TEMPVAR、TEMPCOMMITMSG,向.git學(xué)習(xí) 它就是用這個(gè)文件來存儲提交的信息,所以我也有兩個(gè)中間變量,我用完之后還刪除了,嘻嘻。

文件1


內(nèi)容

GitHub:https://github.com/pirder/StudyNotes_Objc


直接貼碼:

pre-commit:提交前

#!/bin/sh

#一開始默認(rèn)是沒有.git 必有g(shù)it壓縮包

#沒有g(shù)it 解壓.git

fileName="./閱讀筆記/StudyNotes"

cd "$fileName"

ls .git &> /dev/null || {

? tar -xvf subtreeGit.tar.gz &> /dev/null || {

? ? ? echo "沒有子倉庫的.git 也沒有 .git 的壓縮包"

? }

}

commit-msg:提交中

#!/bin/sh

# ===== 在commit 主倉庫時(shí)候 就可以如果子倉庫有改動就可以把子倉庫的提交并且推送了

echo "======提交之前"

mssageFile="./閱讀筆記/StudyNotes/TEMPCOMMITMSG"

fileName="./閱讀筆記/StudyNotes/TEMPVAR"

TAGCOMMITFIRS=$(cat $fileName || {

? ? ##確保之前就存在

? ? touch $fileName

? ? echo "true" > $fileName

? ? })

TAGCOMMITFIRS=$(cat $fileName)

#第一次 提交tag 為true 非第一次 tag 為false

if $TAGCOMMITFIRS

then

echo "進(jìn)入 第一次的子庫提交"

else

echo "提前結(jié)束"

exit 0

fi

commitMessage=$(cat "$1")

hasCommitCommand=true

echo "信息描述為 $commitMessage"

##確保之前就存在

touch $mssageFile

#存起來我們提交的msg

echo $commitMessage > $mssageFile

#處理子倉庫 提交

cd ./閱讀筆記/StudyNotes

git add -A

git pull origin main #解壓出來的git 防止存在版本偏差 先進(jìn)行拉取

git commit -m "$commitMessage" || {

echo "子倉庫無commit或者在上一次已經(jīng)提交了"

hasCommitCommand=false

}

#如果有提交內(nèi)容 就進(jìn)行推送 并且打包好推送完成的.git文件

if $hasCommitCommand

then

echo "子倉庫開始push"

git push origin main || {

? ? echo? "子倉庫推送失敗"

}

echo "把子倉庫的.git打包起來 接著刪除存在的 并且在進(jìn)行解壓"

#對于子倉庫應(yīng)該是不知他的存在 在主倉庫存在

tar -zcvf subtreeGit.tar.gz .git &> /dev/null

fi

post-commit:提交后

#!/bin/sh

# ===== 在commit 主倉庫時(shí)候 就可以如果子倉庫有改動就可以把子倉庫的提交并且推送了

# 子倉庫提交完成之后 主倉庫回滾 到上一次提交 把.git 壓縮起來提交 以后都能使用 可以在提交前hook把其解壓出來

echo "======提交之后"

##中間變量記錄主倉庫第幾次提交

fileName="./閱讀筆記/StudyNotes/TEMPVAR"

##記錄中間消息內(nèi)容

mssageFile="./閱讀筆記/StudyNotes/TEMPCOMMITMSG"

TAGCOMMITFIRS=$(cat $fileName || {

? ? echo "true" > $fileName

? ? })

TAGCOMMITFIRS=$(cat $fileName)

echo $TAGCOMMITFIRS

if $TAGCOMMITFIRS

then

#回滾之前第一次主倉庫提交

git reset --mixed master^

TAGCOMMITFIRS=false

echo $TAGCOMMITFIRS > $fileName

echo "====第一個(gè)提交 負(fù)責(zé)處理子倉庫中的提交 和 推送"

git add -A

commitMsg=$(cat $mssageFile)

#這才是真正的提交

git commit -m "$commitMsg"

else

#移除中間文件

echo "移除臨時(shí)中間文件"

rm -r $fileName

rm -r $mssageFile

echo "====結(jié)束所有流程"

fi

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容