[英]Git subtree merge strategy or subtree command?
我正在開始一個新的 Zend Framework 項目,我將在其中與設計師合作。 我將使用 git 維護這個項目代碼,通常設計師不會說 git(或任何編程語言)所以我想讓他的事情變得容易,否則我擔心他根本不會使用 ZBA9F11ECC3497D6993B933FDCBD2 我的計划是給他一些 Git gui,然后他應該只使用基本的 git 功能,例如提交、差異、獲取、合並、推送和拉取。
我正在使用 gitolite 來維護我們的 git 存儲庫的共享副本,並且由於它具有細粒度的權限系統,因此我將僅授予設計人員對專用分支(設計)的 RW 訪問權限和對其他分支的讀取權限。
為了簡單起見,我只想與他分享主項目中的一些文件夾(遵循ZF 推薦的結構),他確實需要訪問這些文件夾才能完成工作。 同時我希望我們倆仍然可以相互融合。
他的分支的簡化結構應該是這樣的:
<project name>/
application/
layouts/
scripts/
views/
scripts/
public/
css/
images/
js/
我知道我可以使用子模塊來完成這項任務,但是維護起來會很痛苦,因為我應該將我的項目拆分為(至少)4 個子存儲庫,他應該只能訪問子存儲庫,並且他有 3 個存儲庫可以使用. 出於這個原因,如果這是唯一的解決方案,我將放棄這個想法。
我已經閱讀過的一些鏈接讓我認為我所要求的是可能的:
這是我的問題:
design
( git checkout -b design
和git mv/rm
?)git merge design
,反之亦然)我發現了解決這兩個 SO 問題的另一種可能方法
我嘗試在設計分支中實現git rm all-unneeded-stuff
之后的第一個,我在 master 分支中進行了提交,其中涉及白名單路徑中的一個文件和黑名單路徑中的另一個文件,但是git merge
失敗並出現以下問題信息
CONFLICT (delete/modify): application/Bootstrap.php deleted in HEAD and modified in master. Version master of application/Bootstrap.php left in tree.
然后我在主分支中添加了一個新目錄,並在從設計合並時添加了新目錄。 我在驅動程序中放了一些調試回顯,我發現在這兩種情況下都沒有調用它,可能是因為它不是真正的合並。
我還沒有嘗試過第二種方法(.gitignore 一種),但如果我理解這種方法不符合我的需要,因為它只會忽略設計分支中的黑名單文件,但它們會在設計分支,打破了我的要求。
我在GitHub上進行了實驗
我認為目前沒有解決方案。 使用當前的 git 實現,這根本無法實現。
我想被反駁,但我又怕它不會發生。
聽起來您希望能夠在每個目錄的基礎上限制讀取訪問。 這是可能的,但我知道的唯一解決方案遠非簡單。 它涉及服務器上同一個存儲庫的多個版本,每個版本都使用一些復雜的鈎子魔法來過濾掉子目錄,從而保持同步。
我在業余時間致力於實現這些鈎子,最終目標是將它們作為開源軟件發布(也許作為 gitolite 的一個功能),但不幸的是,我的業余時間有限。
通用解決方案涉及同一存儲庫的至少三個變體: 一個協調兩個或多個委托存儲庫的權限存儲庫。 用戶從不克隆權限庫; 只有委托存儲庫被克隆。
代表負責將傳入的提交轉發到權限存儲庫。 權限存儲庫負責為每個其他委托存儲庫適當地過濾傳入的提交。 然后將結果下推給其他代表。
權限存儲庫不是嚴格要求的——代表可以自己執行過濾,然后將結果直接推送給其他代表——但是使用另一個存儲庫作為集中協調器可以大大簡化實施。
每個委托存儲庫都包含整個項目數據的子集(例如,過濾掉的零個或多個子目錄)。 所有委托存儲庫都彼此相同,只是每個委托都有一組不同的文件被過濾掉。 它們都具有相同的提交歷史圖,但提交將具有不同的文件內容,因此具有不同的 SHA1 標識符。 它們具有相同的分支和標簽集(換句話說,如果項目有一個master
分支,那么每個委托存儲庫也有一個master
分支),但是因為等效提交的 SHA1 標識符不同,所以引用將指向不同的 SHA1 標識符。
例如,以下是兩個委托存儲庫的內容圖表。 everything.git
存儲庫沒有過濾掉任何內容,但是no-foo.git
存儲庫過濾掉了子目錄foo
中的所有內容。
$ cd ~git/repositories/everything.git
$ git log --graph --oneline --decorate --date-order --all
* 2faaad9 (HEAD, master) barbaz
| * c3eb6a9 (release) foobar
* | 8b56913 Merge branch 'release'
|\ \
| |/
| * b8f899c qux
* | aad30f1 baz
|/
* f4acd9f put a new file in subdirectory bar
* 2a15586 put a new file in subdirectory foo
$ cd ~git/repositories/no-foo.git
$ git log --graph --oneline --decorate --date-order --all
* 81c2189 (HEAD, master) barbaz
| * 6bbd85f (release) foobar
* | c579c4b Merge branch 'release'
|\ \
| |/
| * 42c45c7 qux
* | 90ecdc7 baz
|/
* 4d1cd8d put a new file in subdirectory bar
* 9cc719d put a new file in subdirectory foo
請注意,這兩個圖看起來相同,具有相同的提交消息、相同的分支名稱等。唯一的區別是 SHA1 ID,因為文件內容不同。
(旁注:提交也可以被過濾掉,以防止另一個委托的用戶甚至知道在過濾掉的目錄中進行了提交。但是,只有在提交只涉及過濾后的文件時才能過濾掉 - out 目錄。否則會出現無法通過 hooks 自動解決的合並沖突。)
權限存儲庫是所有委托權限的超集。 每個委托倉庫中的所有提交對象都會通過每個委托倉庫中的掛鈎自動推送到授權倉庫中。 因此,如果有兩個委托存儲庫,則權限存儲庫中將有兩個同構 DAG(每個委托一個)(假設委托不共享公共根提交)。
權限存儲庫還將具有來自每個委托的每個項目分支的版本,以委托名稱為前綴。 繼續上面的示例, everything.git
委托存儲庫有一個master
分支指向提交2faaad9
,而委托no-foo.git
有一個master
分支指向過濾但其他等效的提交81c2189
。 在這種情況下, authority.git
將有兩個 master 分支: everything/master
指向2faaad9
和no-foo/master
指向81c2189
。 下圖說明了這一點。
$ cd ~git/repositories/authority.git
$ git log --graph --oneline --decorate --date-order --all
* 2faaad9 (everything/master) barbaz
| * 81c2189 (no-foo/master) barbaz
| | * c3eb6a9 (everything/release) foobar
| | | * 6bbd85f (no-foo/release) foobar
* | | | 8b56913 Merge branch 'release'
|\ \ \ \
| | |/ /
| |/| |
| | * | c579c4b Merge branch 'release'
| | |\ \
| | | |/
| * | | b8f899c qux
| | | * 42c45c7 qux
* | | | aad30f1 baz
|/ / /
| * | 90ecdc7 baz
| |/
* | f4acd9f put a new file in subdirectory bar
| * 4d1cd8d put a new file in subdirectory bar
* | 2a15586 put a new file in subdirectory foo
/
* 9cc719d put a new file in subdirectory foo
請注意,每個提交有兩個版本,每個代表一個版本。 還要注意分支名稱。
每個委托都將提交提交給權限存儲庫。
當用戶更新委托存儲庫中的引用(通過git push
)時,該存儲庫的update
掛鈎會自動將git push
送到權限存儲庫中。 但是,它不使用標准推送 refspec,而是使用 refspec 導致授權存儲庫中的引用以委托存儲庫的名稱為前綴(例如,如果委托存儲庫名為foo.git
,那么它將使用推送 refspec,如+refs/heads/master:refs/heads/foo/master
和+refs/tags/v1.0:refs/tags/foo/v1.0
)。
權限存儲庫過濾傳入的提交並將它們推送到其他委托存儲庫。
當委托倉庫推送到權限倉庫時,權限的update
鈎子:
必須注意避免委托存儲庫之間的競爭條件並正確處理錯誤。
在您的示例中,您將有兩個這樣的委托存儲庫:
everything.git
(給你)zend-project.git
(供您的設計師使用) authority.git
中的分支將以everything
為前綴,而zend-project
對應於兩個委托存儲庫。
當你 push to master
in everything.git
時,會發生以下情況:
everything.git
中的update
掛鈎會將傳入的提交推送到authority.git
中的everything/master
分支。authority.git
中的update
掛鈎將:
application
和public
子目錄之外的所有內容。zend-project/master
以指向新的提交。zend-project/master
中的authority.git
推送到zend-project.git
中的master
中。 當您的設計人員推動master
zend-project.git
時,會發生以下情況:
zend-project.git
中的update
掛鈎會將傳入的提交推送到authority.git
中的zend-project/master
分支。authority.git
中的update
掛鈎將:
application
或public
子目錄之外創建了任何新文件。 如果是,則返回錯誤消息。everything/master
節點的其他子目錄。everything/master
以指向新的提交。everything/master
in authority.git
to master
in everything.git
。上面描述了一種實現按目錄讀取訪問控制的方法。 如果您真的不希望某些用戶能夠訪問存儲庫的某些部分,它應該是合適的。 在您的情況下,為您的設計師提供便利可能比限制訪問更重要。 如果是這樣,可能有一種更簡單的方法來完成你想要的。
我希望我能夠足夠清楚地解釋這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.